# 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:
self.orderedkeys=[]
self.outdatedpackages=[]
self._args_atoms = {}
+ self._args_nodes = set()
self.blocker_digraph = digraph()
self.blocker_parents = {}
self._unresolved_blocker_parents = {}
# 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":
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(
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"
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)
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.
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:
# 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:
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:
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 \