Allow new uninstallables from allow-uninst hint

When an allow-uninst hint is added for an unversioned binary package, items
are allowed to migrate, even if they make that binary package uninstallable
(on the architecture specified in the hint, if one was specified, or on all
architectures otherwise).

Using this hint should avoid using force-hint to allow specific breakage.

Signed-off-by: Ivo De Decker <ivodd@debian.org>
ubuntu/rebased
Ivo De Decker 5 years ago
parent 988b33d0ba
commit 93b46dde0d

@ -330,7 +330,7 @@ class Britney(object):
self._migration_item_factory = MigrationItemFactory(self.suite_info)
self._hint_parser = HintParser(self._migration_item_factory)
self._migration_manager = MigrationManager(self.options, self.suite_info, self.all_binaries, self.pkg_universe,
self.constraints, self._migration_item_factory)
self.constraints, self.allow_uninst, self._migration_item_factory)
if not self.options.nuninst_cache:
self.logger.info("Building the list of non-installable packages for the full archive")
@ -1071,6 +1071,7 @@ class Britney(object):
# This usually only happens with hints
break_arches = set()
better = is_nuninst_asgood_generous(self.constraints,
self.allow_uninst,
self.options.architectures,
self.nuninst_orig,
nuninst_end,

@ -25,8 +25,9 @@ def compute_eqv_set(pkg_universe, updates, rms):
return eqv_set
def is_nuninst_worse(must_be_installable, nuninst_now_arch, nuninst_after_arch):
if len(nuninst_after_arch) > len(nuninst_now_arch):
def is_nuninst_worse(must_be_installable, nuninst_now_arch, nuninst_after_arch, allow_uninst):
if len(nuninst_after_arch - allow_uninst) > \
len(nuninst_now_arch - allow_uninst):
return True
regression = nuninst_after_arch - nuninst_now_arch
@ -37,12 +38,13 @@ def is_nuninst_worse(must_be_installable, nuninst_now_arch, nuninst_after_arch):
class MigrationManager(object):
def __init__(self, options, suite_info, all_binaries, pkg_universe, constraints, migration_item_factory):
def __init__(self, options, suite_info, all_binaries, pkg_universe, constraints, allow_uninst, migration_item_factory):
self.options = options
self.suite_info = suite_info
self.all_binaries = all_binaries
self.pkg_universe = pkg_universe
self.constraints = constraints
self.allow_uninst = allow_uninst
self._transactions = []
self._all_architectures = frozenset(self.options.architectures)
self._migration_item_factory = migration_item_factory
@ -450,7 +452,7 @@ class MigrationManager(object):
# if the uninstallability counter is worse than before, break the loop
if stop_on_first_regression:
worse = is_nuninst_worse(must_be_installable, nuninst_now[arch], nuninst_after[arch])
worse = is_nuninst_worse(must_be_installable, nuninst_now[arch], nuninst_after[arch], self.allow_uninst[arch])
# ... except for a few special cases
if worse and ((not is_source_migration and arch not in new_arches) or

@ -334,7 +334,7 @@ def old_libraries(mi_factory, suite_info, outofsync_arches=frozenset()):
return removals
def is_nuninst_asgood_generous(constraints, architectures, old, new, break_arches=frozenset()):
def is_nuninst_asgood_generous(constraints, allow_uninst, architectures, old, new, break_arches=frozenset()):
"""Compares the nuninst counters and constraints to see if they improved
Given a list of architectures, the previous and the current nuninst
@ -355,7 +355,9 @@ def is_nuninst_asgood_generous(constraints, architectures, old, new, break_arche
for arch in architectures:
if arch in break_arches:
continue
diff = diff + (len(new[arch]) - len(old[arch]))
diff = diff + \
(len(new[arch] - allow_uninst[arch])
- len(old[arch] - allow_uninst[arch]))
if diff > 0:
return False
must_be_installable = constraints['keep-installable']

Loading…
Cancel
Save