version: Modify Version class to use make_version

This commit is contained in:
Fatih Aşıcı
2010-03-08 09:26:10 +00:00
parent a81590a42a
commit 85ab697c88
3 changed files with 51 additions and 196 deletions
+7 -4
View File
@@ -150,7 +150,7 @@ class Install(AtomicOperation):
self.ask_reinstall = ask_reinstall
self.check_requirements()
self.check_versioning("%s-%s" % (self.pkginfo.version, self.pkginfo.release))
self.check_versioning(self.pkginfo.version, self.pkginfo.release)
self.check_relations()
self.check_operation()
self.extract_install()
@@ -184,9 +184,12 @@ class Install(AtomicOperation):
if self.installdb.has_package(replaced.package):
pisi.operations.remove.remove_replaced_packages([replaced.package])
def check_versioning(self, version):
if not pisi.version.Version.valid(version):
raise Error("%s is not a valid PiSi version format" % version)
def check_versioning(self, version, release):
try:
int(release)
pisi.version.Version(version)
except (ValueError, InvalidVersionError):
raise Error(_("%s-%s is not a valid PiSi version format") % (version, release))
def check_relations(self):
# check dependencies
+9 -5
View File
@@ -200,7 +200,7 @@ class Builder:
self.specdir = os.path.dirname(self.specuri.get_uri())
# Don't wait until creating .pisi file for complaining about versioning scheme errors
self.check_versioning("%s-%s" % (self.spec.getSourceVersion(), self.spec.getSourceRelease()))
self.check_versioning(self.spec.getSourceVersion(), self.spec.getSourceRelease())
self.read_translations(self.specdir)
@@ -586,9 +586,12 @@ class Builder:
os.chdir(curDir)
return True
def check_versioning(self, version):
if not pisi.version.Version.valid(version):
raise Error("%s is not a valid PiSi version format" % version)
def check_versioning(self, version, release):
try:
int(release)
pisi.version.Version(version)
except (ValueError, InvalidVersionError):
raise Error(_("%s-%s is not a valid PiSi version format") % (version, release))
def check_build_dependencies(self):
"""check and try to install build dependencies, otherwise fail."""
@@ -813,7 +816,8 @@ class Builder:
pkg = os.path.basename(old_package_fn)
name, version = pisi.util.parse_package_name(pkg[:-5])
ctx.ui.info(_('(found old version %s)') % old_package_fn)
old_build = int(str(pisi.version.Version(version).build))
ver, rel, build = pisi.util.split_version(version)
old_build = int(build) if build else 0
found.add( (old_package_fn, old_build) )
except Error:
ctx.ui.warning('Package file %s may be corrupt. Skipping.' % old_package_fn)
+35 -187
View File
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2005 - 2007, TUBITAK/UEKAE
# Copyright (C) 2005 - 2010, TUBITAK/UEKAE
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
@@ -12,32 +12,16 @@
"""version structure"""
import re
import string
import gettext
__trans = gettext.translation('pisi', fallback=True)
_ = __trans.ugettext
import pisi
import pisi.util as util
maxdashes = 2
# Basic rule is:
# p > (no suffix) > m > rc > pre > beta > alpha
# m: milestone. this was added for OO.o
# p: patch-level
keywords = {
"alpha" : 0,
"beta" : 1,
"pre" : 2,
"rc" : 3,
"m" : 4,
"NOKEY" : 5,
"p" : 6,
}
__keywords = (
("alpha", -5),
("beta", -4),
@@ -79,196 +63,60 @@ def make_version(version):
except ValueError:
raise InvalidVersionError(_("Invalid version string: '%s'") % version)
# helper functions
def has_keyword(versionitem):
if versionitem._keyword != "NOKEY":
return True
class Version(object):
return False
class VersionException(pisi.Exception):
def __init__(self, str):
pisi.Exception.__init__(self, str)
class VersionItem:
_keyword = "NOKEY"
_value = 0
def __init__(self, itemstring):
# special-case: 1.5p
# here "p" comes as a separate itemstring and conflicts with
# keyword "p". But keyword should allways contain an integer prefix.
# So, skipping looking for keywords if the length() is 1 makes the
# trick.
if len(itemstring) > 1:
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":
if len(itemstring) == 1 and itemstring in string.ascii_letters:
# single letter version item ('a' to 'Z')
self._value = itemstring
elif len(itemstring) > 1 and itemstring[0] in string.ascii_letters:
# Unknown keyword
raise VersionException("")
else:
self._value = int(itemstring)
else:
# rest is the version item's value. And each must have
# one!
self._value = int(itemstring[len(self._keyword):])
def __str__(self):
return str(self._value)
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
def __eq__(self,rhs):
l = keywords[self._keyword]
r = keywords[rhs._keyword]
if l == r and self._value == rhs._value:
return True
return False
class Version:
__slots__ = ("__version", "__version_string")
@staticmethod
def valid(version):
try:
pisi.version.Version(version)
except pisi.version.VersionException, e:
make_version(version)
except InvalidVersionError:
return False
return True
def __init__(self, verstring):
# PiSi version policy does not allow "-" in version strings.
# They are special and used for build and release no separation.
if verstring.count("-") > maxdashes:
raise VersionException("%s is not a valid PiSi version format" % verstring)
verchunks = verstring.split("-")
verchunks.extend("0" * (maxdashes - verstring.count("-")))
(version, release, build) = verchunks
self.comps = []
for i in util.multisplit(version,'._'):
# 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
self.release = VersionItem(release)
self.build = VersionItem(build)
self.__version_string = verstring
self.__version = make_version(verstring)
def string(self):
return self.verstring
return self.__version_string
def compare(self, ver):
"""this comparison routine is essentially a comparison routine
for two rationals in (0,1) interval. we compare two sequences
of digits one by one. We start with the leftmost digit
in the expansion. If they are equal, we proceed to the next. If
not we use the comparison operator. And we iterate to the left.
The result is, 0 if two are equal, -1 if self < rhs, and +1
if self>rhs"""
if isinstance(ver, basestring):
ver = pisi.version.Version(ver)
return cmp(self.__version, make_version(ver))
lhs = self.comps
rhs = ver.comps
# pad the short version string with zeros
if len(lhs) < len(rhs):
lhs.extend( [VersionItem('0')] * (len(rhs) - len(lhs)) )
elif len(lhs) > len(rhs):
rhs.extend( [VersionItem('0')] * (len(lhs) - len(rhs)) )
# now let's iterate from left to right in version items
for (litem, ritem) in zip(lhs, rhs):
if litem < ritem:
return -1
elif litem > ritem:
return +1
# now let's compare release and build
lhs = (self.release, self.build)
rhs = (ver.release, ver.build)
for (litem, ritem) in zip(lhs, rhs):
if litem < ritem:
return -1
elif litem > ritem:
return +1
return 0
return cmp(self.__version, ver.__version)
# premature optimization is the root of all evil
def __lt__(self, rhs):
if isinstance(rhs, basestring):
return self.__version < make_version(rhs)
def __lt__(self,rhs):
return self.compare(rhs) < 0
return self.__version < rhs.__version
def __le__(self,rhs):
return self.compare(rhs) <= 0
def __le__(self, rhs):
if isinstance(rhs, basestring):
return self.__version <= make_version(rhs)
def __gt__(self,rhs):
return self.compare(rhs) > 0
return self.__version <= rhs.__version
def __ge__(self,rhs):
return self.compare(rhs) >= 0
def __gt__(self, rhs):
if isinstance(rhs, basestring):
return self.__version > make_version(rhs)
def __eq__(self,rhs):
return self.compare(rhs) == 0
return self.__version > rhs.__version
def __ge__(self, rhs):
if isinstance(rhs, basestring):
return self.__version >= make_version(rhs)
return self.__version >= rhs.__version
def __eq__(self, rhs):
if isinstance(rhs, basestring):
return self.__version_string == rhs
return self.__version_string == rhs.__version_string
def __str__(self):
return self.verstring
return self.__version_string