from collections import namedtuple from enum import Enum, unique class DependencyType(Enum): DEPENDS = ('Depends', 'depends', 'dependency') # BUILD_DEPENDS includes BUILD_DEPENDS_ARCH BUILD_DEPENDS = ('Build-Depends(-Arch)', 'build-depends', 'build-dependency') BUILD_DEPENDS_INDEP = ('Build-Depends-Indep', 'build-depends-indep', 'build-dependency (indep)') def __str__(self): return self.value[0] def get_reason(self): return self.value[1] def get_description(self): return self.value[2] @unique class SuiteClass(Enum): TARGET_SUITE = (False, False) PRIMARY_SOURCE_SUITE = (True, True) ADDITIONAL_SOURCE_SUITE = (True, False) @property def is_source(self): return self.value[0] @property def is_target(self): return not self.is_source @property def is_primary_source(self): return self is SuiteClass.PRIMARY_SOURCE_SUITE @property def is_additional_source(self): return self is SuiteClass.ADDITIONAL_SOURCE_SUITE class Suite(object): def __init__(self, suite_class, name, path, suite_short_name=None): self.suite_class = suite_class self.name = name self.path = path self.suite_short_name = suite_short_name if suite_short_name else '' self.sources = {} self._binaries = {} self.provides_table = {} self._all_binaries_in_suite = None @property def excuses_suffix(self): return self.suite_short_name @property def binaries(self): return self._binaries @binaries.setter def binaries(self, binaries): self._binaries = binaries self._all_binaries_in_suite = {x.pkg_id: x for a in binaries for x in binaries[a].values()} def any_of_these_are_in_the_suite(self, pkgs): """Test if at least one package of a given set is in the suite :param pkgs: A set of BinaryPackageId :return: True if any of the packages in pkgs are currently in the suite """ return not self._all_binaries_in_suite.isdisjoint(pkgs) def is_pkg_in_the_suite(self, pkg_id): """Test if the package of is in testing :param pkg_id: A BinaryPackageId :return: True if the pkg is currently in the suite """ return pkg_id in self._all_binaries_in_suite class TargetSuite(Suite): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.inst_tester = None def any_of_these_are_in_the_suite(self, pkg_ids): """Test if at least one package of a given set is in the suite :param pkg_ids: A set of BinaryPackageId :return: True if any of the packages in pkgs are currently in the suite """ return self.inst_tester.any_of_these_are_in_the_suite(pkg_ids) def is_pkg_in_the_suite(self, pkg_id): """Test if the package of is in testing :param pkg_id: A BinaryPackageId :return: True if the pkg is currently in the suite """ return self.inst_tester.is_pkg_in_the_suite(pkg_id) def is_installable(self, pkg_id): """Determine whether the given package can be installed in the suite :param pkg_id: A BinaryPackageId :return: True if the pkg is currently installable in the suite """ return self.inst_tester.is_installable(pkg_id) def add_binary(self, pkg_id): """Add a binary package to the suite If the package is not known, this method will throw an KeyError. :param pkg_id The id of the package """ self.inst_tester.add_binary(pkg_id) def remove_binary(self, pkg_id): """Remove a binary from the suite :param pkg_id The id of the package If the package is not known, this method will throw an KeyError. """ self.inst_tester.remove_binary(pkg_id) class Suites(object): def __init__(self, target_suite, source_suites): self._suites = {} self._by_name_or_alias = {} self.target_suite = target_suite self.source_suites = source_suites self._suites[target_suite.name] = target_suite self._by_name_or_alias[target_suite.name] = target_suite if target_suite.suite_short_name: self._by_name_or_alias[target_suite.suite_short_name] = target_suite for suite in source_suites: self._suites[suite.name] = suite self._by_name_or_alias[suite.name] = suite if suite.suite_short_name: self._by_name_or_alias[suite.suite_short_name] = suite @property def primary_source_suite(self): return self.source_suites[0] @property def by_name_or_alias(self): return self._by_name_or_alias @property def additional_source_suites(self): return self.source_suites[1:] def __getitem__(self, item): return self._suites[item] def __len__(self): return len(self.source_suites) + 1 def __contains__(self, item): return item in self._suites def __iter__(self): # Sources first (as we will rely on this for loading data in the old live-data tests) yield from self.source_suites yield self.target_suite class SourcePackage(object): __slots__ = ['version', 'section', 'binaries', 'maintainer', 'is_fakesrc', 'build_deps_arch', 'build_deps_indep', 'testsuite', 'testsuite_triggers'] def __init__(self, version, section, binaries, maintainer, is_fakesrc, build_deps_arch, build_deps_indep, testsuite, testsuite_triggers): self.version = version self.section = section self.binaries = binaries self.maintainer = maintainer self.is_fakesrc = is_fakesrc self.build_deps_arch = build_deps_arch self.build_deps_indep = build_deps_indep self.testsuite = testsuite self.testsuite_triggers = testsuite_triggers def __getitem__(self, item): return getattr(self, self.__slots__[item]) BinaryPackageId = namedtuple('BinaryPackageId', [ 'package_name', 'version', 'architecture', ]) BinaryPackage = namedtuple('BinaryPackage', [ 'version', 'section', 'source', 'source_version', 'architecture', 'multi_arch', 'depends', 'conflicts', 'provides', 'is_essential', 'pkg_id', ])