mirror of
				https://git.launchpad.net/~ubuntu-release/britney/+git/britney2-ubuntu
				synced 2025-11-04 10:34:05 +00:00 
			
		
		
		
	britney.py: Make iter_packages repeat until no more actions work
Signed-off-by: Niels Thykier <niels@thykier.net>
This commit is contained in:
		
							parent
							
								
									37c179f5f3
								
							
						
					
					
						commit
						bbc6c34ca5
					
				
							
								
								
									
										94
									
								
								britney.py
									
									
									
									
									
								
							
							
						
						
									
										94
									
								
								britney.py
									
									
									
									
									
								
							@ -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)))
 | 
			
		||||
        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 = []
 | 
			
		||||
 | 
			
		||||
                if len(comp) > 1:
 | 
			
		||||
                    self.output_write("    - splitting the component into single items and retrying them\n")
 | 
			
		||||
                    worklist.extend([item] for item in comp)
 | 
			
		||||
            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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user