From f76b983e95d022d6f377e3efd599dd8efbd30b3d Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Wed, 29 Aug 2012 00:38:12 -0700 Subject: EAPI 5: Profile IUSE injection See bug #176467 and the PMS patch: http://git.overlays.gentoo.org/gitweb/?p=proj/pms.git;a=commit;h=d9040ab3482af5f790368bac5d053bf1cd760ba8 --- pym/_emerge/Package.py | 13 +++-- pym/portage/const.py | 4 +- pym/portage/dbapi/__init__.py | 9 +++- pym/portage/dbapi/_expand_new_virt.py | 10 +++- pym/portage/eapi.py | 6 ++- pym/portage/package/ebuild/config.py | 93 ++++++++++++++++++++++++++++++++-- pym/portage/package/ebuild/doebuild.py | 8 ++- 7 files changed, 125 insertions(+), 18 deletions(-) (limited to 'pym') diff --git a/pym/_emerge/Package.py b/pym/_emerge/Package.py index 0da374af4..ce51a8b06 100644 --- a/pym/_emerge/Package.py +++ b/pym/_emerge/Package.py @@ -64,6 +64,13 @@ class Package(Task): self.slot_abi = self.cpv.slot_abi # sync metadata with validated repo (may be UNKNOWN_REPO) self.metadata['repository'] = self.cpv.repo + + if eapi_attrs.iuse_effective: + implicit_match = self.root_config.settings._iuse_effective_match + else: + implicit_match = self.root_config.settings._iuse_implicit_match + self.iuse = self._iuse(self.metadata["IUSE"].split(), implicit_match) + if (self.iuse.enabled or self.iuse.disabled) and \ not eapi_attrs.iuse_defaults: if not self.installed: @@ -615,7 +622,7 @@ class _PackageMetadataWrapper(_PackageMetadataWrapperBase): __slots__ = ("_pkg",) _wrapped_keys = frozenset( - ["COUNTER", "INHERITED", "IUSE", "USE", "_mtime_"]) + ["COUNTER", "INHERITED", "USE", "_mtime_"]) _use_conditional_keys = frozenset( ['LICENSE', 'PROPERTIES', 'PROVIDE', 'RESTRICT',]) @@ -684,10 +691,6 @@ class _PackageMetadataWrapper(_PackageMetadataWrapperBase): v = frozenset(v.split()) self._pkg.inherited = v - def _set_iuse(self, k, v): - self._pkg.iuse = self._pkg._iuse( - v.split(), self._pkg.root_config.settings._iuse_implicit_match) - def _set_counter(self, k, v): if isinstance(v, basestring): try: diff --git a/pym/portage/const.py b/pym/portage/const.py index c2049f871..6dffc5d06 100644 --- a/pym/portage/const.py +++ b/pym/portage/const.py @@ -79,8 +79,10 @@ OS_HEADERS_PACKAGE_ATOM = "virtual/os-headers" INCREMENTALS = ("USE", "USE_EXPAND", "USE_EXPAND_HIDDEN", "FEATURES", "ACCEPT_KEYWORDS", "CONFIG_PROTECT_MASK", "CONFIG_PROTECT", + "IUSE_IMPLICIT", "PRELINK_PATH", "PRELINK_PATH_MASK", - "PROFILE_ONLY_VARIABLES") + "PROFILE_ONLY_VARIABLES", + "USE_EXPAND_IMPLICIT", "USE_EXPAND_UNPREFIXED") EBUILD_PHASES = ("pretend", "setup", "unpack", "prepare", "configure", "compile", "test", "install", "package", "preinst", "postinst","prerm", "postrm", diff --git a/pym/portage/dbapi/__init__.py b/pym/portage/dbapi/__init__.py index 97b425558..f326e6828 100644 --- a/pym/portage/dbapi/__init__.py +++ b/pym/portage/dbapi/__init__.py @@ -16,6 +16,7 @@ portage.proxy.lazyimport.lazyimport(globals(), from portage import os from portage import auxdbkeys +from portage.eapi import _get_eapi_attrs from portage.exception import InvalidData from portage.localization import _ @@ -181,7 +182,7 @@ class dbapi(object): 2) Check enabled/disabled flag states. """ - aux_keys = ["IUSE", "KEYWORDS", "SLOT", "USE", "repository"] + aux_keys = ["EAPI", "IUSE", "KEYWORDS", "SLOT", "USE", "repository"] for cpv in cpv_iter: try: metadata = dict(zip(aux_keys, @@ -195,7 +196,11 @@ class dbapi(object): yield cpv def _match_use(self, atom, cpv, metadata): - iuse_implicit_match = self.settings._iuse_implicit_match + eapi_attrs = _get_eapi_attrs(metadata["EAPI"]) + if eapi_attrs.iuse_effective: + iuse_implicit_match = self.settings._iuse_effective_match + else: + iuse_implicit_match = self.settings._iuse_implicit_match iuse = frozenset(x.lstrip('+-') for x in metadata["IUSE"].split()) for x in atom.unevaluated_atom.use.required: diff --git a/pym/portage/dbapi/_expand_new_virt.py b/pym/portage/dbapi/_expand_new_virt.py index d379b4c1d..95b2c28cd 100644 --- a/pym/portage/dbapi/_expand_new_virt.py +++ b/pym/portage/dbapi/_expand_new_virt.py @@ -1,8 +1,9 @@ -# Copyright 2011 Gentoo Foundation +# Copyright 2011-2012 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import portage from portage.dep import Atom, _get_useflag_re +from portage.eapi import _get_eapi_attrs def expand_new_virt(vardb, atom): """ @@ -44,6 +45,7 @@ def expand_new_virt(vardb, atom): 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 = [] @@ -54,7 +56,11 @@ def expand_new_virt(vardb, atom): valid_iuse.append(x) valid_iuse = frozenset(valid_iuse) - iuse_implicit_match = vardb.settings._iuse_implicit_match + 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): diff --git a/pym/portage/eapi.py b/pym/portage/eapi.py index b701d02ab..00ce2a512 100644 --- a/pym/portage/eapi.py +++ b/pym/portage/eapi.py @@ -8,6 +8,9 @@ from portage import eapi_is_supported def eapi_has_iuse_defaults(eapi): return eapi != "0" +def eapi_has_iuse_effective(eapi): + return eapi not in ("0", "1", "2", "3", "4", "4-python", "4-slot-abi") + def eapi_has_slot_deps(eapi): return eapi != "0" @@ -72,7 +75,7 @@ def eapi_allows_dots_in_use_flags(eapi): return eapi in ("4-python",) _eapi_attrs = collections.namedtuple('_eapi_attrs', - 'dots_in_PN dots_in_use_flags iuse_defaults ' + 'dots_in_PN dots_in_use_flags iuse_defaults iuse_effective ' 'repo_deps required_use required_use_at_most_one_of slot_abi slot_deps ' 'src_uri_arrows strong_blocks use_deps use_dep_defaults') @@ -98,6 +101,7 @@ def _get_eapi_attrs(eapi): dots_in_PN = (eapi is None or eapi_allows_dots_in_PN(eapi)), dots_in_use_flags = (eapi is None or eapi_allows_dots_in_use_flags(eapi)), iuse_defaults = (eapi is None or eapi_has_iuse_defaults(eapi)), + iuse_effective = (eapi is not None and eapi_has_iuse_effective(eapi)), repo_deps = (eapi is None or eapi_has_repo_deps(eapi)), required_use = (eapi is None or eapi_has_required_use(eapi)), required_use_at_most_one_of = (eapi is None or eapi_has_required_use_at_most_one_of(eapi)), diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py index 871831fb6..6a9ed08b8 100644 --- a/pym/portage/package/ebuild/config.py +++ b/pym/portage/package/ebuild/config.py @@ -32,7 +32,7 @@ from portage.dbapi.porttree import portdbapi from portage.dbapi.vartree import vartree from portage.dep import Atom, isvalidatom, match_from_list, use_reduce, _repo_separator, _slot_separator from portage.eapi import eapi_exports_AA, eapi_exports_merge_type, \ - eapi_supports_prefix, eapi_exports_replace_vars + eapi_supports_prefix, eapi_exports_replace_vars, _get_eapi_attrs from portage.env.loaders import KeyValuePairFileLoader from portage.exception import InvalidDependString, PortageException from portage.localization import _ @@ -215,6 +215,7 @@ class config(object): self.profiles = clone.profiles self.packages = clone.packages self.repositories = clone.repositories + self._iuse_effective = clone._iuse_effective self._iuse_implicit_match = clone._iuse_implicit_match self._non_user_variables = clone._non_user_variables self._env_d_blacklist = clone._env_d_blacklist @@ -793,6 +794,7 @@ class config(object): if bsd_chflags: self.features.add('chflags') + self._iuse_effective = self._calc_iuse_effective() self._iuse_implicit_match = _iuse_implicit_match_cache(self) self._validate_commands() @@ -1251,6 +1253,7 @@ class config(object): pkg_configdict["CATEGORY"] = cat pkg_configdict["PF"] = pf repository = None + eapi = None if mydb: if not hasattr(mydb, "aux_get"): for k in aux_keys: @@ -1277,6 +1280,7 @@ class config(object): # Empty USE means this dbapi instance does not contain # built packages. built_use = None + eapi = pkg_configdict['EAPI'] repository = pkg_configdict.pop("repository", None) if repository is not None: @@ -1295,6 +1299,9 @@ class config(object): elif x.startswith("-"): pkginternaluse.append(x) pkginternaluse = " ".join(pkginternaluse) + + eapi_attrs = _get_eapi_attrs(eapi) + if pkginternaluse != self.configdict["pkginternal"].get("USE", ""): self.configdict["pkginternal"]["USE"] = pkginternaluse has_changed = True @@ -1434,9 +1441,17 @@ class config(object): use = set(self["USE"].split()) if explicit_iuse is None: explicit_iuse = frozenset(x.lstrip("+-") for x in iuse.split()) - iuse_implicit_match = self._iuse_implicit_match - portage_iuse = self._get_implicit_iuse() - portage_iuse.update(explicit_iuse) + + if eapi_attrs.iuse_effective: + iuse_implicit_match = self._iuse_effective_match + portage_iuse = set(self._iuse_effective) + portage_iuse.update(explicit_iuse) + self.configdict["pkg"]["IUSE_EFFECTIVE"] = \ + " ".join(sorted(portage_iuse)) + else: + iuse_implicit_match = self._iuse_implicit_match + portage_iuse = self._get_implicit_iuse() + portage_iuse.update(explicit_iuse) # PORTAGE_IUSE is not always needed so it's lazily evaluated. self.configdict["env"].addLazySingleton( @@ -1501,6 +1516,14 @@ class config(object): self.configdict['env'].addLazySingleton(k, lazy_use_expand.__getitem__, k) + for k in self.get("USE_EXPAND_UNPREFIXED", "").split(): + var_split = self.get(k, '').split() + var_split = [ x for x in var_split if x in use ] + if var_split: + self.configlist[-1][k] = ' '.join(var_split) + elif k in self: + self.configlist[-1][k] = '' + # Filtered for the ebuild environment. Store this in a separate # attribute since we still want to be able to see global USE # settings for things like emerge --info. @@ -1545,9 +1568,42 @@ class config(object): else: container[k] = v + def _iuse_effective_match(self, flag): + return flag in self._iuse_effective + + def _calc_iuse_effective(self): + """ + Beginning with EAPI 5, IUSE_EFFECTIVE is defined by PMS. + """ + iuse_effective = [] + iuse_effective.extend(self.get("IUSE_IMPLICIT", "").split()) + + # USE_EXPAND_IMPLICIT should contain things like ARCH, ELIBC, + # KERNEL, and USERLAND. + use_expand_implicit = frozenset( + self.get("USE_EXPAND_IMPLICIT", "").split()) + + # USE_EXPAND_UNPREFIXED should contain at least ARCH, and + # USE_EXPAND_VALUES_ARCH should contain all valid ARCH flags. + for v in self.get("USE_EXPAND_UNPREFIXED", "").split(): + if v not in use_expand_implicit: + continue + iuse_effective.extend( + self.get("USE_EXPAND_VALUES_" + v, "").split()) + + use_expand = frozenset(self.get("USE_EXPAND", "").split()) + for v in use_expand_implicit: + if v not in use_expand: + continue + lower_v = v.lower() + for x in self.get("USE_EXPAND_VALUES_" + v, "").split(): + iuse_effective.append(lower_v + "_" + x) + + return frozenset(iuse_effective) + def _get_implicit_iuse(self): """ - Some flags are considered to + Prior to EAPI 5, these flags are considered to be implicit members of IUSE: * Flags derived from ARCH * Flags derived from USE_EXPAND_HIDDEN variables @@ -2005,6 +2061,8 @@ class config(object): if v is not None: use_expand_dict[k] = v + use_expand_unprefixed = self.get("USE_EXPAND_UNPREFIXED", "").split() + # In order to best accomodate the long-standing practice of # setting default USE_EXPAND variables in the profile's # make.defaults, we translate these variables into their @@ -2018,6 +2076,12 @@ class config(object): continue use = cfg.get("USE", "") expand_use = [] + + for k in use_expand_unprefixed: + v = cfg.get(k) + if v is not None: + expand_use.extend(v.split()) + for k in use_expand_dict: v = cfg.get(k) if v is None: @@ -2055,6 +2119,17 @@ class config(object): iuse = [x.lstrip("+-") for x in iuse.split()] myflags = set() for curdb in self.uvlist: + + for k in use_expand_unprefixed: + v = curdb.get(k) + if v is None: + continue + for x in v.split(): + if x[:1] == "-": + myflags.discard(x[1:]) + else: + myflags.add(x) + cur_use_expand = [x for x in use_expand if x in curdb] mysplit = curdb.get("USE", "").split() if not mysplit and not cur_use_expand: @@ -2171,6 +2246,14 @@ class config(object): elif k in self: self.configlist[-1][k] = '' + for k in use_expand_unprefixed: + var_split = self.get(k, '').split() + var_split = [ x for x in var_split if x in myflags ] + if var_split: + self.configlist[-1][k] = ' '.join(var_split) + elif k in self: + self.configlist[-1][k] = '' + @property def virts_p(self): warnings.warn("portage config.virts_p attribute " + \ diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py index 6e7e63c40..3ba8ebd6f 100644 --- a/pym/portage/package/ebuild/doebuild.py +++ b/pym/portage/package/ebuild/doebuild.py @@ -1638,8 +1638,12 @@ def _post_src_install_write_metadata(settings): build_info_dir = os.path.join(settings['PORTAGE_BUILDDIR'], 'build-info') - for k in ('IUSE',): - v = settings.get(k) + metadata_keys = ['IUSE'] + if eapi_attrs.iuse_effective: + metadata_keys.append('IUSE_EFFECTIVE') + + for k in metadata_keys: + v = settings.configdict['pkg'].get(k) if v is not None: write_atomic(os.path.join(build_info_dir, k), v + '\n') -- cgit v1.2.3-1-g7c22