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:
parent
88c9f2978f
commit
351d568fa3
|
@ -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:
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue