From d1b2c9340f38efefd494455fd28bec34b14f1ebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Metin?= Date: Thu, 22 Sep 2005 22:25:32 +0000 Subject: [PATCH] - fix release critical bug #457. Add alphanumeric support to version numbers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is what Çağlar offered to do. Çağlar, please take a look at the versiontests file and give feedback! --- pisi/version.py | 126 ++++++++++++++++++++++++++++++++++++++++-- tests/versiontests.py | 26 ++++++++- 2 files changed, 145 insertions(+), 7 deletions(-) diff --git a/pisi/version.py b/pisi/version.py index 728f5943..263b6a2f 100644 --- a/pisi/version.py +++ b/pisi/version.py @@ -12,20 +12,137 @@ # Authors: Eray Ozkural +import re + import pisi.util as util + + +# Basic rule is: +# p > (no suffix) > rc > pre > beta > alpha +keywords = {"alpha": 0, + "beta" : 1, + "pre" : 2, + "rc" : 3, + "NOKEY" : 4, + "p" : 5} + +# helper functions +def has_keyword(versionitem): + if versionitem._keyword != "NOKEY": + return True + + return False + + + +class VersionItem: + _keyword = "NOKEY" + _value = 0 + + def __init__(self, itemstring): + + for keyword in keywords.keys(): + if itemstring.startswith(keyword): + + if self._keyword == "NOKEY": + self._keyword = keyword + else: + # longer match is correct + if len(keyword) > len(self._keyword): + self._keyword = keyword + + if self._keyword == "NOKEY": + self._value = itemstring + else: + # rest is the version item's value. And each must have + # one! + self._value = itemstring[len(self._keyword):] + + def __lt__(self,rhs): + l = keywords[self._keyword] + r = keywords[rhs._keyword] + if l < r: + return True + elif l == r: + return self._value < rhs._value + else: # l > r + return False + + def __le__(self,rhs): + l = keywords[self._keyword] + r = keywords[rhs._keyword] + if l < r: + return True + elif l == r: + return self._value <= rhs._value + else: # l > r + return False + + def __gt__(self,rhs): + l = keywords[self._keyword] + r = keywords[rhs._keyword] + if l > r: + return True + elif l == r: + return self._value > rhs._value + else: # l < r + return False + + def __ge__(self,rhs): + l = keywords[self._keyword] + r = keywords[rhs._keyword] + if l > r: + return True + elif l == r: + return self._value >= rhs._value + else: # l < r + return False + + + class Version: + def __init__(self, verstring): - self.comps = map(lambda x: int(x), util.multisplit(verstring,'.-')) + self.comps = [] + for i in util.multisplit(verstring,'.-_'): + # some version strings can contain ascii chars at the + # back. As an example: 2.11a + # We split '11a' as two items like '11' and 'a' + s = re.compile("[a-z-A-Z]$").search(i) + if s: + head = i[:s.start()] + tail = s.group() + self.comps.append(VersionItem(head)) + self.comps.append(VersionItem(tail)) + else: + self.comps.append(VersionItem(i)) + self.verstring = verstring def string(self): return self.verstring - def pred(self,rhs,pred): - for i in range(0, len(self.comps)): - if pred(self.comps[i],rhs.comps[i]): + def pred(self, rhs, pred): + + loop = len(self.comps) + if len(rhs.comps) > loop: + loop = len(rhs.comps) + + for i in range(0, loop): + try: + litem = self.comps[i] + except IndexError: + litem = VersionItem("") + + try: + ritem = rhs.comps[i] + except IndexError: + ritem = VersionItem("") + + if pred(litem, ritem): return True + else: return False @@ -41,3 +158,4 @@ class Version: def __ge__(self,rhs): return self.pred(rhs, lambda x,y: x>=y) + diff --git a/tests/versiontests.py b/tests/versiontests.py index b5532612..19250b62 100644 --- a/tests/versiontests.py +++ b/tests/versiontests.py @@ -12,13 +12,11 @@ import unittest import os from pisi import version -from pisi import util -from pisi import context class VersionTestCase(unittest.TestCase): def setUp(self): pass - + def testOps(self): v1 = version.Version("0.3.1") v2 = version.Version("0.3.5") @@ -29,4 +27,26 @@ class VersionTestCase(unittest.TestCase): self.assert_(v1 <= v3) self.assert_(v4 >= v4) + # with keywords + v1 = version.Version("2.23_pre10") + v2 = version.Version("2.23") + v3 = version.Version("2.21") + v4 = version.Version("2.23_p1") + v5 = version.Version("2.23_beta1") + self.assert_(v1 < v2) + self.assert_(v1 > v3) + self.assert_(v1 < v4) + self.assert_(v1 > v5) + self.assert_(v2 < v4) + self.assert_(v2 > v5) + + # with character + v1 = version.Version("2.10a") + v2 = version.Version("2.10") + v3 = version.Version("2.10d") + self.assert_(v1 > v2) + self.assert_(v1 < v3) + self.assert_(v2 < v3) + + suite = unittest.makeSuite(VersionTestCase)