if not self.name == other.name:
return cmp(self.name, other.name)
- ret = util.version_compare((self.epoch, self.version, self.release),
- (other.epoch, other.version, other.release))
+ ret = util.version_compare(self.version_tuple, other.version_tuple)
# Compare the build times if we have a rebuilt package.
if not ret:
return int(epoch)
+ @property
+ def version_tuple(self):
+ """
+ Returns a tuple like (epoch, version, release) that can
+ be used to compare versions of packages.
+ """
+ return (self.epoch, self.version, self.release)
+
@property
def arch(self):
raise NotImplementedError
if self.name == requires.requires:
return True
+ # Get all provide strings from the package data
+ # and return true if requires is matched.
+ if requires.requires in self.provides:
+ return True
+
if requires.type == "file":
return requires.requires in self.filelist
- # Get all provide strings from the package data
- # and return true if requires is matched. Otherwise return false.
- provides = self.provides
+ elif requires.type == "expr":
+ # Handle all expressions like "gcc>=4.0.0-1"
+ (e_expr, e_name, e_epoch, e_version, e_release) = \
+ util.parse_pkg_expr(requires.requires)
+
+ # If the package names do not match, we do not provide this:
+ if not self.name == e_name:
+ return False
+
+ ret = util.version_compare(self.version_tuple, (e_epoch, e_version, e_release))
+
+ # If we equal the version, we provide this
+ if "=" in e_expr and ret == 0:
+ return True
+
+ elif ">" in e_expr and ret > 0:
+ return True
+
+ elif "<" in e_expr and ret < 0:
+ return True
+
+ return False
- return requires.requires in provides
-
- # XXX this function has to do lots more of magic:
- # e.g. filename matches, etc.
+ # No match was found at all
+ return False
def extract(self, path):
raise NotImplementedError
from __future__ import division
import hashlib
+import re
from pakfire.constants import *
def version_compare_epoch(e1, e2):
+ # If either e1 or e2 is None, we cannot say anything
+ if None in (e1, e2):
+ return 0
+
return cmp(e1, e2)
def version_compare_version(v1, v2):
return cmp(v1, v2)
def version_compare_release(r1, r2):
+ # If either e1 or e2 is None, we cannot say anything
+ if None in (r1, r2):
+ return 0
+
+ if "." in r1:
+ r1 = r1.split(".")[0]
+
+ if "." in r2:
+ r2 = r2.split(".")[0]
+
return cmp(r1, r2)
def version_compare((e1, v1, r1), (e2, v2, r2)):
-
ret = version_compare_epoch(e1, e2)
if not ret == 0:
return ret
f.close()
return h.hexdigest()
+
+def parse_pkg_expr(s):
+ # Possible formats:
+ # gcc=4.0.0
+ # gcc=4.0.0-1
+ # gcc=4.0.0-1.ip3
+ # gcc=0:4.0.0-1
+ # gcc=0:4.0.0-1.ip3
+ # gcc>=...
+ # gcc>...
+ # gcc<...
+ # gcc<=...
+
+ (name, exp, epoch, version, release) = (None, None, None, None, None)
+
+ m = re.match(r"([A-Za-z0-9\-\+]+)(=|\<|\>|\>=|\<=)([0-9]+\:)?([0-9A-Za-z\.]+)-?([0-9]+\.?[a-z0-9]+|[0-9]+)?", s)
+
+ if m:
+ (name, exp, epoch, version, release) = m.groups()
+
+ # Remove : from epoch and convert to int
+ if epoch:
+ epoch = epoch.replace(":", "")
+ epoch = int(epoch)
+
+ return (exp, name, epoch, version, release)
+
+def test_parse_pkg_expr():
+ strings = (
+ "gcc=4.0.0",
+ "gcc=4.0.0-1",
+ "gcc=4.0.0-1.ip3",
+ "gcc=0:4.0.0-1",
+ "gcc=0:4.0.0-1.ip3",
+ "gcc>=4.0.0-1",
+ "gcc>4.0.0-1",
+ "gcc<4.0.0-1",
+ "gcc<=4.0.0-1",
+ )
+
+ for s in strings:
+ print s, parse_pkg_expr(s)
+
+if __name__ == "__main__":
+ test_parse_pkg_expr()