From 351d568fa3b3e4dd062054b91d766aa54d379867 Mon Sep 17 00:00:00 2001 From: Bulat Gaifullin Date: Sat, 23 Jan 2016 22:04:50 +0300 Subject: [PATCH] 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 fdbcd571ab85d80fcca46ae3f94d4e3e55407220) --- packetary/drivers/deb_driver.py | 3 +- packetary/objects/package_relation.py | 40 ++++++++++++--------------- packetary/objects/packages_tree.py | 19 +++++-------- packetary/tests/test_deb_driver.py | 5 +--- packetary/tests/test_index.py | 2 +- packetary/tests/test_objects.py | 29 +++++++++++++------ 6 files changed, 49 insertions(+), 49 deletions(-) diff --git a/packetary/drivers/deb_driver.py b/packetary/drivers/deb_driver.py index 0c26f43..10c4803 100644 --- a/packetary/drivers/deb_driver.py +++ b/packetary/drivers/deb_driver.py @@ -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: diff --git a/packetary/objects/package_relation.py b/packetary/objects/package_relation.py index 31cdfd0..6ab37f3 100644 --- a/packetary/objects/package_relation.py +++ b/packetary/objects/package_relation.py @@ -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): diff --git a/packetary/objects/packages_tree.py b/packetary/objects/packages_tree.py index ce1158c..afd7f39 100644 --- a/packetary/objects/packages_tree.py +++ b/packetary/objects/packages_tree.py @@ -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 diff --git a/packetary/tests/test_deb_driver.py b/packetary/tests/test_deb_driver.py index 3712c28..8fa3575 100644 --- a/packetary/tests/test_deb_driver.py +++ b/packetary/tests/test_deb_driver.py @@ -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", diff --git a/packetary/tests/test_index.py b/packetary/tests/test_index.py index e5baa18..78e1947 100644 --- a/packetary/tests/test_index.py +++ b/packetary/tests/test_index.py @@ -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): diff --git a/packetary/tests/test_objects.py b/packetary/tests/test_objects.py index 7eb90a1..f41ee48 100644 --- a/packetary/tests/test_objects.py +++ b/packetary/tests/test_objects.py @@ -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)