From: Fabian Groffen Date: Tue, 30 Jun 2009 09:24:08 +0000 (-0000) Subject: Merged from trunk -r13733:13743 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=03ad9972e51f299f00014dd5d31ee718a3417827;p=portage.git Merged from trunk -r13733:13743 | 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) | | | 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 --- diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index 5ad75743d..3cf91405a 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -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]) diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 2f9bf0790..ad45924ba 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -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: