version: Modify Version class to use make_version
This commit is contained in:
@@ -150,7 +150,7 @@ class Install(AtomicOperation):
|
|||||||
|
|
||||||
self.ask_reinstall = ask_reinstall
|
self.ask_reinstall = ask_reinstall
|
||||||
self.check_requirements()
|
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_relations()
|
||||||
self.check_operation()
|
self.check_operation()
|
||||||
self.extract_install()
|
self.extract_install()
|
||||||
@@ -184,9 +184,12 @@ class Install(AtomicOperation):
|
|||||||
if self.installdb.has_package(replaced.package):
|
if self.installdb.has_package(replaced.package):
|
||||||
pisi.operations.remove.remove_replaced_packages([replaced.package])
|
pisi.operations.remove.remove_replaced_packages([replaced.package])
|
||||||
|
|
||||||
def check_versioning(self, version):
|
def check_versioning(self, version, release):
|
||||||
if not pisi.version.Version.valid(version):
|
try:
|
||||||
raise Error("%s is not a valid PiSi version format" % version)
|
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):
|
def check_relations(self):
|
||||||
# check dependencies
|
# check dependencies
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ class Builder:
|
|||||||
self.specdir = os.path.dirname(self.specuri.get_uri())
|
self.specdir = os.path.dirname(self.specuri.get_uri())
|
||||||
|
|
||||||
# Don't wait until creating .pisi file for complaining about versioning scheme errors
|
# 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)
|
self.read_translations(self.specdir)
|
||||||
|
|
||||||
@@ -586,9 +586,12 @@ class Builder:
|
|||||||
os.chdir(curDir)
|
os.chdir(curDir)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def check_versioning(self, version):
|
def check_versioning(self, version, release):
|
||||||
if not pisi.version.Version.valid(version):
|
try:
|
||||||
raise Error("%s is not a valid PiSi version format" % version)
|
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):
|
def check_build_dependencies(self):
|
||||||
"""check and try to install build dependencies, otherwise fail."""
|
"""check and try to install build dependencies, otherwise fail."""
|
||||||
@@ -813,7 +816,8 @@ class Builder:
|
|||||||
pkg = os.path.basename(old_package_fn)
|
pkg = os.path.basename(old_package_fn)
|
||||||
name, version = pisi.util.parse_package_name(pkg[:-5])
|
name, version = pisi.util.parse_package_name(pkg[:-5])
|
||||||
ctx.ui.info(_('(found old version %s)') % old_package_fn)
|
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) )
|
found.add( (old_package_fn, old_build) )
|
||||||
except Error:
|
except Error:
|
||||||
ctx.ui.warning('Package file %s may be corrupt. Skipping.' % old_package_fn)
|
ctx.ui.warning('Package file %s may be corrupt. Skipping.' % old_package_fn)
|
||||||
|
|||||||
+31
-183
@@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- 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
|
# 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
|
# the terms of the GNU General Public License as published by the Free
|
||||||
@@ -12,32 +12,16 @@
|
|||||||
|
|
||||||
"""version structure"""
|
"""version structure"""
|
||||||
|
|
||||||
import re
|
|
||||||
import string
|
|
||||||
|
|
||||||
import gettext
|
import gettext
|
||||||
__trans = gettext.translation('pisi', fallback=True)
|
__trans = gettext.translation('pisi', fallback=True)
|
||||||
_ = __trans.ugettext
|
_ = __trans.ugettext
|
||||||
|
|
||||||
import pisi
|
import pisi
|
||||||
import pisi.util as util
|
|
||||||
|
|
||||||
maxdashes = 2
|
|
||||||
|
|
||||||
# Basic rule is:
|
# Basic rule is:
|
||||||
# p > (no suffix) > m > rc > pre > beta > alpha
|
# p > (no suffix) > m > rc > pre > beta > alpha
|
||||||
# m: milestone. this was added for OO.o
|
# m: milestone. this was added for OO.o
|
||||||
# p: patch-level
|
# p: patch-level
|
||||||
keywords = {
|
|
||||||
"alpha" : 0,
|
|
||||||
"beta" : 1,
|
|
||||||
"pre" : 2,
|
|
||||||
"rc" : 3,
|
|
||||||
"m" : 4,
|
|
||||||
"NOKEY" : 5,
|
|
||||||
"p" : 6,
|
|
||||||
}
|
|
||||||
|
|
||||||
__keywords = (
|
__keywords = (
|
||||||
("alpha", -5),
|
("alpha", -5),
|
||||||
("beta", -4),
|
("beta", -4),
|
||||||
@@ -79,196 +63,60 @@ def make_version(version):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
raise InvalidVersionError(_("Invalid version string: '%s'") % version)
|
raise InvalidVersionError(_("Invalid version string: '%s'") % version)
|
||||||
|
|
||||||
# helper functions
|
class Version(object):
|
||||||
def has_keyword(versionitem):
|
|
||||||
if versionitem._keyword != "NOKEY":
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
__slots__ = ("__version", "__version_string")
|
||||||
|
|
||||||
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:
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def valid(version):
|
def valid(version):
|
||||||
try:
|
try:
|
||||||
pisi.version.Version(version)
|
make_version(version)
|
||||||
except pisi.version.VersionException, e:
|
except InvalidVersionError:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def __init__(self, verstring):
|
def __init__(self, verstring):
|
||||||
# PiSi version policy does not allow "-" in version strings.
|
self.__version_string = verstring
|
||||||
# They are special and used for build and release no separation.
|
self.__version = make_version(verstring)
|
||||||
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)
|
|
||||||
|
|
||||||
def string(self):
|
def string(self):
|
||||||
return self.verstring
|
return self.__version_string
|
||||||
|
|
||||||
def compare(self, ver):
|
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):
|
if isinstance(ver, basestring):
|
||||||
ver = pisi.version.Version(ver)
|
return cmp(self.__version, make_version(ver))
|
||||||
|
|
||||||
lhs = self.comps
|
return cmp(self.__version, ver.__version)
|
||||||
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
|
|
||||||
|
|
||||||
# premature optimization is the root of all evil
|
|
||||||
|
|
||||||
def __lt__(self, rhs):
|
def __lt__(self, rhs):
|
||||||
return self.compare(rhs) < 0
|
if isinstance(rhs, basestring):
|
||||||
|
return self.__version < make_version(rhs)
|
||||||
|
|
||||||
|
return self.__version < rhs.__version
|
||||||
|
|
||||||
def __le__(self, rhs):
|
def __le__(self, rhs):
|
||||||
return self.compare(rhs) <= 0
|
if isinstance(rhs, basestring):
|
||||||
|
return self.__version <= make_version(rhs)
|
||||||
|
|
||||||
|
return self.__version <= rhs.__version
|
||||||
|
|
||||||
def __gt__(self, rhs):
|
def __gt__(self, rhs):
|
||||||
return self.compare(rhs) > 0
|
if isinstance(rhs, basestring):
|
||||||
|
return self.__version > make_version(rhs)
|
||||||
|
|
||||||
|
return self.__version > rhs.__version
|
||||||
|
|
||||||
def __ge__(self, rhs):
|
def __ge__(self, rhs):
|
||||||
return self.compare(rhs) >= 0
|
if isinstance(rhs, basestring):
|
||||||
|
return self.__version >= make_version(rhs)
|
||||||
|
|
||||||
|
return self.__version >= rhs.__version
|
||||||
|
|
||||||
def __eq__(self, rhs):
|
def __eq__(self, rhs):
|
||||||
return self.compare(rhs) == 0
|
if isinstance(rhs, basestring):
|
||||||
|
return self.__version_string == rhs
|
||||||
|
|
||||||
|
return self.__version_string == rhs.__version_string
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.verstring
|
return self.__version_string
|
||||||
|
|||||||
Reference in New Issue
Block a user