acadavid / WinLibre
WinLibre Repository Development
Clone this repository (size: 2.0 MB): HTTPS / SSH
$ hg clone http://bitbucket.org/acadavid/winlibre/
| commit 62: | 3d1558b09cf9 |
| parent 57: | e2ad630f815d |
| branch: | default |
Added version comparison algorithm. Tested with Packaging Policy examples for valid results.
Changed (Δ3.1 KB):
raw changeset »
wpkg/vercmp.py (119 lines added, 0 lines removed)
Up to file-list wpkg/vercmp.py:
1 |
class VerCompare(): |
|
2 |
def __init__(self, version): |
|
3 |
""" Parses the version into epoch, version, and revision revision """ |
|
4 |
epoch = version.split(':') |
|
5 |
||
6 |
if len(epoch) > 1: # We have an epoch |
|
7 |
#TODO: Make sure len(epoch[0]) ! > 1 |
|
8 |
val = int(epoch[0]) |
|
9 |
if val in range(0,10): |
|
10 |
self.epoch = int(epoch[0]) |
|
11 |
else: |
|
12 |
raise AttributeError, 'Invalid version string' |
|
13 |
else: |
|
14 |
self.epoch = 0 |
|
15 |
epoch = ['0',epoch[0]] # Setup fake list |
|
16 |
||
17 |
version = ''.join(epoch[1:]).split('-') |
|
18 |
||
19 |
if len(version) > 1: # We have a revision version |
|
20 |
self.revision = version[-1] |
|
21 |
self.version = '-'.join(version[:-1]) |
|
22 |
else: |
|
23 |
self.revision = '' |
|
24 |
self.version = version[0] |
|
25 |
||
26 |
class VerType: |
|
27 |
def __init__(self, val): |
|
28 |
self.val = val |
|
29 |
||
30 |
def type(self): |
|
31 |
if self.val.isalpha(): |
|
32 |
return 'alpha' |
|
33 |
elif self.val.isdigit(): |
|
34 |
return 'digit' |
|
35 |
elif self.val == '~': |
|
36 |
return 'tilde' |
|
37 |
else: |
|
38 |
return 'delimit' |
|
39 |
||
40 |
def order(self): |
|
41 |
if self.val == '~': return -1 |
|
42 |
elif self.val.isdigit(): return 0 |
|
43 |
elif not self.val: return 0 |
|
44 |
elif self.val.isalpha(): return ord(self.val) |
|
45 |
else: return ord(self.val) + 256 |
|
46 |
||
47 |
def __compare_section(s1, s2): |
|
48 |
""" Compares two version subsections """ |
|
49 |
types1 = [VerType(x) for x in s1] |
|
50 |
types2 = [VerType(x) for x in s2] |
|
51 |
#print len(types1), len(types2) |
|
52 |
||
53 |
# While there is more |
|
54 |
i=0 |
|
55 |
while(i < len(types1) and i < len(types2)): |
|
56 |
# Types are not equal |
|
57 |
if not types1[i].type() == types2[i].type(): |
|
58 |
# Check order |
|
59 |
if types1[i].order() > types2[i].order(): |
|
60 |
return 1 |
|
61 |
else: |
|
62 |
return -1 |
|
63 |
||
64 |
# Get more of same type for both |
|
65 |
j = i |
|
66 |
curtype = types1[i].type() |
|
67 |
while(j < len(types1) and types1[j].type() == curtype): |
|
68 |
j += 1 |
|
69 |
str1 = ''.join([types1[x].val for x in range(i, j)]) |
|
70 |
||
71 |
j = i |
|
72 |
while(j < len(types2) and types2[j].type() == curtype): |
|
73 |
j += 1 |
|
74 |
str2 = ''.join([types2[x].val for x in range(i, j)]) |
|
75 |
||
76 |
#print str1, str2, curtype |
|
77 |
||
78 |
# Compare |
|
79 |
if str1 > str2: |
|
80 |
return 1 |
|
81 |
elif str1 < str2: |
|
82 |
return -1 |
|
83 |
else: |
|
84 |
j += 1 |
|
85 |
||
86 |
i = j |
|
87 |
||
88 |
if s1 > s2: |
|
89 |
return 1 |
|
90 |
elif s1 < s2: |
|
91 |
return -1 |
|
92 |
else: |
|
93 |
return 0 |
|
94 |
||
95 |
def vercmp(ver1, ver2): |
|
96 |
""" Compares 2 version strings |
|
97 |
||
98 |
Returns: |
|
99 |
-1 if ver1 less than (<) ver2 |
|
100 |
0 if ver1 equal to (=) ver2 |
|
101 |
1 if ver1 greater than (>) ver2 |
|
102 |
""" |
|
103 |
||
104 |
ver1 = VerCompare(ver1) |
|
105 |
ver2 = VerCompare(ver2) |
|
106 |
||
107 |
# Compare epochs |
|
108 |
if ver1.epoch > ver2.epoch: |
|
109 |
return 1 |
|
110 |
elif ver1.epoch < ver2.epoch: |
|
111 |
return -1 |
|
112 |
||
113 |
# Epochs are equal, compare version |
|
114 |
result = __compare_section(ver1.version, ver2.version) |
|
115 |
if result: |
|
116 |
return result |
|
117 |
||
118 |
# Compare revisions |
|
119 |
return __compare_section(ver1.revision, ver2.revision) |
