britney.py: Make iter_packages repeat until no more actions work

Signed-off-by: Niels Thykier <niels@thykier.net>
master
Niels Thykier 9 years ago
parent 37c179f5f3
commit bbc6c34ca5

@ -2291,21 +2291,22 @@ class Britney(object):
return (is_accepted, nuninst_after, undo_list, arch)
def iter_packages(self, packages, selected, nuninst=None, lundo=None):
"""Iter on the list of actions and apply them one-by-one
This method applies the changes from `packages` to testing, checking the uninstallability
counters for every action performed. If the action does not improve them, it is reverted.
The method returns the new uninstallability counters and the remaining actions if the
final result is successful, otherwise (None, None).
final result is successful, otherwise (None, []).
"""
extra = []
groups = set()
group_info = {}
maybe_rescheduled = packages
changed = True
for y in sorted((y for y in packages), key=attrgetter('uvname')):
updates, rms, _ = self._compute_groups(y.package, y.suite, y.architecture, y.is_removal)
groups.add((y, frozenset(updates), frozenset(rms)))
result = (y, frozenset(updates), frozenset(rms))
group_info[y] = result
if selected is None:
selected = []
@ -2313,46 +2314,53 @@ class Britney(object):
nuninst_orig = nuninst
else:
nuninst_orig = self.nuninst_orig
nuninst_last_accepted = nuninst_orig
maybe_reschuled = []
worklist = self._inst_tester.solve_groups(groups)
worklist.reverse()
self.output_write("recur: [] %s %d/%d\n" % (",".join(x.uvname for x in selected), len(packages), len(extra)))
while worklist:
comp = worklist.pop()
comp_name = ' '.join(item.uvname for item in comp)
self.output_write("trying: %s\n" % comp_name)
accepted, nuninst_after, comp_undo, failed_arch = self.try_migration(comp, nuninst_last_accepted, lundo)
if accepted:
nuninst_last_accepted = nuninst_after
selected.extend(comp)
if lundo is not None:
lundo.extend(comp_undo)
self.output_write("accepted: %s\n" % comp_name)
self.output_write(" ori: %s\n" % (self.eval_nuninst(nuninst_orig)))
self.output_write(" pre: %s\n" % (self.eval_nuninst(nuninst_last_accepted)))
self.output_write(" now: %s\n" % (self.eval_nuninst(nuninst_after)))
if len(selected) <= 20:
self.output_write(" all: %s\n" % (" ".join(x.uvname for x in selected)))
else:
self.output_write(" most: (%d) .. %s\n" % (len(selected), " ".join(x.uvname for x in selected[-20:])))
else:
broken = sorted(b for b in nuninst_after[failed_arch]
if b not in nuninst_last_accepted[failed_arch])
compare_nuninst = None
if any(item for item in comp if item.architecture != 'source'):
compare_nuninst = nuninst_last_accepted
# NB: try_migration already reverted this for us, so just print the results and move on
self.output_write("skipped: %s (%d, %d)\n" % (comp_name, len(maybe_reschuled), len(worklist)))
self.output_write(" got: %s\n" % (self.eval_nuninst(nuninst_after, compare_nuninst)))
self.output_write(" * %s: %s\n" % (failed_arch, ", ".join(broken)))
if len(comp) > 1:
self.output_write(" - splitting the component into single items and retrying them\n")
worklist.extend([item] for item in comp)
self.output_write("recur: [] %s %d/0\n" % (",".join(x.uvname for x in selected), len(packages)))
while changed:
changed = False
groups = {group_info[x] for x in maybe_rescheduled}
worklist = self._inst_tester.solve_groups(groups)
maybe_rescheduled = []
worklist.reverse()
while worklist:
comp = worklist.pop()
comp_name = ' '.join(item.uvname for item in comp)
self.output_write("trying: %s\n" % comp_name)
accepted, nuninst_after, comp_undo, failed_arch = self.try_migration(comp, nuninst_last_accepted, lundo)
if accepted:
nuninst_last_accepted = nuninst_after
selected.extend(comp)
changed = True
if lundo is not None:
lundo.extend(comp_undo)
self.output_write("accepted: %s\n" % comp_name)
self.output_write(" ori: %s\n" % (self.eval_nuninst(nuninst_orig)))
self.output_write(" pre: %s\n" % (self.eval_nuninst(nuninst_last_accepted)))
self.output_write(" now: %s\n" % (self.eval_nuninst(nuninst_after)))
if len(selected) <= 20:
self.output_write(" all: %s\n" % (" ".join(x.uvname for x in selected)))
else:
self.output_write(" most: (%d) .. %s\n" % (len(selected), " ".join(x.uvname for x in selected[-20:])))
else:
extra.extend(comp)
broken = sorted(b for b in nuninst_after[failed_arch]
if b not in nuninst_last_accepted[failed_arch])
compare_nuninst = None
if any(item for item in comp if item.architecture != 'source'):
compare_nuninst = nuninst_last_accepted
# NB: try_migration already reverted this for us, so just print the results and move on
self.output_write("skipped: %s (%d, %d)\n" % (comp_name, len(maybe_rescheduled), len(worklist)))
self.output_write(" got: %s\n" % (self.eval_nuninst(nuninst_after, compare_nuninst)))
self.output_write(" * %s: %s\n" % (failed_arch, ", ".join(broken)))
if len(comp) > 1:
self.output_write(" - splitting the component into single items and retrying them\n")
worklist.extend([item] for item in comp)
else:
maybe_rescheduled.append(comp[0])
self.output_write(" finish: [%s]\n" % ",".join( x.uvname for x in selected ))
self.output_write("endloop: %s\n" % (self.eval_nuninst(self.nuninst_orig)))
@ -2361,7 +2369,7 @@ class Britney(object):
newly_uninst(self.nuninst_orig, nuninst_last_accepted)))
self.output_write("\n")
return (nuninst_last_accepted, extra)
return (nuninst_last_accepted, maybe_rescheduled)
def do_all(self, hinttype=None, init=None, actions=None):

Loading…
Cancel
Save