From d94b088b931b3527fc70f292480886a73d58ee65 Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Wed, 16 Sep 2009 18:13:39 +0000 Subject: [PATCH] Merged from trunk -r14270:14274 | 14271 | Make depgraph._select_atoms() return a dict, in order to | | zmedico | separate selected direct deps from indirect virtual deps. | | 14272 | Add support in depgraph._add_pkg_dep_string() for adding | | zmedico | indirect virtual deps to the graph. This takes advantage of | | | circular dependency avoidance that's done by dep_zapdeps, | | | while avoiding the dependency graph distortion reported in | | | bug #283795. | | 14273 | Fix broken virtual depth code from previous commit. | | zmedico | | | 14274 | Update documentation of inherit. Reported by Jeremy Olexa. | | arfrever | | svn path=/main/branches/prefix/; revision=14277 --- man/ebuild.5 | 9 ++--- pym/_emerge/depgraph.py | 76 ++++++++++++++++++++++++++++++++--------- 2 files changed, 64 insertions(+), 21 deletions(-) diff --git a/man/ebuild.5 b/man/ebuild.5 index dcb9b7eb0..56666e730 100644 --- a/man/ebuild.5 +++ b/man/ebuild.5 @@ -527,10 +527,11 @@ Inherit is portage's maintenance of extra classes of functions that are external to ebuilds and provided as inheritable capabilities and data. They define functions and set data types as drop\-in replacements, expanded, and simplified routines for extremely common tasks to streamline the build -process. Inherit may only be called once in an ebuild and it may \fBnever be -wrapped within any conditionals\fR of any kind. Specification of the eclasses -contains only their name and not the \fI.eclass\fR extension. Also note that -the inherit statement must come before other variable declarations. +process. Call to inherit cannot depend on conditions which can vary in given +ebuild. Specification of the eclasses contains only their name and not the +\fI.eclass\fR extension. Also note that the inherit statement must come +before other variable declarations unless these variables are used in global +scope of eclasses. .SH "PHASE FUNCTIONS" .TP .B pkg_nofetch diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index 23232d31e..ad3e2d06e 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -12,6 +12,7 @@ from itertools import chain, izip import portage from portage import os from portage import digraph +from portage.dep import Atom from portage.output import bold, blue, colorize, create_color_func, darkblue, \ darkgreen, green, nc_len, red, teal, turquoise, yellow bad = create_color_func("BAD") @@ -1146,7 +1147,7 @@ class depgraph(object): vardb = self._frozen_config.roots[dep_root].trees["vartree"].dbapi - for atom in selected_atoms: + for atom in selected_atoms[pkg]: try: atom = portage.dep.Atom(atom) @@ -1168,6 +1169,37 @@ class depgraph(object): if not pkg.installed: return 0 + selected_atoms.pop(pkg) + + # Add selected indirect virtual deps to the graph. This + # takes advantage of circular dependency avoidance that's done + # by dep_zapdeps. We preserve actual parent/child relationships + # here in order to avoid distorting the dependency graph like + # <=portage-2.1.6.x did. + for virt_pkg, atoms in selected_atoms.iteritems(): + + # Just assume depth + 1 here for now, though it's not entirely + # accurate since multilple levels of indirect virtual deps may + # have been traversed. The _add_pkg call will reset the depth to + # 0 if this package happens to match an argument. + if not self._add_pkg(virt_pkg, + Dependency(atom=Atom('=' + virt_pkg.cpv), + depth=(depth + 1), parent=pkg, priority=dep_priority.copy(), + root=dep_root)): + return 0 + + for atom in atoms: + # This is a GLEP 37 virtual, so its deps are all runtime. + mypriority = self._priority(runtime=True) + if not atom.blocker and vardb.match(atom): + mypriority.satisfied = True + + if not self._add_dep(Dependency(atom=atom, + blocker=atom.blocker, depth=virt_pkg.depth, + parent=virt_pkg, priority=mypriority, root=dep_root), + allow_unsatisfied=allow_unsatisfied): + return 0 + if debug: print "Exiting...", pkg @@ -1780,12 +1812,14 @@ class depgraph(object): for pkg in greedy_pkgs + [highest_pkg]: dep_str = " ".join(pkg.metadata[k] for k in blocker_dep_keys) try: - atoms = self._select_atoms( + selected_atoms = self._select_atoms( pkg.root, dep_str, pkg.use.enabled, parent=pkg, strict=True) except portage.exception.InvalidDependString: continue - blocker_atoms = (x for x in atoms if x.blocker) + blocker_atoms = [] + for atoms in selected_atoms.itervalues(): + blocker_atoms.extend(x for x in atoms if x.blocker) blockers[pkg] = InternalPackageSet(initial_atoms=blocker_atoms) if highest_pkg not in blockers: @@ -1862,17 +1896,24 @@ class depgraph(object): if parent is None: selected_atoms = mycheck[1] else: - if parent.cpv in atom_graph: - # TODO: Write code to add selected indirect virtual deps to - # the graph. This will take advantage of circular dependency - # avoidance that's done by dep_zapdeps. For now, only return - # direct deps here, since we don't want to distort the - # dependency graph by mixing indirect deps. - direct_deps = set(atom_graph.child_nodes(parent.cpv)) - selected_atoms = [atom for atom in mycheck[1] \ - if atom in direct_deps] - else: - selected_atoms = [] + chosen_atoms = frozenset(mycheck[1]) + selected_atoms = {parent : []} + for node in atom_graph: + if isinstance(node, Atom): + continue + if node == parent.cpv: + pkg = parent + else: + virt_atom = Atom('=' + node) + if virt_atom not in chosen_atoms: + continue + pkg, existing_node = self._select_package( + root, virt_atom) + if pkg is None: + raise AssertionError(node) + selected_atoms[pkg] = [atom for atom in \ + atom_graph.child_nodes(node) if atom in chosen_atoms] + return selected_atoms def _show_unsatisfied_dep(self, root, atom, myparent=None, arg=None): @@ -3027,9 +3068,10 @@ class depgraph(object): "'%svar/db/pkg/%s/RDEPEND': %s\n" % \ (running_root, running_portage.cpv, e), noiselevel=-1) del e - portage_rdepend = [] - runtime_deps.update(atom for atom in portage_rdepend \ - if not atom.startswith("!")) + portage_rdepend = {running_portage : []} + for atoms in portage_rdepend.itervalues(): + runtime_deps.update(atom for atom in atoms \ + if not atom.blocker) def gather_deps(ignore_priority, mergeable_nodes, selected_nodes, node): -- 2.26.2