blob: 9aa603d1149ff973fe47f05943ec6bf318dd90de [file] [log] [blame]
# Copyright 2011-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from __future__ import unicode_literals
import portage
from portage.dep import Atom, _get_useflag_re
from portage.eapi import _get_eapi_attrs
def expand_new_virt(vardb, atom):
"""
Iterate over the recursively expanded RDEPEND atoms of
a new-style virtual. If atom is not a new-style virtual
or it does not match an installed package then it is
yielded without any expansion.
"""
if not isinstance(atom, Atom):
atom = Atom(atom)
if not atom.cp.startswith("virtual/"):
yield atom
return
traversed = set()
stack = [atom]
while stack:
atom = stack.pop()
if atom.blocker or \
not atom.cp.startswith("virtual/"):
yield atom
continue
matches = vardb.match(atom)
if not (matches and matches[-1].startswith("virtual/")):
yield atom
continue
virt_cpv = matches[-1]
if virt_cpv in traversed:
continue
traversed.add(virt_cpv)
eapi, iuse, rdepend, use = vardb.aux_get(virt_cpv,
["EAPI", "IUSE", "RDEPEND", "USE"])
if not portage.eapi_is_supported(eapi):
yield atom
continue
eapi_attrs = _get_eapi_attrs(eapi)
# Validate IUSE and IUSE, for early detection of vardb corruption.
useflag_re = _get_useflag_re(eapi)
valid_iuse = []
for x in iuse.split():
if x[:1] in ("+", "-"):
x = x[1:]
if useflag_re.match(x) is not None:
valid_iuse.append(x)
valid_iuse = frozenset(valid_iuse)
if eapi_attrs.iuse_effective:
iuse_implicit_match = vardb.settings._iuse_effective_match
else:
iuse_implicit_match = vardb.settings._iuse_implicit_match
valid_use = []
for x in use.split():
if x in valid_iuse or iuse_implicit_match(x):
valid_use.append(x)
valid_use = frozenset(valid_use)
success, atoms = portage.dep_check(rdepend,
None, vardb.settings, myuse=valid_use,
myroot=vardb.settings['EROOT'],
trees={vardb.settings['EROOT']:{"porttree":vardb.vartree,
"vartree":vardb.vartree}})
if success:
stack.extend(atoms)
else:
yield atom