The InstallabilityTester is suffering from a lack of clear purpose because it serves multiple. This commit extracts most of one of these purposes into the BinaryPackageUniverse class while retaining the original API of the InstallabilityTester. Signed-off-by: Niels Thykier <niels@thykier.net>ubuntu/rebased
parent
b7fe352713
commit
530db5d3f7
@ -0,0 +1,115 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright (C) 2012 Niels Thykier <niels@thykier.net>
|
||||||
|
|
||||||
|
# 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 Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
|
||||||
|
class BinaryPackageRelation(object):
|
||||||
|
"""All relations of a given binary package"""
|
||||||
|
|
||||||
|
__slots__ = ['dependencies', 'negative_dependencies', 'reverse_dependencies']
|
||||||
|
|
||||||
|
def __init__(self, dependencies, negative_dependencies, reverse_dependencies):
|
||||||
|
self.dependencies = dependencies
|
||||||
|
self.negative_dependencies = negative_dependencies
|
||||||
|
self.reverse_dependencies = reverse_dependencies
|
||||||
|
|
||||||
|
|
||||||
|
class BinaryPackageUniverse(object):
|
||||||
|
"""A "universe" of all binary packages and their relations
|
||||||
|
|
||||||
|
The package universe is a read-only ("immutable") data structure
|
||||||
|
that knows of all binary packages and their internal relations.
|
||||||
|
The relations are either in Conjunctive Normal Form (CNF) represented
|
||||||
|
via sets of sets of the package ids or simply sets of package ids.
|
||||||
|
|
||||||
|
Being immutable, the universe does *not* track stateful data such
|
||||||
|
as "which package is in what suite?" nor "is this package installable
|
||||||
|
in that suite?".
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, relations):
|
||||||
|
self._relations = relations
|
||||||
|
|
||||||
|
def dependencies_of(self, pkg_id):
|
||||||
|
"""Returns the set of dependencies of a given package
|
||||||
|
|
||||||
|
:param pkg_id: The BinaryPackageId of a binary package.
|
||||||
|
:return: A set containing the package ids all of the dependencies
|
||||||
|
of the input package in CNF.
|
||||||
|
"""
|
||||||
|
return self._relations[pkg_id].dependencies
|
||||||
|
|
||||||
|
def negative_dependencies_of(self, pkg_id):
|
||||||
|
"""Returns the set of negative dependencies of a given package
|
||||||
|
|
||||||
|
Note that there is no "reverse_negative_dependencies_of" method,
|
||||||
|
since negative dependencies have no "direction" unlike positive
|
||||||
|
dependencies.
|
||||||
|
|
||||||
|
:param pkg_id: The BinaryPackageId of a binary package.
|
||||||
|
:return: A set containing the package ids all of the negative
|
||||||
|
dependencies of the input package.
|
||||||
|
"""
|
||||||
|
return self._relations[pkg_id].negative_dependencies
|
||||||
|
|
||||||
|
def reverse_dependencies_of(self, pkg_id):
|
||||||
|
"""Returns the set of reverse dependencies of a given package
|
||||||
|
|
||||||
|
Note that a package is considered a reverse dependency of the
|
||||||
|
given package as long as at least one of its dependency relations
|
||||||
|
*could* be satisfied by the given package.
|
||||||
|
|
||||||
|
:param pkg_id: The BinaryPackageId of a binary package.
|
||||||
|
:return: A set containing the package ids all of the reverse
|
||||||
|
dependencies of the input package.
|
||||||
|
"""
|
||||||
|
return self._relations[pkg_id].reverse_dependencies
|
||||||
|
|
||||||
|
def are_equivalent(self, pkg_id1, pkg_id2):
|
||||||
|
"""Test if pkg_id1 and pkg_id2 are equivalent
|
||||||
|
|
||||||
|
:param pkg_id1 The id of the first package
|
||||||
|
:param pkg_id2 The id of the second package
|
||||||
|
:return: True if pkg_id1 and pkg_id2 have the same "signature" in
|
||||||
|
the package dependency graph (i.e. relations can not tell
|
||||||
|
them apart semantically except for their name). Otherwise False.
|
||||||
|
|
||||||
|
Note that this can return True even if pkg_id1 and pkg_id2 can
|
||||||
|
tell each other apart.
|
||||||
|
"""
|
||||||
|
return pkg_id2 in self.packages_equivalent_to(pkg_id1)
|
||||||
|
|
||||||
|
def packages_equivalent_to(self, pkg_id):
|
||||||
|
"""Determine which packages are equivalent to a given package
|
||||||
|
|
||||||
|
:param pkg_id: The BinaryPackageId of a binary package.
|
||||||
|
:return: A frozenset of all package ids that are equivalent to the
|
||||||
|
input package. Note that this set always includes the input
|
||||||
|
package assuming it is a known package.
|
||||||
|
"""
|
||||||
|
return NotImplemented
|
||||||
|
|
||||||
|
def relations_of(self, pkg_id):
|
||||||
|
"""Get the direct relations of a given packge
|
||||||
|
|
||||||
|
:param pkg_id: The BinaryPackageId of a binary package.
|
||||||
|
:return: A BinaryPackageRelation describing all known direct
|
||||||
|
relations for the package.
|
||||||
|
"""
|
||||||
|
return self._relations[pkg_id]
|
||||||
|
|
||||||
|
def __contains__(self, pkg_id):
|
||||||
|
return pkg_id in self._relations
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
yield from self._relations
|
Loading…
Reference in new issue