Devuan deployment of britney2
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

272 lines
8.4 KiB

  1. import logging
  2. from collections import namedtuple
  3. from enum import Enum, unique
  4. class DependencyType(Enum):
  5. DEPENDS = ('Depends', 'depends', 'dependency')
  6. # BUILD_DEPENDS includes BUILD_DEPENDS_ARCH
  7. BUILD_DEPENDS = ('Build-Depends(-Arch)', 'build-depends', 'build-dependency')
  8. BUILD_DEPENDS_INDEP = ('Build-Depends-Indep', 'build-depends-indep', 'build-dependency (indep)')
  9. BUILT_USING = ('Built-Using', 'built-using', 'built-using')
  10. def __str__(self):
  11. return self.value[0]
  12. def get_reason(self):
  13. return self.value[1]
  14. def get_description(self):
  15. return self.value[2]
  16. @unique
  17. class SuiteClass(Enum):
  18. TARGET_SUITE = (False, False)
  19. PRIMARY_SOURCE_SUITE = (True, True)
  20. ADDITIONAL_SOURCE_SUITE = (True, False)
  21. @property
  22. def is_source(self):
  23. return self.value[0]
  24. @property
  25. def is_target(self):
  26. return not self.is_source
  27. @property
  28. def is_primary_source(self):
  29. return self is SuiteClass.PRIMARY_SOURCE_SUITE
  30. @property
  31. def is_additional_source(self):
  32. return self is SuiteClass.ADDITIONAL_SOURCE_SUITE
  33. class Suite(object):
  34. def __init__(self, suite_class, name, path, suite_short_name=None):
  35. self.suite_class = suite_class
  36. self.name = name
  37. self.path = path
  38. self.suite_short_name = suite_short_name if suite_short_name else ''
  39. self.sources = {}
  40. self._binaries = {}
  41. self.provides_table = {}
  42. self._all_binaries_in_suite = None
  43. @property
  44. def excuses_suffix(self):
  45. return self.suite_short_name
  46. @property
  47. def binaries(self):
  48. return self._binaries
  49. @binaries.setter
  50. def binaries(self, binaries):
  51. self._binaries = binaries
  52. self._all_binaries_in_suite = {x.pkg_id: x for a in binaries for x in binaries[a].values()}
  53. def any_of_these_are_in_the_suite(self, pkgs):
  54. """Test if at least one package of a given set is in the suite
  55. :param pkgs: A set of BinaryPackageId
  56. :return: True if any of the packages in pkgs are currently in the suite
  57. """
  58. return not self._all_binaries_in_suite.isdisjoint(pkgs)
  59. def is_pkg_in_the_suite(self, pkg_id):
  60. """Test if the package of is in testing
  61. :param pkg_id: A BinaryPackageId
  62. :return: True if the pkg is currently in the suite
  63. """
  64. return pkg_id in self._all_binaries_in_suite
  65. def which_of_these_are_in_the_suite(self, pkgs):
  66. """Iterate over all packages that are in the suite
  67. :param pkgs: An iterable of package ids
  68. :return: An iterable of package ids that are in the suite
  69. """
  70. yield from (x for x in pkgs if x in self._all_binaries_in_suite)
  71. class TargetSuite(Suite):
  72. def __init__(self, *args, **kwargs):
  73. super().__init__(*args, **kwargs)
  74. self.inst_tester = None
  75. logger_name = ".".join((self.__class__.__module__, self.__class__.__name__))
  76. self._logger = logging.getLogger(logger_name)
  77. def any_of_these_are_in_the_suite(self, pkg_ids):
  78. """Test if at least one package of a given set is in the suite
  79. :param pkg_ids: A set of BinaryPackageId
  80. :return: True if any of the packages in pkgs are currently in the suite
  81. """
  82. return self.inst_tester.any_of_these_are_in_the_suite(pkg_ids)
  83. def is_pkg_in_the_suite(self, pkg_id):
  84. """Test if the package of is in testing
  85. :param pkg_id: A BinaryPackageId
  86. :return: True if the pkg is currently in the suite
  87. """
  88. return self.inst_tester.is_pkg_in_the_suite(pkg_id)
  89. def which_of_these_are_in_the_suite(self, pkgs):
  90. """Iterate over all packages that are in the suite
  91. :param pkgs: An iterable of package ids
  92. :return: An iterable of package ids that are in the suite
  93. """
  94. yield from self.inst_tester.which_of_these_are_in_the_suite(pkgs)
  95. def is_installable(self, pkg_id):
  96. """Determine whether the given package can be installed in the suite
  97. :param pkg_id: A BinaryPackageId
  98. :return: True if the pkg is currently installable in the suite
  99. """
  100. return self.inst_tester.is_installable(pkg_id)
  101. def add_binary(self, pkg_id):
  102. """Add a binary package to the suite
  103. If the package is not known, this method will throw an
  104. KeyError.
  105. :param pkg_id The id of the package
  106. """
  107. self.inst_tester.add_binary(pkg_id)
  108. def remove_binary(self, pkg_id):
  109. """Remove a binary from the suite
  110. :param pkg_id The id of the package
  111. If the package is not known, this method will throw an
  112. KeyError.
  113. """
  114. self.inst_tester.remove_binary(pkg_id)
  115. def check_suite_source_pkg_consistency(self, comment):
  116. sources_t = self.sources
  117. binaries_t = self.binaries
  118. logger = self._logger
  119. issues_found = False
  120. logger.info("check_target_suite_source_pkg_consistency %s", comment)
  121. for arch in binaries_t:
  122. for pkg_name in binaries_t[arch]:
  123. pkg = binaries_t[arch][pkg_name]
  124. src = pkg.source
  125. if src not in sources_t: # pragma: no cover
  126. issues_found = True
  127. logger.error("inconsistency found (%s): src %s not in target, target has pkg %s with source %s" % (
  128. comment, src, pkg_name, src))
  129. for src in sources_t:
  130. source_data = sources_t[src]
  131. for pkg_id in source_data.binaries:
  132. binary, _, parch = pkg_id
  133. if binary not in binaries_t[parch]: # pragma: no cover
  134. issues_found = True
  135. logger.error("inconsistency found (%s): binary %s from source %s not in binaries_t[%s]" % (
  136. comment, binary, src, parch))
  137. if issues_found: # pragma: no cover
  138. raise AssertionError("inconsistencies found in target suite")
  139. class Suites(object):
  140. def __init__(self, target_suite, source_suites):
  141. self._suites = {}
  142. self._by_name_or_alias = {}
  143. self.target_suite = target_suite
  144. self.source_suites = source_suites
  145. self._suites[target_suite.name] = target_suite
  146. self._by_name_or_alias[target_suite.name] = target_suite
  147. if target_suite.suite_short_name:
  148. self._by_name_or_alias[target_suite.suite_short_name] = target_suite
  149. for suite in source_suites:
  150. self._suites[suite.name] = suite
  151. self._by_name_or_alias[suite.name] = suite
  152. if suite.suite_short_name:
  153. self._by_name_or_alias[suite.suite_short_name] = suite
  154. @property
  155. def primary_source_suite(self):
  156. return self.source_suites[0]
  157. @property
  158. def by_name_or_alias(self):
  159. return self._by_name_or_alias
  160. @property
  161. def additional_source_suites(self):
  162. return self.source_suites[1:]
  163. def __getitem__(self, item):
  164. return self._suites[item]
  165. def __len__(self):
  166. return len(self.source_suites) + 1
  167. def __contains__(self, item):
  168. return item in self._suites
  169. def __iter__(self):
  170. # Sources first (as we will rely on this for loading data in the old live-data tests)
  171. yield from self.source_suites
  172. yield self.target_suite
  173. class SourcePackage(object):
  174. __slots__ = ['version', 'section', 'binaries', 'maintainer', 'is_fakesrc', 'build_deps_arch', 'build_deps_indep',
  175. 'testsuite', 'testsuite_triggers']
  176. def __init__(self, version, section, binaries, maintainer, is_fakesrc, build_deps_arch, build_deps_indep,
  177. testsuite, testsuite_triggers):
  178. self.version = version
  179. self.section = section
  180. self.binaries = binaries
  181. self.maintainer = maintainer
  182. self.is_fakesrc = is_fakesrc
  183. self.build_deps_arch = build_deps_arch
  184. self.build_deps_indep = build_deps_indep
  185. self.testsuite = testsuite
  186. self.testsuite_triggers = testsuite_triggers
  187. def __getitem__(self, item):
  188. return getattr(self, self.__slots__[item])
  189. BinaryPackageId = namedtuple('BinaryPackageId', [
  190. 'package_name',
  191. 'version',
  192. 'architecture',
  193. ])
  194. BinaryPackage = namedtuple('BinaryPackage', [
  195. 'version',
  196. 'section',
  197. 'source',
  198. 'source_version',
  199. 'architecture',
  200. 'multi_arch',
  201. 'depends',
  202. 'conflicts',
  203. 'provides',
  204. 'is_essential',
  205. 'pkg_id',
  206. 'builtusing',
  207. ])