aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/_emerge')
-rw-r--r--lib/_emerge/actions.py33
-rw-r--r--lib/_emerge/depgraph.py21
2 files changed, 38 insertions, 16 deletions
diff --git a/lib/_emerge/actions.py b/lib/_emerge/actions.py
index 31252af16..4bf9ce425 100644
--- a/lib/_emerge/actions.py
+++ b/lib/_emerge/actions.py
@@ -1,8 +1,9 @@
-# Copyright 1999-2019 Gentoo Authors
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
from __future__ import division, print_function, unicode_literals
+import collections
import errno
import logging
import operator
@@ -741,8 +742,20 @@ def action_depclean(settings, trees, ldpath_mtimes,
return rval
+
def calc_depclean(settings, trees, ldpath_mtimes,
myopts, action, args_set, spinner):
+ result = _calc_depclean(settings, trees, ldpath_mtimes,
+ myopts, action, args_set, spinner)
+ return result.returncode, result.cleanlist, result.ordered, result.req_pkg_count
+
+
+_depclean_result = collections.namedtuple('_depclean_result',
+ ('returncode', 'cleanlist', 'ordered', 'req_pkg_count', 'depgraph'))
+
+
+def _calc_depclean(settings, trees, ldpath_mtimes,
+ myopts, action, args_set, spinner):
allow_missing_deps = bool(args_set)
debug = '--debug' in myopts
@@ -805,7 +818,7 @@ def calc_depclean(settings, trees, ldpath_mtimes,
writemsg_level(_("!!! Aborting due to set configuration "
"errors displayed above.\n"),
level=logging.ERROR, noiselevel=-1)
- return 1, [], False, 0
+ return _depclean_result(1, [], False, 0, None)
if action == "depclean":
emergelog(xterm_titles, " >>> depclean")
@@ -920,7 +933,7 @@ def calc_depclean(settings, trees, ldpath_mtimes,
resolver.display_problems()
if not success:
- return 1, [], False, 0
+ return _depclean_result(1, [], False, 0, resolver)
def unresolved_deps():
@@ -1020,7 +1033,7 @@ def calc_depclean(settings, trees, ldpath_mtimes,
return False
if unresolved_deps():
- return 1, [], False, 0
+ return _depclean_result(1, [], False, 0, resolver)
graph = resolver._dynamic_config.digraph.copy()
required_pkgs_total = 0
@@ -1321,7 +1334,7 @@ def calc_depclean(settings, trees, ldpath_mtimes,
runtime_slot_op=True),
root=pkg.root)):
resolver.display_problems()
- return 1, [], False, 0
+ return _depclean_result(1, [], False, 0, resolver)
writemsg_level("\nCalculating dependencies ")
success = resolver._complete_graph(
@@ -1329,9 +1342,9 @@ def calc_depclean(settings, trees, ldpath_mtimes,
writemsg_level("\b\b... done!\n")
resolver.display_problems()
if not success:
- return 1, [], False, 0
+ return _depclean_result(1, [], False, 0, resolver)
if unresolved_deps():
- return 1, [], False, 0
+ return _depclean_result(1, [], False, 0, resolver)
graph = resolver._dynamic_config.digraph.copy()
required_pkgs_total = 0
@@ -1340,7 +1353,7 @@ def calc_depclean(settings, trees, ldpath_mtimes,
required_pkgs_total += 1
cleanlist = create_cleanlist()
if not cleanlist:
- return 0, [], False, required_pkgs_total
+ return _depclean_result(0, [], False, required_pkgs_total, resolver)
clean_set = set(cleanlist)
if clean_set:
@@ -1458,8 +1471,8 @@ def calc_depclean(settings, trees, ldpath_mtimes,
graph.remove(node)
cleanlist.append(node.cpv)
- return 0, cleanlist, ordered, required_pkgs_total
- return 0, [], False, required_pkgs_total
+ return _depclean_result(0, cleanlist, ordered, required_pkgs_total, resolver)
+ return _depclean_result(0, [], False, required_pkgs_total, resolver)
def action_deselect(settings, trees, opts, atoms):
enter_invalid = '--ask-enter-invalid' in opts
diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py
index 8e0d79e29..27696ad40 100644
--- a/lib/_emerge/depgraph.py
+++ b/lib/_emerge/depgraph.py
@@ -6955,9 +6955,18 @@ class depgraph(object):
# Removal actions may override sets with temporary
# replacements that have had atoms removed in order
# to implement --deselect behavior.
- required_set_names = set(required_sets[root])
depgraph_sets.sets.clear()
depgraph_sets.sets.update(required_sets[root])
+ if 'world' in depgraph_sets.sets:
+ # For consistent order of traversal for both update
+ # and removal (depclean) actions, sets other that
+ # world are always nested under the world set.
+ world_atoms = list(depgraph_sets.sets['world'])
+ world_atoms.extend(SETPREFIX + s for s in required_sets[root] if s != 'world')
+ depgraph_sets.sets['world'] = InternalPackageSet(initial_atoms=world_atoms)
+ required_set_names = {'world'}
+ else:
+ required_set_names = set(required_sets[root])
if "remove" not in self._dynamic_config.myparams and \
root == self._frozen_config.target_root and \
already_deep:
@@ -6967,7 +6976,7 @@ class depgraph(object):
not self._dynamic_config._dep_stack:
continue
root_config = self._frozen_config.roots[root]
- for s in required_set_names:
+ for s in sorted(required_set_names):
pset = depgraph_sets.sets.get(s)
if pset is None:
pset = root_config.sets[s]
@@ -6977,10 +6986,10 @@ class depgraph(object):
self._set_args(args)
for arg in self._expand_set_args(args, add_to_digraph=True):
- for atom in sorted(arg.pset.getAtoms(), reverse=True):
- self._dynamic_config._dep_stack.append(
- Dependency(atom=atom, root=arg.root_config.root,
- parent=arg, depth=self._UNREACHABLE_DEPTH))
+ for atom in sorted(arg.pset.getAtoms()):
+ if not self._add_dep(Dependency(atom=atom, root=arg.root_config.root,
+ parent=arg, depth=self._UNREACHABLE_DEPTH), allow_unsatisfied=True):
+ return 0
if True:
if self._dynamic_config._ignored_deps: