Merged from trunk -r14270:14274
authorFabian Groffen <grobian@gentoo.org>
Wed, 16 Sep 2009 18:13:39 +0000 (18:13 -0000)
committerFabian Groffen <grobian@gentoo.org>
Wed, 16 Sep 2009 18:13:39 +0000 (18:13 -0000)
   | 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
pym/_emerge/depgraph.py

index dcb9b7eb099153b1448399fb88e9e8088acfdc7d..56666e730fdfa350a209555f056f961b7a9d3ccb 100644 (file)
@@ -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
index 23232d31ea901165fb040f48a2ee2fbdc16c5b05..ad3e2d06e3116c55f35425f8fddc7740e51ce4b2 100644 (file)
@@ -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):