Merged from trunk -r13733:13743
authorFabian Groffen <grobian@gentoo.org>
Tue, 30 Jun 2009 09:24:08 +0000 (09:24 -0000)
committerFabian Groffen <grobian@gentoo.org>
Tue, 30 Jun 2009 09:24:08 +0000 (09:24 -0000)
   | 13735   | Move code from bug #258773 to dep_zapdeps, since the parent  |
   | zmedico | always needs to be passed in for atom validation in order to |
   |         | solve bug #275821.                                           |

   | 13736   | Bug #275821 - Make emerge reject !!atom blockers for EAPI 0  |
   | zmedico | and 1.                                                       |

   | 13737   | Bug #275796 - Prefer packages selected for install over      |
   | zmedico | installed packages. This helps automatically solve cases     |
   |         | such as the upgrade to the new bluez package which requires  |
   |         | uninstallation of the older bluez-libs and bluez-utils       |
   |         | packages. Thanks to Sebastian Mingramm (few)                 |
   |         | <s.mingramm@gmx.de> for this patch.                          |

   | 13738   | Use a finally blocker to ensure _expand_new_virtuals         |
   | zmedico | properly resets eapi state when an exception is raised.      |

   | 13739   | Fix virtual blocker code inside _expand_new_virtuals to      |
   | zmedico | correctly handle !!atom blockers.                            |

   | 13740   | Remove the upgrade selection code inside dep_zapdeps (from   |
   | zmedico | bug #171840 and bug #159360) since the code in               |
   |         | depgraph._dep_check_composite_db._visible() from bug #253904 |
   |         | now masks choices that do not match the highest available    |
   |         | version in the slot. This means that such undesirable        |
   |         | choices automatically go into the dep_zapdeps "other"        |
   |         | category.                                                    |

   | 13741   | In _expand_new_virtuals, don't expand old-style virtuals     |
   | zmedico | when there is a new-style match.                             |

   | 13742   | Bug #82488 - In _expand_new_virtuals(), check PROVIDE before |
   | zmedico | expanding old-style virtuals.                                |

   | 13743   | Bug #275901 - Make emerge bail out for USE deps in EAPI 0    |
   | zmedico | and 1.                                                       |

svn path=/main/branches/prefix/; revision=13744

pym/_emerge/depgraph.py
pym/portage/__init__.py

index 5ad75743df6c2d737c63ef27229c6a0aebe36127..3cf91405a08af9c93385127c567d7cf16c969eb2 100644 (file)
@@ -1595,18 +1595,12 @@ class depgraph(object):
                pkgsettings = self.pkgsettings[root]
                if trees is None:
                        trees = self._filtered_trees
-               if not getattr(priority, "buildtime", False):
-                       # The parent should only be passed to dep_check() for buildtime
-                       # dependencies since that's the only case when it's appropriate
-                       # to trigger the circular dependency avoidance code which uses it.
-                       # It's important not to trigger the same circular dependency
-                       # avoidance code for runtime dependencies since it's not needed
-                       # and it can promote an incorrect package choice.
-                       parent = None
                if True:
                        try:
                                if parent is not None:
                                        trees[root]["parent"] = parent
+                               if priority is not None:
+                                       trees[root]["priority"] = priority
                                if not strict:
                                        portage.dep._dep_check_strict = False
                                mycheck = portage.dep_check(depstring, None,
@@ -1615,6 +1609,8 @@ class depgraph(object):
                        finally:
                                if parent is not None:
                                        trees[root].pop("parent")
+                               if priority is not None:
+                                       trees[root].pop("priority")
                                portage.dep._dep_check_strict = True
                        if not mycheck[0]:
                                raise portage.exception.InvalidDependString(mycheck[1])
index 2f9bf07905cef2c094de78827ed29dc13b936c0c..ad45924baca6506abb077e8138bc476860d1201b 100644 (file)
@@ -6901,7 +6901,12 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/",
        # According to GLEP 37, RDEPEND is the only dependency type that is valid
        # for new-style virtuals.  Repoman should enforce this.
        dep_keys = ["RDEPEND", "DEPEND", "PDEPEND"]
-       portdb = trees[myroot]["porttree"].dbapi
+       mytrees = trees[myroot]
+       portdb = mytrees["porttree"].dbapi
+       parent = mytrees.get("parent")
+       eapi = mytrees.get("eapi")
+       if eapi is None and parent is not None:
+               eapi = parent.metadata["EAPI"]
        repoman = not mysettings.local_config
        if kwargs["use_binaries"]:
                portdb = trees[myroot]["bintree"].dbapi
@@ -6924,6 +6929,15 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/",
                                if portage.dep._dep_check_strict:
                                        raise portage.exception.ParseError(
                                                "invalid atom: '%s'" % x)
+                       else:
+                               if x.blocker and x.blocker.overlap.forbid and \
+                                       eapi in ("0", "1") and portage.dep._dep_check_strict:
+                                       raise portage.exception.ParseError(
+                                               "invalid atom: '%s'" % (x,))
+                               if x.use and eapi in ("0", "1") and \
+                                       portage.dep._dep_check_strict:
+                                       raise portage.exception.ParseError(
+                                               "invalid atom: '%s'" % (x,))
 
                if repoman and x.use and x.use.conditional:
                        evaluated_atom = portage.dep.remove_slot(x)
@@ -6956,7 +6970,8 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/",
                        continue
                match_atom = x
                if isblocker:
-                       match_atom = x[1:]
+                       match_atom = x.lstrip("!")
+                       isblocker = x[:-len(match_atom)]
                pkgs = []
                matches = portdb.match(match_atom)
                # Use descending order to prefer higher versions.
@@ -6973,13 +6988,8 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/",
                        # dependency that needs to be satisfied.
                        newsplit.append(x)
                        continue
-               if not pkgs and len(mychoices) == 1:
-                       newsplit.append(portage.dep.Atom(x.replace(mykey, mychoices[0])))
-                       continue
-               if isblocker:
-                       a = []
-               else:
-                       a = ['||']
+
+               a = []
                for y in pkgs:
                        cpv, pv_split, db = y
                        depstring = " ".join(db.aux_get(cpv, dep_keys))
@@ -6993,8 +7003,22 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/",
                        if edebug:
                                print "Virtual Parent:   ", y[0]
                                print "Virtual Depstring:", depstring
-                       mycheck = dep_check(depstring, mydbapi, mysettings, myroot=myroot,
-                               trees=trees, **pkg_kwargs)
+
+                       # Set EAPI used for validation in dep_check() recursion.
+                       virtual_eapi, = db.aux_get(cpv, ["EAPI"])
+                       prev_eapi = mytrees.get("eapi")
+                       mytrees["eapi"] = virtual_eapi
+
+                       try:
+                               mycheck = dep_check(depstring, mydbapi, mysettings,
+                                       myroot=myroot, trees=trees, **pkg_kwargs)
+                       finally:
+                               # Restore previous EAPI after recursion.
+                               if prev_eapi is not None:
+                                       mytrees["eapi"] = prev_eapi
+                               else:
+                                       del mytrees["eapi"]
+
                        if not mycheck[0]:
                                raise portage.exception.ParseError(
                                        "%s: %s '%s'" % (y[0], mycheck[1], depstring))
@@ -7004,19 +7028,37 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/",
                                if len(virtual_atoms) == 1:
                                        # It wouldn't make sense to block all the components of a
                                        # compound virtual, so only a single atom block is allowed.
-                                       a.append(portage.dep.Atom("!" + virtual_atoms[0]))
+                                       a.append(portage.dep.Atom(isblocker + virtual_atoms[0]))
                        else:
                                # pull in the new-style virtual
                                mycheck[1].append(portage.dep.Atom("="+y[0]))
                                a.append(mycheck[1])
                # Plain old-style virtuals.  New-style virtuals are preferred.
-               for y in mychoices:
-                       a.append(portage.dep.Atom(x.replace(mykey, y, 1)))
-               if isblocker and not a:
-                       # Probably a compound virtual.  Pass the atom through unprocessed.
+               if not pkgs:
+                       if repoman:
+                               # TODO: Add PROVIDE check for repoman.
+                               for y in mychoices:
+                                       a.append(portage.dep.Atom(x.replace(mykey, y, 1)))
+                       else:
+                               for y in mychoices:
+                                       new_atom = portage.dep.Atom(x.replace(mykey, y, 1))
+                                       matches = portdb.match(new_atom)
+                                       # portdb is an instance of depgraph._dep_check_composite_db, so
+                                       # USE conditionals are already evaluated.
+                                       if matches and mykey in \
+                                               portdb.aux_get(matches[-1], ['PROVIDE'])[0].split():
+                                               a.append(new_atom)
+
+               if not a:
                        newsplit.append(x)
-                       continue
-               newsplit.append(a)
+               elif len(a) == 1:
+                       newsplit.append(a[0])
+               else:
+                       if isblocker:
+                               newsplit.extend(a)
+                       else:
+                               newsplit.append(['||'] + a)
+
        return newsplit
 
 def dep_eval(deplist):
@@ -7075,14 +7117,15 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None):
        # c) contains masked installed packages
        # d) is the first item
 
-       preferred = []
-       preferred_not_installed = []
+       preferred_installed = []
+       preferred_in_graph = []
        preferred_any_slot = []
-       possible_upgrades = []
+       preferred_non_installed = []
        other = []
 
        # Alias the trees we'll be checking availability against
        parent   = trees[myroot].get("parent")
+       priority = trees[myroot].get("priority")
        graph_db = trees[myroot].get("graph_db")
        vardb = None
        if "vartree" in trees[myroot]:
@@ -7092,15 +7135,15 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None):
        else:
                mydbapi = trees[myroot]["porttree"].dbapi
 
-       # Sort the deps into preferred (installed) and other
-       # with values of [[required_atom], availablility]
+       # Sort the deps into installed, not installed but already 
+       # in the graph and other, not installed and not in the graph
+       # and other, with values of [[required_atom], availablility]
        for dep, satisfied in izip(deps, satisfieds):
                if isinstance(dep, list):
                        atoms = dep_zapdeps(dep, satisfied, myroot,
                                use_binaries=use_binaries, trees=trees)
                else:
                        atoms = [dep]
-
                if not vardb:
                        # called by repoman
                        other.append((atoms, None, False))
@@ -7125,8 +7168,8 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None):
                this_choice = (atoms, versions, all_available)
                if all_available:
                        # The "all installed" criterion is not version or slot specific.
-                       # If any version of a package is installed then we assume that it
-                       # is preferred over other possible packages choices.
+                       # If any version of a package is already in the graph then we
+                       # assume that it is preferred over other possible packages choices.
                        all_installed = True
                        for atom in set([dep_getkey(atom) for atom in atoms \
                                if atom[:1] != "!"]):
@@ -7145,7 +7188,7 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None):
                                                break
                        if all_installed:
                                if all_installed_slots:
-                                       preferred.append(this_choice)
+                                       preferred_installed.append(this_choice)
                                else:
                                        preferred_any_slot.append(this_choice)
                        elif graph_db is None:
@@ -7159,12 +7202,14 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None):
                                                all_in_graph = False
                                                break
                                if all_in_graph:
-                                       if parent is None:
-                                               preferred_not_installed.append(this_choice)
-                                       else:
+                                       if parent is None or priority is None:
+                                               preferred_in_graph.append(this_choice)
+                                       elif priority.buildtime:
                                                # Check if the atom would result in a direct circular
                                                # dependency and try to avoid that if it seems likely
-                                               # to be unresolvable.
+                                               # to be unresolvable. This is only relevant for
+                                               # buildtime deps that aren't already satisfied by an
+                                               # installed package.
                                                cpv_slot_list = [parent]
                                                circular_atom = None
                                                for atom in atoms:
@@ -7180,59 +7225,16 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None):
                                                                circular_atom = atom
                                                                break
                                                if circular_atom is None:
-                                                       preferred_not_installed.append(this_choice)
+                                                       preferred_in_graph.append(this_choice)
                                                else:
                                                        other.append(this_choice)
                                else:
-                                       possible_upgrades.append(this_choice)
+                                       preferred_non_installed.append(this_choice)
                else:
                        other.append(this_choice)
 
-       # Compare the "all_installed" choices against the "all_available" choices
-       # for possible missed upgrades.  The main purpose of this code is to find
-       # upgrades of new-style virtuals since _expand_new_virtuals() expands them
-       # into || ( highest version ... lowest version ).  We want to prefer the
-       # highest all_available version of the new-style virtual when there is a
-       # lower all_installed version.
-       preferred.extend(preferred_not_installed)
-       preferred.extend(preferred_any_slot)
-       preferred.extend(possible_upgrades)
-       possible_upgrades = preferred[1:]
-       for possible_upgrade in possible_upgrades:
-               atoms, versions, all_available = possible_upgrade
-               myslots = set(versions)
-               for other_choice in preferred:
-                       if possible_upgrade is other_choice:
-                               # possible_upgrade will not be promoted, so move on
-                               break
-                       o_atoms, o_versions, o_all_available = other_choice
-                       intersecting_slots = myslots.intersection(o_versions)
-                       if not intersecting_slots:
-                               continue
-                       has_upgrade = False
-                       has_downgrade = False
-                       for myslot in intersecting_slots:
-                               myversion = versions[myslot]
-                               o_version = o_versions[myslot]
-                               difference = pkgcmp(catpkgsplit(myversion)[1:],
-                                       catpkgsplit(o_version)[1:])
-                               if difference:
-                                       if difference > 0:
-                                               has_upgrade = True
-                                       else:
-                                               has_downgrade = True
-                                               break
-                       if has_upgrade and not has_downgrade:
-                               preferred.remove(possible_upgrade)
-                               o_index = preferred.index(other_choice)
-                               preferred.insert(o_index, possible_upgrade)
-                               break
-
-       # preferred now contains a) and c) from the order above with
-       # the masked flag differentiating the two. other contains b)
-       # and d) so adding other to preferred will give us a suitable
-       # list to iterate over.
-       preferred.extend(other)
+       preferred = preferred_in_graph + preferred_installed + \
+               preferred_any_slot + preferred_non_installed + other
 
        for allow_masked in (False, True):
                for atoms, versions, all_available in preferred: