| # 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 |