From f0cf4ef06a71c18760c480802c289c2efd9162a8 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Thu, 16 Sep 2010 19:42:46 -0700 Subject: Move traversal of world_sets from calc_depclean() to depgraph._complete_graph(). With this patch, nested set traversal is only used for removal operations like --depclean and --prune. A later patch will introduce similar traversal for all operations, in order to solve bug #337540. --- pym/_emerge/actions.py | 46 ++++++++++++++++++++++------------------------ pym/_emerge/depgraph.py | 31 +++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py index b12c57116..9f77036e8 100644 --- a/pym/_emerge/actions.py +++ b/pym/_emerge/actions.py @@ -621,33 +621,18 @@ def calc_depclean(settings, trees, ldpath_mtimes, root_config = trees[myroot]["root_config"] psets = root_config.setconfig.psets deselect = myopts.get('--deselect') != 'n' - - required_set_stack = ["world"] required_sets = {} - set_args = [] + required_sets['world'] = psets['world'] - # Recursively create InternalPackageSet instances for world - # and any sets nested within it. - while required_set_stack: - s = required_set_stack.pop() - if s in required_sets: - continue - pset = psets.get(s) - if pset is not None: - required_sets[s] = InternalPackageSet( - initial_atoms=pset.getAtoms()) - for n in pset.getNonAtoms(): - if n.startswith(SETPREFIX): - required_set_stack.append(n[len(SETPREFIX):]) - - # When removing packages, use a temporary version of world 'selected' - # set which excludes packages that are intended to be eligible for - # removal. - selected_set = required_sets["selected"] + # When removing packages, a temporary version of the world 'selected' + # set may be used which excludes packages that are intended to be + # eligible for removal. + selected_set = psets['selected'] + required_sets['selected'] = selected_set protected_set = InternalPackageSet() protected_set_name = '____depclean_protected_set____' required_sets[protected_set_name] = protected_set - system_set = required_sets.get("system") + system_set = psets["system"] if not system_set or not selected_set: @@ -680,7 +665,11 @@ def calc_depclean(settings, trees, ldpath_mtimes, if args_set: if deselect: - selected_set.clear() + # Start with an empty set. + selected_set = InternalPackageSet() + required_sets['selected'] = selected_set + # Pull in any sets nested within the selected set. + selected_set.update(psets['selected'].getNonAtoms()) # Pull in everything that's installed but not matched # by an argument atom since we don't want to clean any @@ -702,7 +691,11 @@ def calc_depclean(settings, trees, ldpath_mtimes, elif action == "prune": if deselect: - selected_set.clear() + # Start with an empty set. + selected_set = InternalPackageSet() + required_sets['selected'] = selected_set + # Pull in any sets nested within the selected set. + selected_set.update(psets['selected'].getNonAtoms()) # Pull in everything that's installed since we don't # to prune a package if something depends on it. @@ -833,6 +826,11 @@ def calc_depclean(settings, trees, ldpath_mtimes, def create_cleanlist(): + if "--debug" in myopts: + writemsg("\ndigraph:\n\n", noiselevel=-1) + graph.debug_print() + writemsg("\n", noiselevel=-1) + # Never display the special internal protected_set. for node in graph: if isinstance(node, SetArg) and node.name == protected_set_name: diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index 4e7777cb6..d47517ebb 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -3085,10 +3085,37 @@ class depgraph(object): if root == self._frozen_config.target_root: self._dynamic_config._sets[s] = expanded_set vardb = root_config.trees["vartree"].dbapi - for arg in args: - for atom in arg.set: + while args: + arg = args.pop() + for atom in arg.set.getAtoms(): self._dynamic_config._dep_stack.append( Dependency(atom=atom, root=root, parent=arg)) + + # Removal actions may override sets with temporary + # replacements that have had atoms removed in order + # to implement --deselect behavior. + if required_sets is None: + set_overrides = {} + else: + set_overrides = required_sets.get(root, {}) + + # Traverse nested sets and add them to the stack + # if they're not already in the graph. Also, graph + # edges between parent and nested sets. + for token in arg.set.getNonAtoms(): + if not token.startswith(SETPREFIX): + continue + s = token[len(SETPREFIX):] + nested_set = set_overrides.get(s) + if nested_set is None: + nested_set = root_config.sets.get(s) + if nested_set is not None: + nested_arg = SetArg(arg=token, set=nested_set, + root_config=root_config) + if nested_arg not in self._dynamic_config.digraph: + args.append(nested_arg) + self._dynamic_config.digraph.add(nested_arg, arg) + if self._dynamic_config._ignored_deps: self._dynamic_config._dep_stack.extend(self._dynamic_config._ignored_deps) self._dynamic_config._ignored_deps = [] -- cgit v1.2.3-1-g7c22