summaryrefslogtreecommitdiffstats
path: root/pym
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2009-03-11 03:38:48 +0000
committerZac Medico <zmedico@gentoo.org>2009-03-11 03:38:48 +0000
commite1b024428fd4140fb6cebad2b3c60929b4e4bd28 (patch)
treeb38450cd25a346615b3080e57229bdd9d61cc37e /pym
parent99f134117886668d17cf47b15026773f3ff6a87e (diff)
downloadportage-e1b024428fd4140fb6cebad2b3c60929b4e4bd28.tar.gz
portage-e1b024428fd4140fb6cebad2b3c60929b4e4bd28.tar.bz2
portage-e1b024428fd4140fb6cebad2b3c60929b4e4bd28.zip
Bug #256616 - Also consider deep runtime dependencies of system packages when
adding packages to merge_wait_queue. (trunk r12578) svn path=/main/branches/2.1.6/; revision=12859
Diffstat (limited to 'pym')
-rw-r--r--pym/_emerge/__init__.py45
1 files changed, 43 insertions, 2 deletions
diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py
index bb7f11bb0..280e38541 100644
--- a/pym/_emerge/__init__.py
+++ b/pym/_emerge/__init__.py
@@ -9774,6 +9774,11 @@ class Scheduler(PollScheduler):
# empty.
self._merge_wait_scheduled = []
+ # Holds system packages and their deep runtime dependencies. Before
+ # being merged, these packages go to merge_wait_queue, to be merged
+ # when no other packages are building.
+ self._deep_system_deps = set()
+
self._status_display = JobStatusDisplay()
self._max_load = myopts.get("--load-average")
max_jobs = myopts.get("--jobs")
@@ -9948,9 +9953,44 @@ class Scheduler(PollScheduler):
return
self._digraph = digraph
+ self._find_system_deps()
self._prune_digraph()
self._prevent_builddir_collisions()
+ def _find_system_deps(self):
+ """
+ Find system packages and their deep runtime dependencies. Before being
+ merged, these packages go to merge_wait_queue, to be merged when no
+ other packages are building.
+ """
+ graph = self._digraph
+ deep_system_deps = self._deep_system_deps
+ deep_system_deps.clear()
+ node_stack = []
+ for node in graph.order:
+ if not isinstance(node, Package) or \
+ node.operation == "uninstall":
+ continue
+ system_set = node.root_config.sets["system"]
+ if system_set.findAtomForPackage(node):
+ node_stack.append(node)
+
+ while node_stack:
+ node = node_stack.pop()
+ if node in deep_system_deps:
+ continue
+ deep_system_deps.add(node)
+ # TODO: Only traverse runtime deps since we aren't concerned about
+ # buildtime deps here.
+ for child in graph.child_nodes(node):
+ if not isinstance(child, Package) or \
+ child.operation == "uninstall":
+ continue
+ node_stack.append(child)
+
+ deep_system_deps.difference_update([pkg for pkg in \
+ deep_system_deps if pkg.operation != "merge"])
+
def _prune_digraph(self):
"""
Prune any root nodes that are irrelevant.
@@ -10556,8 +10596,8 @@ class Scheduler(PollScheduler):
if build.returncode == os.EX_OK:
self.curval += 1
merge = PackageMerge(merge=build)
- system_set = build.pkg.root_config.sets["system"]
- if system_set.findAtomForPackage(build.pkg):
+ if not build.build_opts.buildpkgonly and \
+ build.pkg in self._deep_system_deps:
# Since dependencies on system packages are frequently
# unspecified, merge them only when no builds are executing.
self._merge_wait_queue.append(merge)
@@ -10613,6 +10653,7 @@ class Scheduler(PollScheduler):
def _main_loop_cleanup(self):
del self._pkg_queue[:]
self._completed_tasks.clear()
+ self._deep_system_deps.clear()
self._choose_pkg_return_early = False
self._status_display.reset()
self._digraph = None