Move traversal of world_sets from calc_depclean() to
authorZac Medico <zmedico@gentoo.org>
Fri, 17 Sep 2010 02:42:46 +0000 (19:42 -0700)
committerZac Medico <zmedico@gentoo.org>
Fri, 17 Sep 2010 02:42:46 +0000 (19:42 -0700)
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
pym/_emerge/depgraph.py

index b12c57116f57ef21b4a23c3cc16ba23e7d26bd8e..9f77036e8bcfde41f50fba2dcc3f2db288c62b80 100644 (file)
@@ -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:
index 4e7777cb64407cfc75ad13402c6d54d76e5d7add..d47517ebbd14131d1e581a409dfd1c92e40deed6 100644 (file)
@@ -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 = []