Backport deb driver fixes from packetary repository

Fixed obsoletes detecting for deb package
Fixed check intersection for range of versions

Change-Id: Ia7f2e3e1b2c3f4adc26324b6267eea359c776ec0
Closes-Bug: #1537391
(cherry picked from commit fdbcd571ab)
This commit is contained in:
Bulat Gaifullin 2016-01-23 22:04:50 +03:00
parent 88c9f2978f
commit 351d568fa3
6 changed files with 49 additions and 49 deletions

View File

@ -138,7 +138,8 @@ class DebRepositoryDriver(RepositoryDriverBase):
requires=self._get_relations(
dpkg, "depends", "pre-depends", "recommends"
),
obsoletes=self._get_relations(dpkg, "replaces"),
# The deb does not have obsoletes section
obsoletes=[],
provides=self._get_relations(dpkg, "provides"),
))
except KeyError as e:

View File

@ -36,6 +36,9 @@ class VersionRange(object):
self.op = op
self.edge = edge
def __contains__(self, point):
return getattr(operator, self.op)(point, self.edge)
def __hash__(self):
return hash((self.op, self.edge))
@ -57,7 +60,12 @@ class VersionRange(object):
return u"any"
def has_intersection(self, other):
"""Checks that 2 ranges has intersection."""
"""Checks that 2 ranges has intersection.
:param other: the candidate to check
:return: True if intersection exists, otherwise False
:raise TypeError: when other does not instance of VersionRange
"""
if not isinstance(other, VersionRange):
raise TypeError(
@ -68,28 +76,16 @@ class VersionRange(object):
if self.op is None or other.op is None:
return True
my_op = getattr(operator, self.op)
other_op = getattr(operator, other.op)
if self.op[0] == other.op[0]:
if self.op[0] == 'l':
if self.edge < other.edge:
return my_op(self.edge, other.edge)
return other_op(other.edge, self.edge)
elif self.op[0] == 'g':
if self.edge > other.edge:
return my_op(self.edge, other.edge)
return other_op(other.edge, self.edge)
if self.op == 'eq':
return other_op(self.edge, other.edge)
if other.op == 'eq':
return my_op(other.edge, self.edge)
return (
my_op(other.edge, self.edge) and
other_op(self.edge, other.edge)
)
if self.op == 'eq':
return self.edge == other.edge
# the intersection is -inf or +inf
return True
if self.edge == other.edge:
# need to cover case < a and >= a
return self.edge in other and other.edge in self
# all other cases
return self.edge in other or other.edge in self
class PackageRelation(object):

View File

@ -74,15 +74,15 @@ class PackagesTree(Index):
self.__get_unresolved_dependencies(main, requirements)
stack = list()
stack.append((None, requirements))
stack.append(requirements)
# add all mandatory packages
for pkg in self.mandatory_packages:
stack.append((pkg, pkg.requires))
resolved.add(pkg)
stack.append(pkg.requires)
while len(stack) > 0:
pkg, required = stack.pop()
resolved.add(pkg)
required = stack.pop()
for require in required:
for rel in require:
if rel not in unresolved:
@ -90,22 +90,17 @@ class PackagesTree(Index):
break
# use all packages that meets depends
candidates = self.find_all(rel.name, rel.version)
found = False
for cand in candidates:
if cand == pkg:
continue
found = True
if cand not in resolved:
stack.append((cand, cand.requires))
if found:
resolved.add(cand)
stack.append(cand.requires)
if len(candidates) > 0:
break
else:
unresolved.add(require)
msg = "Unresolved depends: {0}".format(require)
warnings.warn(UnresolvedWarning(msg))
resolved.remove(None)
return resolved
@staticmethod

View File

@ -138,10 +138,7 @@ class TestDebDriver(base.TestCase):
["file (any)"],
(str(x) for x in package.provides)
)
self.assertItemsEqual(
["test-old (any)"],
(str(x) for x in package.obsoletes)
)
self.assertEqual([], package.obsoletes)
@mock.patch.multiple(
"packetary.drivers.deb_driver",

View File

@ -169,7 +169,7 @@ class TestIndex(base.TestCase):
p2, index.find("provides1", objects.VersionRange("ge", 2))
)
self.assertIsNone(
index.find("provides1", objects.VersionRange("lt", 2))
index.find("provides1", objects.VersionRange("gt", 2))
)
def test_len(self):

View File

@ -175,22 +175,33 @@ class TestVersionRange(TestObjectBase):
def test_have_intersection(self):
cases = [
(("eq", 2), ("eq", 2)),
(("eq", 2), ("lt", 3)),
(("eq", 2), ("gt", 1)),
(("lt", 2), ("gt", 1)),
(("lt", 3), ("lt", 4)),
(("gt", 3), ("gt", 4)),
(("eq", 1), ("eq", 1)),
(("ge", 1), ("le", 1)),
(("eq", 1), ("lt", 2)),
((None, None), ("le", 10)),
(("lt", 2), ("lt", 3)),
(("lt", 2), ("lt", 2)),
(("lt", 2), ("le", 2)),
(("gt", 2), ("gt", 1)),
(("gt", 2), ("lt", 3)),
(("gt", 2), ("ge", 2)),
(("gt", 2), ("gt", 2)),
(("ge", 2), ("le", 2)),
((None, None), ("eq", 2)),
]
self.__check_intersection(self.assertTrue, cases)
def test_does_not_have_intersection(self):
cases = [
(("lt", 2), ("gt", 2)),
(("ge", 2), ("lt", 2)),
(("eq", 2), ("eq", 1)),
(("eq", 2), ("lt", 2)),
(("eq", 2), ("gt", 2)),
(("eq", 2), ("gt", 3)),
(("eq", 2), ("lt", 1)),
(("lt", 2), ("ge", 2)),
(("lt", 2), ("gt", 3)),
(("gt", 2), ("le", 2)),
(("gt", 1), ("lt", 1)),
(("gt", 2), ("lt", 1)),
]
self.__check_intersection(self.assertFalse, cases)