def __init__(self, atom=None, **kwargs):
DependencyArg.__init__(self, **kwargs)
self.atom = atom
+ self.set = (self.atom, )
class PackageArg(DependencyArg):
def __init__(self, package=None, **kwargs):
DependencyArg.__init__(self, **kwargs)
self.package = package
self.atom = "=" + package.cpv
+ self.set = (self.atom, )
class SetArg(DependencyArg):
def __init__(self, set=None, **kwargs):
# contains all atoms from all sets added to the graph, including
# atoms given as arguments
self._set_atoms = InternalPackageSet()
+ self._atom_arg_map = {}
# contains all nodes pulled in by self._set_atoms
self._set_nodes = set()
self.blocker_digraph = digraph()
# TODO: add multiple $ROOT support
if pkg.root != self.target_root:
return None
- arg_atom = self._set_atoms.findAtomForPackage(pkg.cpv, pkg.metadata)
- # TODO: map atom back to DependencyArg instance and return that instead
- return arg_atom
+ atom_arg_map = self._atom_arg_map
+ any_arg = None
+ for atom in self._set_atoms.iterAtomsForPackage(pkg):
+ refs = atom_arg_map[(atom, pkg.root)]
+ for arg in refs:
+ any_arg = arg
+ if isinstance(arg, PackageArg):
+ return arg
+ return any_arg
def select_files(self, myfiles):
"""Given a list of .tbz2s, .ebuilds sets, and deps, create the
if not oneshot:
myfavorites.append(myatom)
self._set_atoms.update(chain(*self._sets.itervalues()))
+ atom_arg_map = self._atom_arg_map
+ for arg in args:
+ for atom in arg.set:
+ atom_key = (atom, myroot)
+ refs = atom_arg_map.get(atom_key)
+ if refs is None:
+ refs = []
+ atom_arg_map[atom_key] = refs
+ if arg not in refs:
+ refs.append(arg)
pprovideddict = pkgsettings.pprovideddict
# Order needs to be preserved since a feature of --nodeps
# is to allow the user to force a specific merge order.
# Distributed under the terms of the GNU General Public License v2
# $Id$
-from portage import flatten
+from portage import cpv_getkey, flatten
from portage.dep import isvalidatom, match_from_list, \
best_match_to_list, dep_getkey, use_reduce, paren_reduce
from portage.exception import InvalidAtom
return atoms[transformed_atoms.index(best_match)]
return None
+ def iterAtomsForPackage(self, pkg):
+ """
+ Find all matching atoms for a given package. This matches virtual
+ arguments against the PROVIDE metadata. This will raise an
+ InvalidDependString exception if PROVIDE is invalid.
+ """
+ cpv_slot_list = ["%s:%s" % (pkg.cpv, pkg.metadata["SLOT"])]
+ cp = cpv_getkey(pkg.cpv)
+ self._load() # make sure the atoms are loaded
+ atoms = self._atommap.get(cp)
+ if atoms:
+ for atom in atoms:
+ if match_from_list(atom, cpv_slot_list):
+ yield atom
+ if not pkg.metadata["PROVIDE"]:
+ return
+ provides = flatten(use_reduce(paren_reduce(pkg.metadata["PROVIDE"]),
+ uselist=pkg.metadata["USE"].split()))
+ for provide in provides:
+ provided_cp = dep_getkey(provide)
+ atoms = self._atommap.get(provided_cp)
+ if atoms:
+ for atom in atoms:
+ if match_from_list(atom.replace(provided_cp, cp),
+ cpv_slot_list):
+ yield atom
+
class EditablePackageSet(PackageSet):
def update(self, atoms):