summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2009-02-13 03:29:01 +0000
committerZac Medico <zmedico@gentoo.org>2009-02-13 03:29:01 +0000
commit4d0658e3dc0bca1854b8ede5dbc4eed7509d1d59 (patch)
treef51869f0a1fb018363683af80741d74392af280e
parentab045e2584bee3148fa9c7c8842f9e304d2428b5 (diff)
downloadportage-4d0658e3dc0bca1854b8ede5dbc4eed7509d1d59.tar.gz
portage-4d0658e3dc0bca1854b8ede5dbc4eed7509d1d59.tar.bz2
portage-4d0658e3dc0bca1854b8ede5dbc4eed7509d1d59.zip
In depgraph._serialize_tasks(), verify that an uninstall task has at least one
theoretically mergeable parent before choosing to reverse it's edges. svn path=/main/trunk/; revision=12605
-rw-r--r--pym/_emerge/__init__.py70
1 files changed, 48 insertions, 22 deletions
diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py
index 52a307eb8..c02d99e6c 100644
--- a/pym/_emerge/__init__.py
+++ b/pym/_emerge/__init__.py
@@ -6862,6 +6862,41 @@ class depgraph(object):
runtime_deps.update(atom for atom in portage_rdepend \
if not atom.startswith("!"))
+ def gather_deps(ignore_priority, mergeable_nodes,
+ selected_nodes, node):
+ """
+ Recursively gather a group of nodes that RDEPEND on
+ eachother. This ensures that they are merged as a group
+ and get their RDEPENDs satisfied as soon as possible.
+ """
+ if node in selected_nodes:
+ return True
+ if node not in mergeable_nodes:
+ return False
+ if node == replacement_portage and \
+ mygraph.child_nodes(node,
+ ignore_priority=DepPriority.MEDIUM_SOFT):
+ # Make sure that portage always has all of it's
+ # RDEPENDs installed first.
+ return False
+ selected_nodes.add(node)
+ for child in mygraph.child_nodes(node,
+ ignore_priority=ignore_priority):
+ if not gather_deps(ignore_priority,
+ mergeable_nodes, selected_nodes, child):
+ return False
+ return True
+
+ def ignore_uninst_or_med(priority):
+ if priority is BlockerDepPriority.instance:
+ return True
+ return priority <= DepPriority.MEDIUM
+
+ def ignore_uninst_or_med_soft(priority):
+ if priority is BlockerDepPriority.instance:
+ return True
+ return priority <= DepPriority.MEDIUM_SOFT
+
ignore_priority_soft_range = [None]
ignore_priority_soft_range.extend(
xrange(DepPriority.MIN, DepPriority.MEDIUM_SOFT + 1))
@@ -6940,28 +6975,6 @@ class depgraph(object):
if not selected_nodes:
nodes = get_nodes(ignore_priority=DepPriority.MEDIUM)
if nodes:
- """Recursively gather a group of nodes that RDEPEND on
- eachother. This ensures that they are merged as a group
- and get their RDEPENDs satisfied as soon as possible."""
- def gather_deps(ignore_priority,
- mergeable_nodes, selected_nodes, node):
- if node in selected_nodes:
- return True
- if node not in mergeable_nodes:
- return False
- if node == replacement_portage and \
- mygraph.child_nodes(node,
- ignore_priority=DepPriority.MEDIUM_SOFT):
- # Make sure that portage always has all of it's
- # RDEPENDs installed first.
- return False
- selected_nodes.add(node)
- for child in mygraph.child_nodes(node,
- ignore_priority=ignore_priority):
- if not gather_deps(ignore_priority,
- mergeable_nodes, selected_nodes, child):
- return False
- return True
mergeable_nodes = set(nodes)
if prefer_asap and asap_nodes:
nodes = asap_nodes
@@ -7019,6 +7032,10 @@ class depgraph(object):
if not selected_nodes and not myblocker_uninstalls.is_empty():
# An Uninstall task needs to be executed in order to
# avoid conflict if possible.
+
+ mergeable_nodes = get_nodes(
+ ignore_priority=ignore_uninst_or_med)
+
min_parent_deps = None
uninst_task = None
for task in myblocker_uninstalls.leaf_nodes():
@@ -7144,10 +7161,19 @@ class depgraph(object):
# best possible choice, but the current algorithm
# is simple and should be near optimal for most
# common cases.
+ mergeable_parent = False
parent_deps = set()
for parent in mygraph.parent_nodes(task):
parent_deps.update(mygraph.child_nodes(parent,
ignore_priority=DepPriority.MEDIUM_SOFT))
+ if parent in mergeable_nodes and \
+ gather_deps(ignore_uninst_or_med_soft,
+ mergeable_nodes, set(), parent):
+ mergeable_parent = True
+
+ if not mergeable_parent:
+ continue
+
parent_deps.remove(task)
if min_parent_deps is None or \
len(parent_deps) < min_parent_deps: