From a81424b600d38e9dfb4f26f9924cc270971e7886 Mon Sep 17 00:00:00 2001 From: Sebastian Luther Date: Thu, 17 May 2012 16:19:03 -0700 Subject: [PATCH] Use backtracking to force updates in case of conflicting packages possibly caused by not updating the parents --- pym/_emerge/depgraph.py | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index 572cea7..4426156 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -2273,10 +2273,24 @@ class depgraph(object): debug = "--debug" in self._frozen_config.myopts onlydeps = "--onlydeps" in self._frozen_config.myopts myroot = self._frozen_config.target_root + root_config = self._frozen_config.roots[myroot] pkgsettings = self._frozen_config.pkgsettings[myroot] pprovideddict = pkgsettings.pprovideddict virtuals = pkgsettings.getvirtuals() args = self._dynamic_config._initial_arg_list[:] + + for pkg in self._dynamic_config._runtime_pkg_mask: + #Add slot atoms to _initial_arg_list for packages + #where updating might solve a conflict, but the + #package wouldn't be pulled in otherwise. + #Note that this can't result in strange errors + #being displayed to the user, because if the backtracker + #gives up, the resolution is done without _runtime_pkg_mask + #and the original error gets displayed. + if "force update" in self._dynamic_config._runtime_pkg_mask[pkg]: + args.append( \ + AtomArg(atom=pkg.slot_atom, root_config=root_config)) + for root, atom in chain(self._rebuild.rebuild_list, self._rebuild.reinstall_list): args.append(AtomArg(arg=atom, atom=atom, @@ -4772,6 +4786,48 @@ class depgraph(object): if unresolved_blocks: self._dynamic_config._unsolvable_blockers.add(blocker, parent) + #Check if all parents of the package(s) that is/are blocked by this blocker + #are installed. If this is true, the blocked package(s) might not be + #pulled into the tree if we force updates for the parent packages. + pkgs_forced_to_update = set() + all_parents_installed = True + for blocked_pkg in blocked_initial: + for ppkg, patom in self._dynamic_config._parent_atoms.get(blocked_pkg): + if not ppkg.installed: + all_parents_installed = False + pkgs_forced_to_update.add(ppkg) + + if all_parents_installed: + if "--debug" in self._frozen_config.myopts: + msg = [] + msg.append("") + msg.append("") + msg.append("backtracking due to conflicting packages:") + msg.append(" blocker parent: %s" % blocker) + msg.append(" root: %s" % blocker.root) + msg.append(" atom: %s" % blocker.atom) + for blocked_pkg in blocked_initial: + msg.append(" blocked package: %s" % blocked_pkg) + for ppkg, patom in self._dynamic_config._parent_atoms.get(blocked_pkg): + msg.append(" masked parent: %s" % ppkg) + msg.append("") + writemsg_level("".join("%s\n" % l for l in msg), + noiselevel=-1, level=logging.DEBUG) + + for ppkg in pkgs_forced_to_update: + if ppkg in self._dynamic_config._runtime_pkg_mask: + if "--debug" in self._frozen_config.myopts: + writemsg( + "!!! backtracking loop detected: %s %s\n" % \ + (ppkg, + self._dynamic_config._runtime_pkg_mask[ + ppkg]), noiselevel=-1) + self._dynamic_config._runtime_pkg_mask.setdefault( + ppkg, {})["force update"] = \ + set([(ppkg, ppkg.root, blocker.atom)]) + + self._dynamic_config._need_restart = True + return True def _accept_blocker_conflicts(self): -- 1.7.9.7