diff --git a/britney.py b/britney.py index 24e7ac7..b22440c 100755 --- a/britney.py +++ b/britney.py @@ -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.constraints, self._migration_item_factory) if not self.options.nuninst_cache: self.logger.info("Building the list of non-installable packages for the full archive") @@ -1473,8 +1473,10 @@ class Britney(object): with mm.start_transaction() as transaction: accepted = False try: - accepted, nuninst_after, failed_arch = mm.migrate_item_to_target_suite(comp, - nuninst_last_accepted) + accepted, nuninst_after, failed_arch, new_cruft = mm.migrate_item_to_target_suite( + comp, + nuninst_last_accepted + ) if accepted: selected.extend(comp) transaction.commit() @@ -1491,6 +1493,11 @@ class Britney(object): if self.options.check_consistency_level >= 3: target_suite.check_suite_source_pkg_consistency('iter_packages after commit') nuninst_last_accepted = nuninst_after + for cruft_item in new_cruft: + _, updates, rms, _ = mm.compute_groups(cruft_item) + result = (cruft_item, frozenset(updates), frozenset(rms)) + group_info[cruft_item] = result + worklist.extend([x] for x in new_cruft) rescheduled_packages.extend(maybe_rescheduled_packages) maybe_rescheduled_packages.clear() else: @@ -1609,15 +1616,19 @@ class Britney(object): if init: # init => a hint (e.g. "easy") - so do the hint run - (_, nuninst_end, _) = mm.migrate_item_to_target_suite(selected, - self.nuninst_orig, - stop_on_first_regression=False) + (_, nuninst_end, _, new_cruft) = mm.migrate_item_to_target_suite(selected, + self.nuninst_orig, + stop_on_first_regression=False) if recurse: # Ensure upgrade_me and selected do not overlap, if we # follow-up with a recurse ("hint"-hint). upgrade_me = [x for x in upgrade_me if x not in set(selected)] + # Add new cruft items regardless of whether we recurse. A future run might clean + # them for us. + upgrade_me.extend(new_cruft) + if recurse: # Either the main run or the recursive run of a "hint"-hint. (nuninst_end, extra) = self.iter_packages(upgrade_me, diff --git a/britney2/migration.py b/britney2/migration.py index 5eca167..a50001f 100644 --- a/britney2/migration.py +++ b/britney2/migration.py @@ -37,7 +37,7 @@ 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): + def __init__(self, options, suite_info, all_binaries, pkg_universe, constraints, migration_item_factory): self.options = options self.suite_info = suite_info self.all_binaries = all_binaries @@ -45,6 +45,7 @@ class MigrationManager(object): self.constraints = constraints self._transactions = [] self._all_architectures = frozenset(self.options.architectures) + self._migration_item_factory = migration_item_factory @property def current_transaction(self): @@ -243,8 +244,7 @@ class MigrationManager(object): pkg_universe = self.pkg_universe transaction = self.current_transaction - source_name, updates, rms, _ = self.compute_groups(item, removals=removals) - + source_name, updates, rms, smooth_updates = self.compute_groups(item, removals=removals) sources_t = target_suite.sources # Handle the source package old_source = sources_t.get(source_name) @@ -364,14 +364,14 @@ class MigrationManager(object): if transaction: transaction.add_undo_item(undo, updated_binaries) # return the affected packages (direct and than all) - return (affected_direct, affected_all) + return (affected_direct, affected_all, smooth_updates) def _apply_multiple_items_to_target_suite(self, items): is_source_migration = False if len(items) == 1: item = items[0] # apply the changes - affected_direct, affected_all = self._apply_item_to_target_suite(item) + affected_direct, affected_all, smooth_updates = self._apply_item_to_target_suite(item) if item.architecture == 'source': affected_architectures = self._all_architectures is_source_migration = True @@ -382,6 +382,7 @@ class MigrationManager(object): removals = set() affected_direct = set() affected_all = set() + smooth_updates = set() for item in items: _, _, rms, _ = self.compute_groups(item, allow_smooth_updates=False) removals.update(rms) @@ -392,12 +393,13 @@ class MigrationManager(object): is_source_migration = True for item in items: - item_affected_direct, item_affected_all = self._apply_item_to_target_suite(item, - removals=removals) + item_affected_direct, item_affected_all, item_smooth = self._apply_item_to_target_suite(item, + removals=removals) affected_direct.update(item_affected_direct) affected_all.update(item_affected_all) + smooth_updates.update(item_smooth) - return is_source_migration, affected_architectures, affected_direct, affected_all + return is_source_migration, affected_architectures, affected_direct, affected_all, smooth_updates def migrate_item_to_target_suite(self, items, nuninst_now, stop_on_first_regression=True): is_accepted = True @@ -409,7 +411,7 @@ class MigrationManager(object): break_arches = self.options.break_arches arch = None - is_source_migration, affected_architectures, affected_direct, affected_all = \ + is_source_migration, affected_architectures, affected_direct, affected_all, smooth_updates = \ self._apply_multiple_items_to_target_suite(items) # Optimise the test if we may revert directly. @@ -448,7 +450,9 @@ class MigrationManager(object): is_accepted = False break - return (is_accepted, nuninst_after, arch) + new_cruft = [self._migration_item_factory.generate_removal_for_cruft_item(x) for x in smooth_updates] + + return (is_accepted, nuninst_after, arch, new_cruft) @contextlib.contextmanager def start_transaction(self):