From 61555134609c642fea6f99b5c2a1f2d0018d9dd1 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Thu, 28 Jun 2007 01:33:54 +0000 Subject: [PATCH] - Improve tracking of correspondence between arguments and packages in the depgraph. (trunk r7063) - Cache aux_get() metadata in depgraph.create() and use PROVIDE for matching packages to arguments. (trunk r7064) - Just use a containment test for matching pprovided args since it works correctly and match_to_list() isn't appropriate for this. (trunk r7065) svn path=/main/branches/2.1.2/; revision=7066 --- bin/emerge | 74 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 20 deletions(-) diff --git a/bin/emerge b/bin/emerge index 5c27d4b88..039e3e3ad 100755 --- a/bin/emerge +++ b/bin/emerge @@ -934,7 +934,8 @@ class depgraph: # Maps slot atom to digraph node for all nodes added to the graph. self._slot_node_map = {} self.mydbapi = {} - self._mydbapi_keys = ["SLOT", "DEPEND", "RDEPEND", "PDEPEND"] + self._mydbapi_keys = ["SLOT", "DEPEND", "RDEPEND", "PDEPEND", + "USE", "IUSE", "PROVIDE"] self.useFlags = {} self.trees = {} for myroot in trees: @@ -978,6 +979,7 @@ class depgraph: self.orderedkeys=[] self.outdatedpackages=[] self._args_atoms = {} + self._args_nodes = set() self.blocker_digraph = digraph() self.blocker_parents = {} self._unresolved_blocker_parents = {} @@ -1108,16 +1110,21 @@ class depgraph: # directive, otherwise we add a "merge" directive. mydbapi = self.trees[myroot][self.pkg_tree_map[mytype]].dbapi + metadata = dict(izip(self._mydbapi_keys, + mydbapi.aux_get(mykey, self._mydbapi_keys))) + if mytype == "ebuild": + pkgsettings.setcpv(mykey, mydb=portdb) + metadata["USE"] = pkgsettings["USE"] + myuse = pkgsettings["USE"].split() if not arg and myroot == self.target_root: - cpv_slot = "%s:%s" % (mykey, mydbapi.aux_get(mykey, ["SLOT"])[0]) - cp = portage.dep_getkey(mykey) - if cp in self._args_atoms: - arg = portage.best_match_to_list(cpv_slot, self._args_atoms[cp]) - - if myuse is None: - self.pkgsettings[myroot].setcpv(mykey, mydb=portdb) - myuse = self.pkgsettings[myroot]["USE"].split() + try: + arg = self._get_arg(mykey, metadata) + except portage_exception.InvalidDependString, e: + show_invalid_depstring_notice(tuple(mybigkey+["merge"]), + metadata["PROVIDE"], str(e)) + del e + return 0 merging=1 if mytype == "installed": @@ -1140,8 +1147,7 @@ class depgraph: forced_flags.update(pkgsettings.useforce) forced_flags.update(pkgsettings.usemask) old_use = vardbapi.aux_get(mykey, ["USE"])[0].split() - iuses = set(filter_iuse_defaults( - mydbapi.aux_get(mykey, ["IUSE"])[0].split())) + iuses = set(filter_iuse_defaults(metadata["IUSE"].split())) old_iuse = set(filter_iuse_defaults( vardbapi.aux_get(mykey, ["IUSE"])[0].split())) if self._reinstall_for_flags( @@ -1155,8 +1161,6 @@ class depgraph: jbigkey = tuple(mybigkey) if addme: - metadata = dict(izip(self._mydbapi_keys, - mydbapi.aux_get(mykey, self._mydbapi_keys))) if merging == 0 and vardbapi.cpv_exists(mykey) and \ mytype != "installed": mybigkey[0] = "installed" @@ -1164,7 +1168,7 @@ class depgraph: jbigkey = tuple(mybigkey) metadata = dict(izip(self._mydbapi_keys, mydbapi.aux_get(mykey, self._mydbapi_keys))) - myuse = mydbapi.aux_get(mykey, ["USE"])[0].split() + myuse = metadata["USE"].split() slot_atom = "%s:%s" % (portage.dep_getkey(mykey), metadata["SLOT"]) existing_node = self._slot_node_map[myroot].get( slot_atom, None) @@ -1222,6 +1226,9 @@ class depgraph: self.digraph.addnode(jbigkey, myparent, priority=priority) + if arg: + self._args_nodes.add(jbigkey) + # Do this even when addme is False (--onlydeps) so that the # parent/child relationship is always known in case # self._show_slot_collision_notice() needs to be called later. @@ -1245,9 +1252,8 @@ class depgraph: edepend={} depkeys = ["DEPEND","RDEPEND","PDEPEND"] - depvalues = mydbapi.aux_get(mykey, depkeys) - for i in xrange(len(depkeys)): - edepend[depkeys[i]] = depvalues[i] + for k in depkeys: + edepend[k] = metadata[k] if mytype == "ebuild": if "--buildpkgonly" in self.myopts: @@ -1554,8 +1560,7 @@ class depgraph: # A provided package has been specified on the command line. The # package will not be merged and a warning will be displayed. cp = portage.dep_getkey(depstring) - if cp in self._args_atoms and \ - portage.match_to_list(depstring, self._args_atoms[cp]): + if cp in self._args_atoms and depstring in self._args_atoms[cp]: self._pprovided_args.append(arg) if myparent: @@ -2273,7 +2278,11 @@ class depgraph: if available: newlist.append(myslot_atom) mylist = newlist - + + for myatom in mylist: + self._args_atoms.setdefault( + portage.dep_getkey(myatom), []).append(myatom) + missing_atoms = [] for mydep in mylist: try: @@ -2299,6 +2308,31 @@ class depgraph: return 1 + def _get_arg(self, cpv, metadata): + """Return the best match for a given package from the arguments, or + None if there are no matches. This matches virtual arguments against + the PROVIDE metadata. This can raise an InvalidDependString exception + if an error occurs while parsing PROVIDE.""" + cpv_slot = "%s:%s" % (cpv, metadata["SLOT"]) + cp = portage.dep_getkey(cpv) + atoms = self._args_atoms.get(cp) + if atoms: + best_match = portage.best_match_to_list(cpv_slot, atoms) + if best_match: + return best_match + provides = portage.flatten(portage_dep.use_reduce( + portage_dep.paren_reduce(metadata["PROVIDE"]), + uselist=metadata["USE"].split())) + for provide in provides: + provided_cp = portage.dep_getkey(provide) + atoms = self._args_atoms.get(provided_cp) + if atoms: + transformed_atoms = [atom.replace(provided_cp, cp) for atom in atoms] + best_match = portage.best_match_to_list(cpv_slot, transformed_atoms) + if best_match: + return atoms[transformed_atoms.index(best_match)] + return None + def display(self,mylist,verbosity=None): if verbosity is None: verbosity = ("--quiet" in self.myopts and 1 or \ -- 2.26.2