summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2010-09-16 19:42:46 -0700
committerZac Medico <zmedico@gentoo.org>2010-09-16 19:42:46 -0700
commitf0cf4ef06a71c18760c480802c289c2efd9162a8 (patch)
treec2d99db87b4b614c13b81b543436be60adf7f1ba
parentcc799474fb8f6ae476788d3768c4a3b341f3e7e8 (diff)
downloadportage-f0cf4ef06a71c18760c480802c289c2efd9162a8.tar.gz
portage-f0cf4ef06a71c18760c480802c289c2efd9162a8.tar.bz2
portage-f0cf4ef06a71c18760c480802c289c2efd9162a8.zip
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.
-rw-r--r--pym/_emerge/actions.py46
-rw-r--r--pym/_emerge/depgraph.py31
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 = []