Add support to depgraph._select_atoms() to take a "parent" parameter
authorZac Medico <zmedico@gentoo.org>
Tue, 15 Apr 2008 06:32:24 +0000 (06:32 -0000)
committerZac Medico <zmedico@gentoo.org>
Tue, 15 Apr 2008 06:32:24 +0000 (06:32 -0000)
and use that to try and avoid unresolvable direct circular dependencies
when necessary. Also, make atom selection more consistent with the
graph to solve some cases of bug #1343. This improves the fix from
bug #141118 to work in cases when a virtual is not yet installed but
it has been pulled into the graph. For example, see the case of
Bug #163801#c17, where we want kaffe to satisfy virtual/jdk-1.4
without an extra jvm being pulled in unnecessarily. (trunk r9901)

svn path=/main/branches/2.1.2/; revision=9903

bin/emerge
pym/portage.py

index d0903559b40584059d9a32cab1096d56e2fe1d8f..ad5cce2254835e9550405d0cba798c324499efbb 100755 (executable)
@@ -1748,6 +1748,7 @@ class depgraph(object):
                                pass
                        filtered_tree.dbapi = self._dep_check_composite_db(self, myroot)
                        self._filtered_trees[myroot]["porttree"] = filtered_tree
+                       self._filtered_trees[myroot]["graph_db"] = graph_tree.dbapi
 
                        # Passing in graph_tree as the vartree here could lead to better
                        # atom selections in some cases by causing atoms for packages that
@@ -2209,7 +2210,7 @@ class depgraph(object):
                                vardb = self.roots[dep_root].trees["vartree"].dbapi
                                try:
                                        selected_atoms = self._select_atoms(dep_root,
-                                               dep_string, myuse=myuse, strict=strict)
+                                               dep_string, myuse=myuse, parent=pkg, strict=strict)
                                except portage_exception.InvalidDependString, e:
                                        show_invalid_depstring_notice(jbigkey, dep_string, str(e))
                                        return 0
@@ -2675,7 +2676,7 @@ class depgraph(object):
                return self._select_atoms_highest_available(*pargs, **kwargs)
 
        def _select_atoms_highest_available(self, root, depstring,
-               myuse=None, strict=True, trees=None):
+               myuse=None, parent=None, strict=True, trees=None):
                """This will raise InvalidDependString if necessary. If trees is
                None then self._filtered_trees is used."""
                pkgsettings = self.pkgsettings[root]
@@ -2683,12 +2684,16 @@ class depgraph(object):
                        trees = self._filtered_trees
                if True:
                        try:
+                               if parent is not None:
+                                       trees[root]["parent"] = parent
                                if not strict:
                                        portage_dep._dep_check_strict = False
                                mycheck = portage.dep_check(depstring, None,
                                        pkgsettings, myuse=myuse,
                                        myroot=root, trees=trees)
                        finally:
+                               if parent is not None:
+                                       trees[root].pop("parent")
                                portage_dep._dep_check_strict = True
                        if not mycheck[0]:
                                raise portage_exception.InvalidDependString(mycheck[1])
index 063acc5f75dbb8ee70a5dd8ebd8531e92fc596ba..3bb6451ee8c73c2c5e352f9e9eb10ed5f0c3452a 100644 (file)
@@ -5464,6 +5464,8 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None):
        other = []
 
        # Alias the trees we'll be checking availability against
+       parent   = trees[myroot].get("parent")
+       graph_db = trees[myroot].get("graph_db")
        vardb = None
        if "vartree" in trees[myroot]:
                vardb = trees[myroot]["vartree"].dbapi
@@ -5525,8 +5527,43 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None):
                                        preferred.append(this_choice)
                                else:
                                        preferred_any_slot.append(this_choice)
-                       else:
+                       elif graph_db is None:
                                possible_upgrades.append(this_choice)
+                       else:
+                               all_in_graph = True
+                               for slot_atom in versions:
+                                       # New-style virtuals have zero cost to install.
+                                       if not graph_db.match(slot_atom) and \
+                                               not slot_atom.startswith("virtual/"):
+                                               all_in_graph = False
+                                               break
+                               if all_in_graph:
+                                       if parent is None:
+                                               preferred.append(this_choice)
+                                       else:
+                                               # Check if the atom would result in a direct circular
+                                               # dependency and try to avoid that if it seems likely
+                                               # to be unresolvable.
+                                               cpv_slot_list = [parent.cpv_slot]
+                                               circular_atom = None
+                                               for atom in atoms:
+                                                       if "!" == atom[:1]:
+                                                               continue
+                                                       if vardb.match(atom):
+                                                               # If the atom is satisfied by an installed
+                                                               # version then it's not a circular dep.
+                                                               continue
+                                                       if dep_getkey(atom) != parent.cp:
+                                                               continue
+                                                       if match_from_list(atom, cpv_slot_list):
+                                                               circular_atom = atom
+                                                               break
+                                               if circular_atom is None:
+                                                       preferred.append(this_choice)
+                                               else:
+                                                       other.append(this_choice)
+                               else:
+                                       possible_upgrades.append(this_choice)
                else:
                        other.append(this_choice)