1 # Copyright 2010-2012 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
5 'autouse', 'best_from_dict', 'check_config_instance', 'config',
9 from itertools import chain
18 from _emerge.Package import Package
20 portage.proxy.lazyimport.lazyimport(globals(),
21 'portage.data:portage_gid',
22 'portage.package.ebuild.doebuild:_phase_func_map',
24 from portage import bsd_chflags, \
25 load_mod, os, selinux, _unicode_decode
26 from portage.const import CACHE_PATH, \
27 DEPCACHE_PATH, INCREMENTALS, MAKE_CONF_FILE, \
29 PRIVATE_PATH, PROFILE_PATH, USER_CONFIG_PATH, \
31 from portage.dbapi import dbapi
32 from portage.dbapi.porttree import portdbapi
33 from portage.dbapi.vartree import vartree
34 from portage.dep import Atom, isvalidatom, match_from_list, use_reduce, _repo_separator, _slot_separator
35 from portage.eapi import eapi_exports_AA, eapi_exports_merge_type, \
36 eapi_supports_prefix, eapi_exports_replace_vars, _get_eapi_attrs
37 from portage.env.loaders import KeyValuePairFileLoader
38 from portage.exception import InvalidDependString, PortageException
39 from portage.localization import _
40 from portage.output import colorize
41 from portage.process import fakeroot_capable, sandbox_capable
42 from portage.repository.config import load_repository_config
43 from portage.util import ensure_dirs, getconfig, grabdict, \
44 grabdict_package, grabfile, grabfile_package, LazyItemsDict, \
45 normalize_path, shlex_split, stack_dictlist, stack_dicts, stack_lists, \
46 writemsg, writemsg_level, _eapi_cache
47 from portage.versions import catpkgsplit, catsplit, cpv_getkey, _pkg_str
49 from portage.package.ebuild._config import special_env_vars
50 from portage.package.ebuild._config.env_var_validation import validate_cmd_var
51 from portage.package.ebuild._config.features_set import features_set
52 from portage.package.ebuild._config.KeywordsManager import KeywordsManager
53 from portage.package.ebuild._config.LicenseManager import LicenseManager
54 from portage.package.ebuild._config.UseManager import UseManager
55 from portage.package.ebuild._config.LocationsManager import LocationsManager
56 from portage.package.ebuild._config.MaskManager import MaskManager
57 from portage.package.ebuild._config.VirtualsManager import VirtualsManager
58 from portage.package.ebuild._config.helper import ordered_by_atom_specificity, prune_incremental
60 if sys.hexversion >= 0x3000000:
63 _feature_flags = frozenset(["test"])
65 def autouse(myvartree, use_cache=1, mysettings=None):
66 warnings.warn("portage.autouse() is deprecated",
67 DeprecationWarning, stacklevel=2)
70 def check_config_instance(test):
71 if not isinstance(test, config):
72 raise TypeError("Invalid type for config object: %s (should be %s)" % (test.__class__, config))
74 def best_from_dict(key, top_dict, key_order, EmptyOnError=1, FullCopy=1, AllowEmpty=1):
76 if x in top_dict and key in top_dict[x]:
78 return copy.deepcopy(top_dict[x][key])
80 return top_dict[x][key]
84 raise KeyError("Key not found in list; '%s'" % key)
86 def _lazy_iuse_regex(iuse_implicit):
88 The PORTAGE_IUSE value is lazily evaluated since re.escape() is slow
89 and the value is only used when an ebuild phase needs to be executed
90 (it's used only to generate QA notices).
92 # Escape anything except ".*" which is supposed to pass through from
93 # _get_implicit_iuse().
94 regex = sorted(re.escape(x) for x in iuse_implicit)
95 regex = "^(%s)$" % "|".join(regex)
96 regex = regex.replace("\\.\\*", ".*")
99 class _iuse_implicit_match_cache(object):
101 def __init__(self, settings):
102 self._iuse_implicit_re = re.compile("^(%s)$" % \
103 "|".join(settings._get_implicit_iuse()))
106 def __call__(self, flag):
108 Returns True if the flag is matched, False otherwise.
111 return self._cache[flag]
113 m = self._iuse_implicit_re.match(flag) is not None
114 self._cache[flag] = m
117 class config(object):
119 This class encompasses the main portage configuration. Data is pulled from
120 ROOT/PORTDIR/profiles/, from ROOT/etc/make.profile incrementally through all
121 parent profiles as well as from ROOT/PORTAGE_CONFIGROOT/* for user specified
124 Generally if you need data like USE flags, FEATURES, environment variables,
125 virtuals ...etc you look in here.
128 _constant_keys = frozenset(['PORTAGE_BIN_PATH', 'PORTAGE_GID',
131 _setcpv_aux_keys = ('DEFINED_PHASES', 'DEPEND', 'EAPI',
132 'INHERITED', 'IUSE', 'REQUIRED_USE', 'KEYWORDS', 'LICENSE', 'PDEPEND',
133 'PROPERTIES', 'PROVIDE', 'RDEPEND', 'SLOT',
134 'repository', 'RESTRICT', 'LICENSE',)
137 "cache.metadata_overlay.database" : "portage.cache.flat_hash.database",
138 "portage.cache.metadata_overlay.database" : "portage.cache.flat_hash.database",
141 _case_insensitive_vars = special_env_vars.case_insensitive_vars
142 _default_globals = special_env_vars.default_globals
143 _env_blacklist = special_env_vars.env_blacklist
144 _environ_filter = special_env_vars.environ_filter
145 _environ_whitelist = special_env_vars.environ_whitelist
146 _environ_whitelist_re = special_env_vars.environ_whitelist_re
147 _global_only_vars = special_env_vars.global_only_vars
149 def __init__(self, clone=None, mycpv=None, config_profile_path=None,
150 config_incrementals=None, config_root=None, target_root=None,
151 eprefix=None, local_config=True, env=None,
152 _unmatched_removal=False):
154 @param clone: If provided, init will use deepcopy to copy by value the instance.
155 @type clone: Instance of config class.
156 @param mycpv: CPV to load up (see setcpv), this is the same as calling init with mycpv=None
157 and then calling instance.setcpv(mycpv).
159 @param config_profile_path: Configurable path to the profile (usually PROFILE_PATH from portage.const)
160 @type config_profile_path: String
161 @param config_incrementals: List of incremental variables
162 (defaults to portage.const.INCREMENTALS)
163 @type config_incrementals: List
164 @param config_root: path to read local config from (defaults to "/", see PORTAGE_CONFIGROOT)
165 @type config_root: String
166 @param target_root: __init__ override of $ROOT env variable.
167 @type target_root: String
168 @param eprefix: set the EPREFIX variable (default is portage.const.EPREFIX)
169 @type eprefix: String
170 @param local_config: Enables loading of local config (/etc/portage); used most by repoman to
171 ignore local config (keywording and unmasking)
172 @type local_config: Boolean
173 @param env: The calling environment which is used to override settings.
174 Defaults to os.environ if unspecified.
176 @param _unmatched_removal: Enabled by repoman when the
177 --unmatched-removal option is given.
178 @type _unmatched_removal: Boolean
181 # This is important when config is reloaded after emerge --sync.
184 # When initializing the global portage.settings instance, avoid
185 # raising exceptions whenever possible since exceptions thrown
186 # from 'import portage' or 'import portage.exceptions' statements
187 # can practically render the api unusable for api consumers.
188 tolerant = hasattr(portage, '_initializing_globals')
189 self._tolerant = tolerant
190 self._unmatched_removal = _unmatched_removal
194 self._setcpv_args_hash = None
197 self.modifiedkeys = []
199 self._accept_chost_re = None
200 self._accept_properties = None
201 self._features_overrides = []
202 self._make_defaults = None
204 # _unknown_features records unknown features that
205 # have triggered warning messages, and ensures that
206 # the same warning isn't shown twice.
207 self._unknown_features = set()
209 self.local_config = local_config
212 # For immutable attributes, use shallow copy for
213 # speed and memory conservation.
214 self._tolerant = clone._tolerant
215 self._unmatched_removal = clone._unmatched_removal
216 self.categories = clone.categories
217 self.depcachedir = clone.depcachedir
218 self.incrementals = clone.incrementals
219 self.module_priority = clone.module_priority
220 self.profile_path = clone.profile_path
221 self.profiles = clone.profiles
222 self.packages = clone.packages
223 self.repositories = clone.repositories
224 self._iuse_effective = clone._iuse_effective
225 self._iuse_implicit_match = clone._iuse_implicit_match
226 self._non_user_variables = clone._non_user_variables
227 self._env_d_blacklist = clone._env_d_blacklist
228 self._repo_make_defaults = clone._repo_make_defaults
229 self.usemask = clone.usemask
230 self.useforce = clone.useforce
231 self.puse = clone.puse
232 self.user_profile_dir = clone.user_profile_dir
233 self.local_config = clone.local_config
234 self.make_defaults_use = clone.make_defaults_use
235 self.mycpv = clone.mycpv
236 self._setcpv_args_hash = clone._setcpv_args_hash
238 # immutable attributes (internal policy ensures lack of mutation)
239 self._locations_manager = clone._locations_manager
240 self._use_manager = clone._use_manager
241 # force instantiation of lazy immutable objects when cloning, so
242 # that they're not instantiated more than once
243 self._keywords_manager_obj = clone._keywords_manager
244 self._mask_manager_obj = clone._mask_manager
246 # shared mutable attributes
247 self._unknown_features = clone._unknown_features
249 self.modules = copy.deepcopy(clone.modules)
250 self._penv = copy.deepcopy(clone._penv)
252 self.configdict = copy.deepcopy(clone.configdict)
254 self.configdict['env.d'],
255 self.configdict['repo'],
256 self.configdict['pkginternal'],
257 self.configdict['globals'],
258 self.configdict['defaults'],
259 self.configdict['conf'],
260 self.configdict['pkg'],
261 self.configdict['env'],
263 self.lookuplist = self.configlist[:]
264 self.lookuplist.reverse()
265 self._use_expand_dict = copy.deepcopy(clone._use_expand_dict)
266 self.backupenv = self.configdict["backupenv"]
267 self.prevmaskdict = copy.deepcopy(clone.prevmaskdict)
268 self.pprovideddict = copy.deepcopy(clone.pprovideddict)
269 self.features = features_set(self)
270 self.features._features = copy.deepcopy(clone.features._features)
271 self._features_overrides = copy.deepcopy(clone._features_overrides)
273 #Strictly speaking _license_manager is not immutable. Users need to ensure that
274 #extract_global_changes() is called right after __init__ (if at all).
275 #It also has the mutable member _undef_lic_groups. It is used to track
276 #undefined license groups, to not display an error message for the same
277 #group again and again. Because of this, it's useful to share it between
278 #all LicenseManager instances.
279 self._license_manager = clone._license_manager
281 # force instantiation of lazy objects when cloning, so
282 # that they're not instantiated more than once
283 self._virtuals_manager_obj = copy.deepcopy(clone._virtuals_manager)
285 self._accept_properties = copy.deepcopy(clone._accept_properties)
286 self._ppropertiesdict = copy.deepcopy(clone._ppropertiesdict)
287 self._penvdict = copy.deepcopy(clone._penvdict)
288 self._expand_map = copy.deepcopy(clone._expand_map)
291 # lazily instantiated objects
292 self._keywords_manager_obj = None
293 self._mask_manager_obj = None
294 self._virtuals_manager_obj = None
296 locations_manager = LocationsManager(config_root=config_root,
297 config_profile_path=config_profile_path, eprefix=eprefix,
298 local_config=local_config, target_root=target_root)
299 self._locations_manager = locations_manager
301 eprefix = locations_manager.eprefix
302 config_root = locations_manager.config_root
303 abs_user_config = locations_manager.abs_user_config
305 make_conf = getconfig(
306 os.path.join(config_root, 'etc', 'make.conf'),
307 tolerant=tolerant, allow_sourcing=True) or {}
309 make_conf.update(getconfig(
310 os.path.join(config_root, MAKE_CONF_FILE),
311 tolerant=tolerant, allow_sourcing=True,
312 expand=make_conf) or {})
314 # Allow ROOT setting to come from make.conf if it's not overridden
315 # by the constructor argument (from the calling environment).
316 locations_manager.set_root_override(make_conf.get("ROOT"))
317 target_root = locations_manager.target_root
318 eroot = locations_manager.eroot
319 self.global_config_path = locations_manager.global_config_path
321 # The expand_map is used for variable substitution
322 # in getconfig() calls, and the getconfig() calls
323 # update expand_map with the value of each variable
324 # assignment that occurs. Variable substitution occurs
325 # in the following order, which corresponds to the
326 # order of appearance in self.lookuplist:
333 # Notably absent is "env", since we want to avoid any
334 # interaction with the calling environment that might
335 # lead to unexpected results.
337 env_d = getconfig(os.path.join(eroot, "etc", "profile.env"),
338 tolerant=tolerant, expand=False) or {}
339 expand_map = env_d.copy()
340 self._expand_map = expand_map
342 # Allow make.globals to set default paths relative to ${EPREFIX}.
343 expand_map["EPREFIX"] = eprefix
345 make_globals = getconfig(os.path.join(
346 self.global_config_path, 'make.globals'),
347 tolerant=tolerant, expand=expand_map)
348 if make_globals is None:
351 for k, v in self._default_globals.items():
352 make_globals.setdefault(k, v)
354 if config_incrementals is None:
355 self.incrementals = INCREMENTALS
357 self.incrementals = config_incrementals
358 if not isinstance(self.incrementals, frozenset):
359 self.incrementals = frozenset(self.incrementals)
361 self.module_priority = ("user", "default")
363 modules_file = os.path.join(config_root, MODULES_FILE_PATH)
364 modules_loader = KeyValuePairFileLoader(modules_file, None, None)
365 modules_dict, modules_errors = modules_loader.load()
366 self.modules["user"] = modules_dict
367 if self.modules["user"] is None:
368 self.modules["user"] = {}
370 self.modules["user"].get("portdbapi.auxdbmodule")
371 if user_auxdbmodule is not None and \
372 user_auxdbmodule in self._module_aliases:
373 warnings.warn("'%s' is deprecated: %s" %
374 (user_auxdbmodule, modules_file))
376 self.modules["default"] = {
377 "portdbapi.auxdbmodule": "portage.cache.flat_hash.database",
382 # back up our incremental variables:
384 self._use_expand_dict = {}
385 # configlist will contain: [ env.d, globals, defaults, conf, pkg, backupenv, env ]
386 self.configlist.append({})
387 self.configdict["env.d"] = self.configlist[-1]
389 self.configlist.append({})
390 self.configdict["repo"] = self.configlist[-1]
392 self.configlist.append({})
393 self.configdict["pkginternal"] = self.configlist[-1]
395 # env_d will be None if profile.env doesn't exist.
397 self.configdict["env.d"].update(env_d)
399 # backupenv is used for calculating incremental variables.
403 # Avoid potential UnicodeDecodeError exceptions later.
404 env_unicode = dict((_unicode_decode(k), _unicode_decode(v))
405 for k, v in env.items())
407 self.backupenv = env_unicode
410 # Remove duplicate values so they don't override updated
411 # profile.env values later (profile.env is reloaded in each
412 # call to self.regenerate).
413 for k, v in env_d.items():
415 if self.backupenv[k] == v:
416 del self.backupenv[k]
421 self.configdict["env"] = LazyItemsDict(self.backupenv)
423 self.configlist.append(make_globals)
424 self.configdict["globals"]=self.configlist[-1]
426 self.make_defaults_use = []
428 #Loading Repositories
429 self["PORTAGE_CONFIGROOT"] = config_root
430 self["ROOT"] = target_root
431 self["EPREFIX"] = eprefix
432 self["EROOT"] = eroot
436 for confs in [make_globals, make_conf, self.configdict["env"]]:
437 v = confs.get("PORTDIR")
440 known_repos.append(v)
441 v = confs.get("PORTDIR_OVERLAY")
444 known_repos.extend(shlex_split(v))
445 known_repos = frozenset(known_repos)
446 self["PORTDIR"] = portdir
447 self["PORTDIR_OVERLAY"] = portdir_overlay
448 self.lookuplist = [self.configdict["env"]]
449 self.repositories = load_repository_config(self)
451 locations_manager.load_profiles(self.repositories, known_repos)
453 profiles_complex = locations_manager.profiles_complex
454 self.profiles = locations_manager.profiles
455 self.profile_path = locations_manager.profile_path
456 self.user_profile_dir = locations_manager.user_profile_dir
458 packages_list = [grabfile_package(os.path.join(x, "packages"),
459 verify_eapi=True) for x in self.profiles]
460 self.packages = tuple(stack_lists(packages_list, incremental=1))
464 for x in self.packages:
465 # Negative atoms are filtered by the above stack_lists() call.
466 if not isinstance(x, Atom):
467 x = Atom(x.lstrip('*'))
468 self.prevmaskdict.setdefault(x.cp, []).append(x)
473 mygcfg_dlists = [getconfig(os.path.join(x, "make.defaults"),
474 tolerant=tolerant, expand=expand_map)
475 for x in self.profiles]
476 self._make_defaults = mygcfg_dlists
477 mygcfg = stack_dicts(mygcfg_dlists,
478 incrementals=self.incrementals)
481 self.configlist.append(mygcfg)
482 self.configdict["defaults"]=self.configlist[-1]
485 os.path.join(config_root, 'etc', 'make.conf'),
486 tolerant=tolerant, allow_sourcing=True,
487 expand=expand_map) or {}
489 mygcfg.update(getconfig(
490 os.path.join(config_root, MAKE_CONF_FILE),
491 tolerant=tolerant, allow_sourcing=True,
492 expand=expand_map) or {})
494 # Don't allow the user to override certain variables in make.conf
495 profile_only_variables = self.configdict["defaults"].get(
496 "PROFILE_ONLY_VARIABLES", "").split()
497 profile_only_variables = stack_lists([profile_only_variables])
498 non_user_variables = set()
499 non_user_variables.update(profile_only_variables)
500 non_user_variables.update(self._env_blacklist)
501 non_user_variables.update(self._global_only_vars)
502 non_user_variables = frozenset(non_user_variables)
503 self._non_user_variables = non_user_variables
505 self._env_d_blacklist = frozenset(chain(
506 profile_only_variables,
509 env_d = self.configdict["env.d"]
510 for k in self._env_d_blacklist:
513 for k in profile_only_variables:
516 self.configlist.append(mygcfg)
517 self.configdict["conf"]=self.configlist[-1]
519 self.configlist.append(LazyItemsDict())
520 self.configdict["pkg"]=self.configlist[-1]
522 self.configdict["backupenv"] = self.backupenv
524 # Don't allow the user to override certain variables in the env
525 for k in profile_only_variables:
526 self.backupenv.pop(k, None)
528 self.configlist.append(self.configdict["env"])
530 # make lookuplist for loading package.*
531 self.lookuplist=self.configlist[:]
532 self.lookuplist.reverse()
534 # Blacklist vars that could interfere with portage internals.
535 for blacklisted in self._env_blacklist:
536 for cfg in self.lookuplist:
537 cfg.pop(blacklisted, None)
538 self.backupenv.pop(blacklisted, None)
541 self["PORTAGE_CONFIGROOT"] = config_root
542 self.backup_changes("PORTAGE_CONFIGROOT")
543 self["ROOT"] = target_root
544 self.backup_changes("ROOT")
546 # The PORTAGE_OVERRIDE_EPREFIX variable propagates the EPREFIX
547 # of this config instance to any portage commands or API
548 # consumers running in subprocesses.
549 self["EPREFIX"] = eprefix
550 self.backup_changes("EPREFIX")
551 self["PORTAGE_OVERRIDE_EPREFIX"] = eprefix
552 self.backup_changes("PORTAGE_OVERRIDE_EPREFIX")
553 self["EROOT"] = eroot
554 self.backup_changes("EROOT")
556 self._ppropertiesdict = portage.dep.ExtendedAtomDict(dict)
557 self._penvdict = portage.dep.ExtendedAtomDict(dict)
559 #filling PORTDIR and PORTDIR_OVERLAY variable for compatibility
560 main_repo = self.repositories.mainRepo()
561 if main_repo is not None:
562 self["PORTDIR"] = main_repo.user_location
563 self.backup_changes("PORTDIR")
565 # repoman controls PORTDIR_OVERLAY via the environment, so no
566 # special cases are needed here.
567 portdir_overlay = list(self.repositories.repoUserLocationList())
568 if portdir_overlay and portdir_overlay[0] == self["PORTDIR"]:
569 portdir_overlay = portdir_overlay[1:]
573 shell_quote_re = re.compile(r"[\s\\\"'$`]")
574 for ov in portdir_overlay:
575 ov = normalize_path(ov)
576 if os.path.isdir(ov):
577 if shell_quote_re.search(ov) is not None:
578 ov = portage._shell_quote(ov)
581 writemsg(_("!!! Invalid PORTDIR_OVERLAY"
582 " (not a dir): '%s'\n") % ov, noiselevel=-1)
584 self["PORTDIR_OVERLAY"] = " ".join(new_ov)
585 self.backup_changes("PORTDIR_OVERLAY")
587 locations_manager.set_port_dirs(self["PORTDIR"], self["PORTDIR_OVERLAY"])
589 self._repo_make_defaults = {}
590 for repo in self.repositories.repos_with_profiles():
591 d = getconfig(os.path.join(repo.location, "profiles", "make.defaults"),
592 tolerant=tolerant, expand=self.configdict["globals"].copy()) or {}
594 for k in chain(self._env_blacklist,
595 profile_only_variables, self._global_only_vars):
597 self._repo_make_defaults[repo.name] = d
599 #Read all USE related files from profiles and optionally from user config.
600 self._use_manager = UseManager(self.repositories, profiles_complex, abs_user_config, user_config=local_config)
601 #Initialize all USE related variables we track ourselves.
602 self.usemask = self._use_manager.getUseMask()
603 self.useforce = self._use_manager.getUseForce()
604 self.configdict["conf"]["USE"] = \
605 self._use_manager.extract_global_USE_changes( \
606 self.configdict["conf"].get("USE", ""))
608 #Read license_groups and optionally license_groups and package.license from user config
609 self._license_manager = LicenseManager(locations_manager.profile_locations, \
610 abs_user_config, user_config=local_config)
611 #Extract '*/*' entries from package.license
612 self.configdict["conf"]["ACCEPT_LICENSE"] = \
613 self._license_manager.extract_global_changes( \
614 self.configdict["conf"].get("ACCEPT_LICENSE", ""))
618 propdict = grabdict_package(os.path.join(
619 abs_user_config, "package.properties"), recursive=1, allow_wildcard=True, \
620 allow_repo=True, verify_eapi=False)
621 v = propdict.pop("*/*", None)
623 if "ACCEPT_PROPERTIES" in self.configdict["conf"]:
624 self.configdict["conf"]["ACCEPT_PROPERTIES"] += " " + " ".join(v)
626 self.configdict["conf"]["ACCEPT_PROPERTIES"] = " ".join(v)
627 for k, v in propdict.items():
628 self._ppropertiesdict.setdefault(k.cp, {})[k] = v
631 penvdict = grabdict_package(os.path.join(
632 abs_user_config, "package.env"), recursive=1, allow_wildcard=True, \
633 allow_repo=True, verify_eapi=False)
634 v = penvdict.pop("*/*", None)
636 global_wildcard_conf = {}
637 self._grab_pkg_env(v, global_wildcard_conf)
638 incrementals = self.incrementals
639 conf_configdict = self.configdict["conf"]
640 for k, v in global_wildcard_conf.items():
641 if k in incrementals:
642 if k in conf_configdict:
643 conf_configdict[k] = \
644 conf_configdict[k] + " " + v
646 conf_configdict[k] = v
648 conf_configdict[k] = v
651 for k, v in penvdict.items():
652 self._penvdict.setdefault(k.cp, {})[k] = v
654 #getting categories from an external file now
655 self.categories = [grabfile(os.path.join(x, "categories")) \
656 for x in locations_manager.profile_and_user_locations]
657 category_re = dbapi._category_re
658 # categories used to be a tuple, but now we use a frozenset
659 # for hashed category validation in pordbapi.cp_list()
660 self.categories = frozenset(
661 x for x in stack_lists(self.categories, incremental=1)
662 if category_re.match(x) is not None)
664 archlist = [grabfile(os.path.join(x, "arch.list")) \
665 for x in locations_manager.profile_and_user_locations]
666 archlist = stack_lists(archlist, incremental=1)
667 self.configdict["conf"]["PORTAGE_ARCHLIST"] = " ".join(archlist)
669 pkgprovidedlines = [grabfile(
670 os.path.join(x.location, "package.provided"),
671 recursive=x.portage1_directories)
672 for x in profiles_complex]
673 pkgprovidedlines = stack_lists(pkgprovidedlines, incremental=1)
674 has_invalid_data = False
675 for x in range(len(pkgprovidedlines)-1, -1, -1):
676 myline = pkgprovidedlines[x]
677 if not isvalidatom("=" + myline):
678 writemsg(_("Invalid package name in package.provided: %s\n") % \
679 myline, noiselevel=-1)
680 has_invalid_data = True
681 del pkgprovidedlines[x]
683 cpvr = catpkgsplit(pkgprovidedlines[x])
684 if not cpvr or cpvr[0] == "null":
685 writemsg(_("Invalid package name in package.provided: ")+pkgprovidedlines[x]+"\n",
687 has_invalid_data = True
688 del pkgprovidedlines[x]
690 if cpvr[0] == "virtual":
691 writemsg(_("Virtual package in package.provided: %s\n") % \
692 myline, noiselevel=-1)
693 has_invalid_data = True
694 del pkgprovidedlines[x]
697 writemsg(_("See portage(5) for correct package.provided usage.\n"),
699 self.pprovideddict = {}
700 for x in pkgprovidedlines:
701 x_split = catpkgsplit(x)
704 mycatpkg = cpv_getkey(x)
705 if mycatpkg in self.pprovideddict:
706 self.pprovideddict[mycatpkg].append(x)
708 self.pprovideddict[mycatpkg]=[x]
710 # reasonable defaults; this is important as without USE_ORDER,
711 # USE will always be "" (nothing set)!
712 if "USE_ORDER" not in self:
713 self.backupenv["USE_ORDER"] = "env:pkg:conf:defaults:pkginternal:repo:env.d"
715 self.depcachedir = DEPCACHE_PATH
717 # See comments about make.globals and EPREFIX
718 # above. DEPCACHE_PATH is similar.
719 if target_root == "/":
721 self.depcachedir = os.path.join(eprefix,
722 DEPCACHE_PATH.lstrip(os.sep))
725 # For now, just assume DEPCACHE_PATH is relative
727 # TODO: Pass in more info to the constructor,
728 # so we know the host system configuration.
729 self.depcachedir = os.path.join(eprefix,
730 DEPCACHE_PATH.lstrip(os.sep))
732 if self.get("PORTAGE_DEPCACHEDIR", None):
733 self.depcachedir = self["PORTAGE_DEPCACHEDIR"]
734 self["PORTAGE_DEPCACHEDIR"] = self.depcachedir
735 self.backup_changes("PORTAGE_DEPCACHEDIR")
737 if "CBUILD" not in self and "CHOST" in self:
738 self["CBUILD"] = self["CHOST"]
739 self.backup_changes("CBUILD")
741 if "USERLAND" not in self:
742 # Set default USERLAND so that our test cases can assume that
743 # it's always set. This allows isolated-functions.sh to avoid
744 # calling uname -s when sourced.
745 system = platform.system()
746 if system is not None and \
747 (system.endswith("BSD") or system == "DragonFly"):
748 self["USERLAND"] = "BSD"
750 self["USERLAND"] = "GNU"
751 self.backup_changes("USERLAND")
754 "PORTAGE_INST_GID": "0",
755 "PORTAGE_INST_UID": "0",
759 # For prefix environments, default to the UID and GID of
760 # the top-level EROOT directory.
762 eroot_st = os.stat(eroot)
766 default_inst_ids["PORTAGE_INST_GID"] = str(eroot_st.st_gid)
767 default_inst_ids["PORTAGE_INST_UID"] = str(eroot_st.st_uid)
769 if "PORTAGE_USERNAME" not in self:
771 pwd_struct = pwd.getpwuid(eroot_st.st_uid)
775 self["PORTAGE_USERNAME"] = pwd_struct.pw_name
776 self.backup_changes("PORTAGE_USERNAME")
778 if "PORTAGE_GRPNAME" not in self:
780 grp_struct = grp.getgrgid(eroot_st.st_gid)
784 self["PORTAGE_GRPNAME"] = grp_struct.gr_name
785 self.backup_changes("PORTAGE_GRPNAME")
787 for var, default_val in default_inst_ids.items():
789 self[var] = str(int(self.get(var, default_val)))
791 writemsg(_("!!! %s='%s' is not a valid integer. "
792 "Falling back to %s.\n") % (var, self[var], default_val),
794 self[var] = default_val
795 self.backup_changes(var)
797 # initialize self.features
801 self.features.add('chflags')
803 self._iuse_effective = self._calc_iuse_effective()
804 self._iuse_implicit_match = _iuse_implicit_match_cache(self)
806 self._validate_commands()
808 for k in self._case_insensitive_vars:
810 self[k] = self[k].lower()
811 self.backup_changes(k)
813 if main_repo is not None and not main_repo.sync:
814 main_repo_sync = self.get("SYNC")
816 main_repo.sync = main_repo_sync
818 # The first constructed config object initializes these modules,
819 # and subsequent calls to the _init() functions have no effect.
820 portage.output._init(config_root=self['PORTAGE_CONFIGROOT'])
821 portage.data._init(self)
828 warnings.warn("portage.config.mygcfg is deprecated", stacklevel=3)
831 def _validate_commands(self):
832 for k in special_env_vars.validate_commands:
835 valid, v_split = validate_cmd_var(v)
839 writemsg_level(_("%s setting is invalid: '%s'\n") % \
840 (k, v), level=logging.ERROR, noiselevel=-1)
842 # before deleting the invalid setting, backup
843 # the default value if available
844 v = self.configdict['globals'].get(k)
846 default_valid, v_split = validate_cmd_var(v)
847 if not default_valid:
850 _("%s setting from make.globals" + \
851 " is invalid: '%s'\n") % \
852 (k, v), level=logging.ERROR, noiselevel=-1)
853 # make.globals seems corrupt, so try for
854 # a hardcoded default instead
855 v = self._default_globals.get(k)
857 # delete all settings for this key,
858 # including the invalid one
860 self.backupenv.pop(k, None)
862 # restore validated default
863 self.configdict['globals'][k] = v
865 def _init_dirs(self):
867 Create a few directories that are critical to portage operation
869 if not os.access(self["EROOT"], os.W_OK):
872 # gid, mode, mask, preserve_perms
874 "tmp" : ( -1, 0o1777, 0, True),
875 "var/tmp" : ( -1, 0o1777, 0, True),
876 PRIVATE_PATH : (portage_gid, 0o2750, 0o2, False),
877 CACHE_PATH : (portage_gid, 0o755, 0o2, False)
880 for mypath, (gid, mode, modemask, preserve_perms) \
881 in dir_mode_map.items():
882 mydir = os.path.join(self["EROOT"], mypath)
883 if preserve_perms and os.path.isdir(mydir):
884 # Only adjust permissions on some directories if
885 # they don't exist yet. This gives freedom to the
886 # user to adjust permissions to suit their taste.
889 ensure_dirs(mydir, gid=gid, mode=mode, mask=modemask)
890 except PortageException as e:
891 writemsg(_("!!! Directory initialization failed: '%s'\n") % mydir,
893 writemsg("!!! %s\n" % str(e),
897 def _keywords_manager(self):
898 if self._keywords_manager_obj is None:
899 self._keywords_manager_obj = KeywordsManager(
900 self._locations_manager.profiles_complex,
901 self._locations_manager.abs_user_config,
903 global_accept_keywords=self.configdict["defaults"].get("ACCEPT_KEYWORDS", ""))
904 return self._keywords_manager_obj
907 def _mask_manager(self):
908 if self._mask_manager_obj is None:
909 self._mask_manager_obj = MaskManager(self.repositories,
910 self._locations_manager.profiles_complex,
911 self._locations_manager.abs_user_config,
912 user_config=self.local_config,
913 strict_umatched_removal=self._unmatched_removal)
914 return self._mask_manager_obj
917 def _virtuals_manager(self):
918 if self._virtuals_manager_obj is None:
919 self._virtuals_manager_obj = VirtualsManager(self.profiles)
920 return self._virtuals_manager_obj
923 def pkeywordsdict(self):
924 result = self._keywords_manager.pkeywordsdict.copy()
925 for k, v in result.items():
931 return self._mask_manager._pmaskdict.copy()
934 def punmaskdict(self):
935 return self._mask_manager._punmaskdict.copy()
937 def expandLicenseTokens(self, tokens):
938 """ Take a token from ACCEPT_LICENSE or package.license and expand it
939 if it's a group token (indicated by @) or just return it if it's not a
940 group. If a group is negated then negate all group elements."""
941 return self._license_manager.expandLicenseTokens(tokens)
944 """Validate miscellaneous settings and display warnings if necessary.
945 (This code was previously in the global scope of portage.py)"""
947 groups = self["ACCEPT_KEYWORDS"].split()
948 archlist = self.archlist()
950 writemsg(_("--- 'profiles/arch.list' is empty or "
951 "not available. Empty portage tree?\n"), noiselevel=1)
954 if group not in archlist and \
955 not (group.startswith("-") and group[1:] in archlist) and \
956 group not in ("*", "~*", "**"):
957 writemsg(_("!!! INVALID ACCEPT_KEYWORDS: %s\n") % str(group),
960 profile_broken = not self.profile_path or \
961 not os.path.exists(os.path.join(self.profile_path, "parent")) and \
962 os.path.exists(os.path.join(self["PORTDIR"], "profiles"))
965 abs_profile_path = None
966 for x in (PROFILE_PATH, 'etc/make.profile'):
967 x = os.path.join(self["PORTAGE_CONFIGROOT"], x)
976 if abs_profile_path is None:
977 abs_profile_path = os.path.join(self["PORTAGE_CONFIGROOT"],
980 writemsg(_("\n\n!!! %s is not a symlink and will probably prevent most merges.\n") % abs_profile_path,
982 writemsg(_("!!! It should point into a profile within %s/profiles/\n") % self["PORTDIR"])
983 writemsg(_("!!! (You can safely ignore this message when syncing. It's harmless.)\n\n\n"))
985 abs_user_virtuals = os.path.join(self["PORTAGE_CONFIGROOT"],
987 if os.path.exists(abs_user_virtuals):
988 writemsg("\n!!! /etc/portage/virtuals is deprecated in favor of\n")
989 writemsg("!!! /etc/portage/profile/virtuals. Please move it to\n")
990 writemsg("!!! this new location.\n\n")
992 if not sandbox_capable and \
993 ("sandbox" in self.features or "usersandbox" in self.features):
994 if self.profile_path is not None and \
995 os.path.realpath(self.profile_path) == \
996 os.path.realpath(os.path.join(
997 self["PORTAGE_CONFIGROOT"], PROFILE_PATH)):
998 # Don't show this warning when running repoman and the
999 # sandbox feature came from a profile that doesn't belong
1001 writemsg(colorize("BAD", _("!!! Problem with sandbox"
1002 " binary. Disabling...\n\n")), noiselevel=-1)
1004 if "fakeroot" in self.features and \
1005 not fakeroot_capable:
1006 writemsg(_("!!! FEATURES=fakeroot is enabled, but the "
1007 "fakeroot binary is not installed.\n"), noiselevel=-1)
1009 if os.getuid() == 0 and not hasattr(os, "setgroups"):
1010 warning_shown = False
1012 if "userpriv" in self.features:
1013 writemsg(_("!!! FEATURES=userpriv is enabled, but "
1014 "os.setgroups is not available.\n"), noiselevel=-1)
1015 warning_shown = True
1017 if "userfetch" in self.features:
1018 writemsg(_("!!! FEATURES=userfetch is enabled, but "
1019 "os.setgroups is not available.\n"), noiselevel=-1)
1020 warning_shown = True
1022 if warning_shown and platform.python_implementation() == 'PyPy':
1023 writemsg(_("!!! See https://bugs.pypy.org/issue833 for details.\n"),
1026 def load_best_module(self,property_string):
1027 best_mod = best_from_dict(property_string,self.modules,self.module_priority)
1030 mod = load_mod(best_mod)
1032 if best_mod in self._module_aliases:
1033 mod = load_mod(self._module_aliases[best_mod])
1034 elif not best_mod.startswith("cache."):
1037 best_mod = "portage." + best_mod
1039 mod = load_mod(best_mod)
1050 def modifying(self):
1052 raise Exception(_("Configuration is locked."))
1054 def backup_changes(self,key=None):
1056 if key and key in self.configdict["env"]:
1057 self.backupenv[key] = copy.deepcopy(self.configdict["env"][key])
1059 raise KeyError(_("No such key defined in environment: %s") % key)
1061 def reset(self, keeping_pkg=0, use_cache=None):
1063 Restore environment from self.backupenv, call self.regenerate()
1064 @param keeping_pkg: Should we keep the setcpv() data or delete it.
1065 @type keeping_pkg: Boolean
1069 if use_cache is not None:
1070 warnings.warn("The use_cache parameter for config.reset() is deprecated and without effect.",
1071 DeprecationWarning, stacklevel=2)
1074 self.configdict["env"].clear()
1075 self.configdict["env"].update(self.backupenv)
1077 self.modifiedkeys = []
1080 self._setcpv_args_hash = None
1083 self.configdict["pkg"].clear()
1084 self.configdict["pkginternal"].clear()
1085 self.configdict["repo"].clear()
1086 self.configdict["defaults"]["USE"] = \
1087 " ".join(self.make_defaults_use)
1088 self.usemask = self._use_manager.getUseMask()
1089 self.useforce = self._use_manager.getUseForce()
1092 class _lazy_vars(object):
1094 __slots__ = ('built_use', 'settings', 'values')
1096 def __init__(self, built_use, settings):
1097 self.built_use = built_use
1098 self.settings = settings
1101 def __getitem__(self, k):
1102 if self.values is None:
1103 self.values = self._init_values()
1104 return self.values[k]
1106 def _init_values(self):
1108 settings = self.settings
1109 use = self.built_use
1111 use = frozenset(settings['PORTAGE_USE'].split())
1113 values['ACCEPT_LICENSE'] = settings._license_manager.get_prunned_accept_license( \
1114 settings.mycpv, use, settings['LICENSE'], settings['SLOT'], settings.get('PORTAGE_REPO_NAME'))
1115 values['PORTAGE_RESTRICT'] = self._restrict(use, settings)
1118 def _restrict(self, use, settings):
1120 restrict = set(use_reduce(settings['RESTRICT'], uselist=use, flat=True))
1121 except InvalidDependString:
1123 return ' '.join(sorted(restrict))
1125 class _lazy_use_expand(object):
1127 Lazily evaluate USE_EXPAND variables since they are only needed when
1128 an ebuild shell is spawned. Variables values are made consistent with
1129 the previously calculated USE settings.
1132 def __init__(self, use, usemask, iuse_implicit,
1133 use_expand_split, use_expand_dict):
1135 self._usemask = usemask
1136 self._iuse_implicit = iuse_implicit
1137 self._use_expand_split = use_expand_split
1138 self._use_expand_dict = use_expand_dict
1140 def __getitem__(self, key):
1141 prefix = key.lower() + '_'
1142 prefix_len = len(prefix)
1143 expand_flags = set( x[prefix_len:] for x in self._use \
1144 if x[:prefix_len] == prefix )
1145 var_split = self._use_expand_dict.get(key, '').split()
1146 # Preserve the order of var_split because it can matter for things
1148 var_split = [ x for x in var_split if x in expand_flags ]
1149 var_split.extend(expand_flags.difference(var_split))
1150 has_wildcard = '*' in expand_flags
1152 var_split = [ x for x in var_split if x != "*" ]
1154 for x in self._iuse_implicit:
1155 if x[:prefix_len] == prefix:
1156 has_iuse.add(x[prefix_len:])
1158 # * means to enable everything in IUSE that's not masked
1160 usemask = self._usemask
1161 for suffix in has_iuse:
1163 if x not in usemask:
1164 if suffix not in expand_flags:
1165 var_split.append(suffix)
1167 # If there is a wildcard and no matching flags in IUSE then
1168 # LINGUAS should be unset so that all .mo files are
1171 # Make the flags unique and filter them according to IUSE.
1172 # Also, continue to preserve order for things like LINGUAS
1173 # and filter any duplicates that variable may contain.
1174 filtered_var_split = []
1175 remaining = has_iuse.intersection(var_split)
1179 filtered_var_split.append(x)
1180 var_split = filtered_var_split
1183 value = ' '.join(var_split)
1185 # Don't export empty USE_EXPAND vars unless the user config
1186 # exports them as empty. This is required for vars such as
1187 # LINGUAS, where unset and empty have different meanings.
1189 # ebuild.sh will see this and unset the variable so
1190 # that things like LINGUAS work properly
1196 # It's not in IUSE, so just allow the variable content
1197 # to pass through if it is defined somewhere. This
1198 # allows packages that support LINGUAS but don't
1199 # declare it in IUSE to use the variable outside of the
1200 # USE_EXPAND context.
1205 def setcpv(self, mycpv, use_cache=None, mydb=None):
1207 Load a particular CPV into the config, this lets us see the
1208 Default USE flags for a particular ebuild as well as the USE
1209 flags from package.use.
1211 @param mycpv: A cpv to load
1213 @param mydb: a dbapi instance that supports aux_get with the IUSE key.
1214 @type mydb: dbapi or derivative.
1218 if use_cache is not None:
1219 warnings.warn("The use_cache parameter for config.setcpv() is deprecated and without effect.",
1220 DeprecationWarning, stacklevel=2)
1226 explicit_iuse = None
1227 if not isinstance(mycpv, basestring):
1231 explicit_iuse = pkg.iuse.all
1232 args_hash = (mycpv, id(pkg))
1234 built_use = pkg.use.enabled
1236 args_hash = (mycpv, id(mydb))
1238 if args_hash == self._setcpv_args_hash:
1240 self._setcpv_args_hash = args_hash
1244 cat, pf = catsplit(mycpv)
1245 cp = cpv_getkey(mycpv)
1246 cpv_slot = self.mycpv
1249 pkg_configdict = self.configdict["pkg"]
1250 previous_iuse = pkg_configdict.get("IUSE")
1251 previous_iuse_effective = pkg_configdict.get("IUSE_EFFECTIVE")
1252 previous_features = pkg_configdict.get("FEATURES")
1254 aux_keys = self._setcpv_aux_keys
1256 # Discard any existing metadata and package.env settings from
1257 # the previous package instance.
1258 pkg_configdict.clear()
1260 pkg_configdict["CATEGORY"] = cat
1261 pkg_configdict["PF"] = pf
1265 if not hasattr(mydb, "aux_get"):
1268 # Make these lazy, since __getitem__ triggers
1269 # evaluation of USE conditionals which can't
1270 # occur until PORTAGE_USE is calculated below.
1271 pkg_configdict.addLazySingleton(k,
1272 mydb.__getitem__, k)
1274 # When calling dbapi.aux_get(), grab USE for built/installed
1275 # packages since we want to save it PORTAGE_BUILT_USE for
1276 # evaluating conditional USE deps in atoms passed via IPC to
1277 # helpers like has_version and best_version.
1278 aux_keys = set(aux_keys)
1279 if hasattr(mydb, '_aux_cache_keys'):
1280 aux_keys = aux_keys.intersection(mydb._aux_cache_keys)
1282 aux_keys = list(aux_keys)
1283 for k, v in zip(aux_keys, mydb.aux_get(self.mycpv, aux_keys)):
1284 pkg_configdict[k] = v
1285 built_use = frozenset(pkg_configdict.pop('USE').split())
1287 # Empty USE means this dbapi instance does not contain
1290 eapi = pkg_configdict['EAPI']
1292 repository = pkg_configdict.pop("repository", None)
1293 if repository is not None:
1294 pkg_configdict["PORTAGE_REPO_NAME"] = repository
1295 slot = pkg_configdict["SLOT"]
1296 iuse = pkg_configdict["IUSE"]
1298 cpv_slot = _pkg_str(self.mycpv, metadata=pkg_configdict,
1303 for x in iuse.split():
1304 if x.startswith("+"):
1305 pkginternaluse.append(x[1:])
1306 elif x.startswith("-"):
1307 pkginternaluse.append(x)
1308 pkginternaluse = " ".join(pkginternaluse)
1310 eapi_attrs = _get_eapi_attrs(eapi)
1312 if pkginternaluse != self.configdict["pkginternal"].get("USE", ""):
1313 self.configdict["pkginternal"]["USE"] = pkginternaluse
1317 if repository and repository != Package.UNKNOWN_REPO:
1320 repos.extend(repo.name for repo in
1321 self.repositories[repository].masters)
1324 repos.append(repository)
1326 d = self._repo_make_defaults.get(repo)
1330 # make a copy, since we might modify it with
1331 # package.use settings
1333 cpdict = self._use_manager._repo_puse_dict.get(repo, {}).get(cp)
1335 repo_puse = ordered_by_atom_specificity(cpdict, cpv_slot)
1338 d["USE"] = d.get("USE", "") + " " + " ".join(x)
1342 if repo_env or self.configdict["repo"]:
1343 self.configdict["repo"].clear()
1344 self.configdict["repo"].update(stack_dicts(repo_env,
1345 incrementals=self.incrementals))
1349 for i, pkgprofileuse_dict in enumerate(self._use_manager._pkgprofileuse):
1350 if self.make_defaults_use[i]:
1351 defaults.append(self.make_defaults_use[i])
1352 cpdict = pkgprofileuse_dict.get(cp)
1354 pkg_defaults = ordered_by_atom_specificity(cpdict, cpv_slot)
1356 defaults.extend(pkg_defaults)
1357 defaults = " ".join(defaults)
1358 if defaults != self.configdict["defaults"].get("USE",""):
1359 self.configdict["defaults"]["USE"] = defaults
1362 useforce = self._use_manager.getUseForce(cpv_slot)
1363 if useforce != self.useforce:
1364 self.useforce = useforce
1367 usemask = self._use_manager.getUseMask(cpv_slot)
1368 if usemask != self.usemask:
1369 self.usemask = usemask
1373 self.puse = self._use_manager.getPUSE(cpv_slot)
1374 if oldpuse != self.puse:
1376 self.configdict["pkg"]["PKGUSE"] = self.puse[:] # For saving to PUSE file
1377 self.configdict["pkg"]["USE"] = self.puse[:] # this gets appended to USE
1379 if previous_features:
1380 # The package from the previous setcpv call had package.env
1381 # settings which modified FEATURES. Therefore, trigger a
1382 # regenerate() call in order to ensure that self.features
1387 cpdict = self._penvdict.get(cp)
1389 penv_matches = ordered_by_atom_specificity(cpdict, cpv_slot)
1391 for x in penv_matches:
1392 self._penv.extend(x)
1394 protected_pkg_keys = set(pkg_configdict)
1395 protected_pkg_keys.discard('USE')
1397 # If there are _any_ package.env settings for this package
1398 # then it automatically triggers config.reset(), in order
1399 # to account for possible incremental interaction between
1400 # package.use, package.env, and overrides from the calling
1401 # environment (configdict['env']).
1404 # USE is special because package.use settings override
1405 # it. Discard any package.use settings here and they'll
1406 # be added back later.
1407 pkg_configdict.pop('USE', None)
1408 self._grab_pkg_env(self._penv, pkg_configdict,
1409 protected_keys=protected_pkg_keys)
1411 # Now add package.use settings, which override USE from
1414 if 'USE' in pkg_configdict:
1415 pkg_configdict['USE'] = \
1416 pkg_configdict['USE'] + " " + self.puse
1418 pkg_configdict['USE'] = self.puse
1421 self.reset(keeping_pkg=1)
1423 env_configdict = self.configdict['env']
1425 # Ensure that "pkg" values are always preferred over "env" values.
1426 # This must occur _after_ the above reset() call, since reset()
1427 # copies values from self.backupenv.
1428 for k in protected_pkg_keys:
1429 env_configdict.pop(k, None)
1431 lazy_vars = self._lazy_vars(built_use, self)
1432 env_configdict.addLazySingleton('ACCEPT_LICENSE',
1433 lazy_vars.__getitem__, 'ACCEPT_LICENSE')
1434 env_configdict.addLazySingleton('PORTAGE_RESTRICT',
1435 lazy_vars.__getitem__, 'PORTAGE_RESTRICT')
1437 if built_use is not None:
1438 pkg_configdict['PORTAGE_BUILT_USE'] = ' '.join(built_use)
1440 # If reset() has not been called, it's safe to return
1441 # early if IUSE has not changed.
1442 if not has_changed and previous_iuse == iuse and \
1443 (previous_iuse_effective is not None == eapi_attrs.iuse_effective):
1446 # Filter out USE flags that aren't part of IUSE. This has to
1447 # be done for every setcpv() call since practically every
1448 # package has different IUSE.
1449 use = set(self["USE"].split())
1450 if explicit_iuse is None:
1451 explicit_iuse = frozenset(x.lstrip("+-") for x in iuse.split())
1453 if eapi_attrs.iuse_effective:
1454 iuse_implicit_match = self._iuse_effective_match
1455 portage_iuse = set(self._iuse_effective)
1456 portage_iuse.update(explicit_iuse)
1457 self.configdict["pkg"]["IUSE_EFFECTIVE"] = \
1458 " ".join(sorted(portage_iuse))
1460 iuse_implicit_match = self._iuse_implicit_match
1461 portage_iuse = self._get_implicit_iuse()
1462 portage_iuse.update(explicit_iuse)
1464 # PORTAGE_IUSE is not always needed so it's lazily evaluated.
1465 self.configdict["env"].addLazySingleton(
1466 "PORTAGE_IUSE", _lazy_iuse_regex, portage_iuse)
1468 ebuild_force_test = self.get("EBUILD_FORCE_TEST") == "1"
1469 if ebuild_force_test and \
1470 not hasattr(self, "_ebuild_force_test_msg_shown"):
1471 self._ebuild_force_test_msg_shown = True
1472 writemsg(_("Forcing test.\n"), noiselevel=-1)
1474 if "test" in explicit_iuse or iuse_implicit_match("test"):
1475 if "test" not in self.features:
1477 elif "test" in self.usemask and not ebuild_force_test:
1478 # "test" is in IUSE and USE=test is masked, so execution
1479 # of src_test() probably is not reliable. Therefore,
1480 # temporarily disable FEATURES=test just for this package.
1481 self["FEATURES"] = " ".join(x for x in self.features \
1486 if ebuild_force_test and "test" in self.usemask:
1488 frozenset(x for x in self.usemask if x != "test")
1490 # Allow _* flags from USE_EXPAND wildcards to pass through here.
1491 use.difference_update([x for x in use \
1492 if (x not in explicit_iuse and \
1493 not iuse_implicit_match(x)) and x[-2:] != '_*'])
1495 # Use the calculated USE flags to regenerate the USE_EXPAND flags so
1496 # that they are consistent. For optimal performance, use slice
1497 # comparison instead of startswith().
1498 use_expand_split = set(x.lower() for \
1499 x in self.get('USE_EXPAND', '').split())
1500 lazy_use_expand = self._lazy_use_expand(use, self.usemask,
1501 portage_iuse, use_expand_split, self._use_expand_dict)
1503 use_expand_iuses = {}
1504 for x in portage_iuse:
1505 x_split = x.split('_')
1506 if len(x_split) == 1:
1508 for i in range(len(x_split) - 1):
1509 k = '_'.join(x_split[:i+1])
1510 if k in use_expand_split:
1511 v = use_expand_iuses.get(k)
1514 use_expand_iuses[k] = v
1518 # If it's not in IUSE, variable content is allowed
1519 # to pass through if it is defined somewhere. This
1520 # allows packages that support LINGUAS but don't
1521 # declare it in IUSE to use the variable outside of the
1522 # USE_EXPAND context.
1523 for k, use_expand_iuse in use_expand_iuses.items():
1525 use.update( x for x in use_expand_iuse if x not in usemask )
1527 self.configdict['env'].addLazySingleton(k,
1528 lazy_use_expand.__getitem__, k)
1530 for k in self.get("USE_EXPAND_UNPREFIXED", "").split():
1531 var_split = self.get(k, '').split()
1532 var_split = [ x for x in var_split if x in use ]
1534 self.configlist[-1][k] = ' '.join(var_split)
1536 self.configlist[-1][k] = ''
1538 # Filtered for the ebuild environment. Store this in a separate
1539 # attribute since we still want to be able to see global USE
1540 # settings for things like emerge --info.
1542 self.configdict["env"]["PORTAGE_USE"] = \
1543 " ".join(sorted(x for x in use if x[-2:] != '_*'))
1545 # Clear the eapi cache here rather than in the constructor, since
1546 # setcpv triggers lazy instantiation of things like _use_manager.
1549 def _grab_pkg_env(self, penv, container, protected_keys=None):
1550 if protected_keys is None:
1552 abs_user_config = os.path.join(
1553 self['PORTAGE_CONFIGROOT'], USER_CONFIG_PATH)
1554 non_user_variables = self._non_user_variables
1555 # Make a copy since we don't want per-package settings
1556 # to pollute the global expand_map.
1557 expand_map = self._expand_map.copy()
1558 incrementals = self.incrementals
1559 for envname in penv:
1560 penvfile = os.path.join(abs_user_config, "env", envname)
1561 penvconfig = getconfig(penvfile, tolerant=self._tolerant,
1562 allow_sourcing=True, expand=expand_map)
1563 if penvconfig is None:
1564 writemsg("!!! %s references non-existent file: %s\n" % \
1565 (os.path.join(abs_user_config, 'package.env'), penvfile),
1568 for k, v in penvconfig.items():
1569 if k in protected_keys or \
1570 k in non_user_variables:
1571 writemsg("!!! Illegal variable " + \
1572 "'%s' assigned in '%s'\n" % \
1573 (k, penvfile), noiselevel=-1)
1574 elif k in incrementals:
1576 container[k] = container[k] + " " + v
1582 def _iuse_effective_match(self, flag):
1583 return flag in self._iuse_effective
1585 def _calc_iuse_effective(self):
1587 Beginning with EAPI 5, IUSE_EFFECTIVE is defined by PMS.
1590 iuse_effective.extend(self.get("IUSE_IMPLICIT", "").split())
1592 # USE_EXPAND_IMPLICIT should contain things like ARCH, ELIBC,
1593 # KERNEL, and USERLAND.
1594 use_expand_implicit = frozenset(
1595 self.get("USE_EXPAND_IMPLICIT", "").split())
1597 # USE_EXPAND_UNPREFIXED should contain at least ARCH, and
1598 # USE_EXPAND_VALUES_ARCH should contain all valid ARCH flags.
1599 for v in self.get("USE_EXPAND_UNPREFIXED", "").split():
1600 if v not in use_expand_implicit:
1602 iuse_effective.extend(
1603 self.get("USE_EXPAND_VALUES_" + v, "").split())
1605 use_expand = frozenset(self.get("USE_EXPAND", "").split())
1606 for v in use_expand_implicit:
1607 if v not in use_expand:
1610 for x in self.get("USE_EXPAND_VALUES_" + v, "").split():
1611 iuse_effective.append(lower_v + "_" + x)
1613 return frozenset(iuse_effective)
1615 def _get_implicit_iuse(self):
1617 Prior to EAPI 5, these flags are considered to
1618 be implicit members of IUSE:
1619 * Flags derived from ARCH
1620 * Flags derived from USE_EXPAND_HIDDEN variables
1621 * Masked flags, such as those from {,package}use.mask
1622 * Forced flags, such as those from {,package}use.force
1623 * build and bootstrap flags used by bootstrap.sh
1625 iuse_implicit = set()
1626 # Flags derived from ARCH.
1627 arch = self.configdict["defaults"].get("ARCH")
1629 iuse_implicit.add(arch)
1630 iuse_implicit.update(self.get("PORTAGE_ARCHLIST", "").split())
1632 # Flags derived from USE_EXPAND_HIDDEN variables
1633 # such as ELIBC, KERNEL, and USERLAND.
1634 use_expand_hidden = self.get("USE_EXPAND_HIDDEN", "").split()
1635 for x in use_expand_hidden:
1636 iuse_implicit.add(x.lower() + "_.*")
1638 # Flags that have been masked or forced.
1639 iuse_implicit.update(self.usemask)
1640 iuse_implicit.update(self.useforce)
1642 # build and bootstrap flags used by bootstrap.sh
1643 iuse_implicit.add("build")
1644 iuse_implicit.add("bootstrap")
1646 # Controlled by FEATURES=test. Make this implicit, so handling
1647 # of FEATURES=test is consistent regardless of explicit IUSE.
1648 # Users may use use.mask/package.use.mask to control
1649 # FEATURES=test for all ebuilds, regardless of explicit IUSE.
1650 iuse_implicit.add("test")
1652 return iuse_implicit
1654 def _getUseMask(self, pkg):
1655 return self._use_manager.getUseMask(pkg)
1657 def _getUseForce(self, pkg):
1658 return self._use_manager.getUseForce(pkg)
1660 def _getMaskAtom(self, cpv, metadata):
1662 Take a package and return a matching package.mask atom, or None if no
1663 such atom exists or it has been cancelled by package.unmask. PROVIDE
1664 is not checked, so atoms will not be found for old-style virtuals.
1666 @param cpv: The package name
1668 @param metadata: A dictionary of raw package metadata
1669 @type metadata: dict
1671 @return: A matching atom string or None if one is not found.
1673 return self._mask_manager.getMaskAtom(cpv, metadata["SLOT"], metadata.get('repository'))
1675 def _getRawMaskAtom(self, cpv, metadata):
1677 Take a package and return a matching package.mask atom, or None if no
1678 such atom exists or it has been cancelled by package.unmask. PROVIDE
1679 is not checked, so atoms will not be found for old-style virtuals.
1681 @param cpv: The package name
1683 @param metadata: A dictionary of raw package metadata
1684 @type metadata: dict
1686 @return: A matching atom string or None if one is not found.
1688 return self._mask_manager.getRawMaskAtom(cpv, metadata["SLOT"], metadata.get('repository'))
1691 def _getProfileMaskAtom(self, cpv, metadata):
1693 Take a package and return a matching profile atom, or None if no
1694 such atom exists. Note that a profile atom may or may not have a "*"
1695 prefix. PROVIDE is not checked, so atoms will not be found for
1698 @param cpv: The package name
1700 @param metadata: A dictionary of raw package metadata
1701 @type metadata: dict
1703 @return: A matching profile atom string or None if one is not found.
1706 warnings.warn("The config._getProfileMaskAtom() method is deprecated.",
1707 DeprecationWarning, stacklevel=2)
1709 cp = cpv_getkey(cpv)
1710 profile_atoms = self.prevmaskdict.get(cp)
1712 pkg = "".join((cpv, _slot_separator, metadata["SLOT"]))
1713 repo = metadata.get("repository")
1714 if repo and repo != Package.UNKNOWN_REPO:
1715 pkg = "".join((pkg, _repo_separator, repo))
1717 for x in profile_atoms:
1718 if match_from_list(x, pkg_list):
1723 def _isStable(self, pkg):
1724 return self._keywords_manager.isStable(pkg,
1725 self.get("ACCEPT_KEYWORDS", ""),
1726 self.configdict["backupenv"].get("ACCEPT_KEYWORDS", ""))
1728 def _getKeywords(self, cpv, metadata):
1729 return self._keywords_manager.getKeywords(cpv, metadata["SLOT"], \
1730 metadata.get("KEYWORDS", ""), metadata.get("repository"))
1732 def _getMissingKeywords(self, cpv, metadata):
1734 Take a package and return a list of any KEYWORDS that the user may
1735 need to accept for the given package. If the KEYWORDS are empty
1736 and the the ** keyword has not been accepted, the returned list will
1737 contain ** alone (in order to distinguish from the case of "none
1740 @param cpv: The package name (for package.keywords support)
1742 @param metadata: A dictionary of raw package metadata
1743 @type metadata: dict
1745 @return: A list of KEYWORDS that have not been accepted.
1748 # Hack: Need to check the env directly here as otherwise stacking
1749 # doesn't work properly as negative values are lost in the config
1750 # object (bug #139600)
1751 backuped_accept_keywords = self.configdict["backupenv"].get("ACCEPT_KEYWORDS", "")
1752 global_accept_keywords = self["ACCEPT_KEYWORDS"]
1754 return self._keywords_manager.getMissingKeywords(cpv, metadata["SLOT"], \
1755 metadata.get("KEYWORDS", ""), metadata.get('repository'), \
1756 global_accept_keywords, backuped_accept_keywords)
1758 def _getRawMissingKeywords(self, cpv, metadata):
1760 Take a package and return a list of any KEYWORDS that the user may
1761 need to accept for the given package. If the KEYWORDS are empty,
1762 the returned list will contain ** alone (in order to distinguish
1763 from the case of "none missing"). This DOES NOT apply any user config
1764 package.accept_keywords acceptance.
1766 @param cpv: The package name (for package.keywords support)
1768 @param metadata: A dictionary of raw package metadata
1769 @type metadata: dict
1771 @return: lists of KEYWORDS that have not been accepted
1772 and the keywords it looked for.
1774 return self._keywords_manager.getRawMissingKeywords(cpv, metadata["SLOT"], \
1775 metadata.get("KEYWORDS", ""), metadata.get('repository'), \
1776 self.get("ACCEPT_KEYWORDS", ""))
1778 def _getPKeywords(self, cpv, metadata):
1779 global_accept_keywords = self.get("ACCEPT_KEYWORDS", "")
1781 return self._keywords_manager.getPKeywords(cpv, metadata["SLOT"], \
1782 metadata.get('repository'), global_accept_keywords)
1784 def _getMissingLicenses(self, cpv, metadata):
1786 Take a LICENSE string and return a list of any licenses that the user
1787 may need to accept for the given package. The returned list will not
1788 contain any licenses that have already been accepted. This method
1789 can throw an InvalidDependString exception.
1791 @param cpv: The package name (for package.license support)
1793 @param metadata: A dictionary of raw package metadata
1794 @type metadata: dict
1796 @return: A list of licenses that have not been accepted.
1798 return self._license_manager.getMissingLicenses( \
1799 cpv, metadata["USE"], metadata["LICENSE"], metadata["SLOT"], metadata.get('repository'))
1801 def _getMissingProperties(self, cpv, metadata):
1803 Take a PROPERTIES string and return a list of any properties the user
1804 may need to accept for the given package. The returned list will not
1805 contain any properties that have already been accepted. This method
1806 can throw an InvalidDependString exception.
1808 @param cpv: The package name (for package.properties support)
1810 @param metadata: A dictionary of raw package metadata
1811 @type metadata: dict
1813 @return: A list of properties that have not been accepted.
1815 accept_properties = self._accept_properties
1818 except AttributeError:
1819 cpv = _pkg_str(cpv, metadata=metadata, settings=self)
1820 cp = cpv_getkey(cpv)
1821 cpdict = self._ppropertiesdict.get(cp)
1823 pproperties_list = ordered_by_atom_specificity(cpdict, cpv)
1824 if pproperties_list:
1825 accept_properties = list(self._accept_properties)
1826 for x in pproperties_list:
1827 accept_properties.extend(x)
1829 properties_str = metadata.get("PROPERTIES", "")
1830 properties = set(use_reduce(properties_str, matchall=1, flat=True))
1831 properties.discard('||')
1833 acceptable_properties = set()
1834 for x in accept_properties:
1836 acceptable_properties.update(properties)
1838 acceptable_properties.clear()
1840 acceptable_properties.discard(x[1:])
1842 acceptable_properties.add(x)
1844 if "?" in properties_str:
1845 use = metadata["USE"].split()
1849 properties_struct = use_reduce(properties_str, uselist=use, opconvert=True)
1850 return self._getMaskedProperties(properties_struct, acceptable_properties)
1852 def _getMaskedProperties(self, properties_struct, acceptable_properties):
1853 if not properties_struct:
1855 if properties_struct[0] == "||":
1857 for element in properties_struct[1:]:
1858 if isinstance(element, list):
1860 tmp = self._getMaskedProperties(
1861 element, acceptable_properties)
1866 if element in acceptable_properties:
1869 # Return all masked properties, since we don't know which combination
1870 # (if any) the user will decide to unmask
1874 for element in properties_struct:
1875 if isinstance(element, list):
1877 ret.extend(self._getMaskedProperties(element,
1878 acceptable_properties))
1880 if element not in acceptable_properties:
1884 def _accept_chost(self, cpv, metadata):
1886 @return True if pkg CHOST is accepted, False otherwise.
1888 if self._accept_chost_re is None:
1889 accept_chost = self.get("ACCEPT_CHOSTS", "").split()
1890 if not accept_chost:
1891 chost = self.get("CHOST")
1893 accept_chost.append(chost)
1894 if not accept_chost:
1895 self._accept_chost_re = re.compile(".*")
1896 elif len(accept_chost) == 1:
1898 self._accept_chost_re = re.compile(r'^%s$' % accept_chost[0])
1899 except re.error as e:
1900 writemsg(_("!!! Invalid ACCEPT_CHOSTS value: '%s': %s\n") % \
1901 (accept_chost[0], e), noiselevel=-1)
1902 self._accept_chost_re = re.compile("^$")
1905 self._accept_chost_re = re.compile(
1906 r'^(%s)$' % "|".join(accept_chost))
1907 except re.error as e:
1908 writemsg(_("!!! Invalid ACCEPT_CHOSTS value: '%s': %s\n") % \
1909 (" ".join(accept_chost), e), noiselevel=-1)
1910 self._accept_chost_re = re.compile("^$")
1912 pkg_chost = metadata.get('CHOST', '')
1913 return not pkg_chost or \
1914 self._accept_chost_re.match(pkg_chost) is not None
1916 def setinst(self, mycpv, mydbapi):
1917 """This updates the preferences for old-style virtuals,
1918 affecting the behavior of dep_expand() and dep_check()
1919 calls. It can change dbapi.match() behavior since that
1920 calls dep_expand(). However, dbapi instances have
1921 internal match caches that are not invalidated when
1922 preferences are updated here. This can potentially
1923 lead to some inconsistency (relevant to bug #1343)."""
1926 # Grab the virtuals this package provides and add them into the tree virtuals.
1927 if not hasattr(mydbapi, "aux_get"):
1928 provides = mydbapi["PROVIDE"]
1930 provides = mydbapi.aux_get(mycpv, ["PROVIDE"])[0]
1933 if isinstance(mydbapi, portdbapi):
1934 self.setcpv(mycpv, mydb=mydbapi)
1935 myuse = self["PORTAGE_USE"]
1936 elif not hasattr(mydbapi, "aux_get"):
1937 myuse = mydbapi["USE"]
1939 myuse = mydbapi.aux_get(mycpv, ["USE"])[0]
1940 virts = use_reduce(provides, uselist=myuse.split(), flat=True)
1942 # Ensure that we don't trigger the _treeVirtuals
1943 # assertion in VirtualsManager._compile_virtuals().
1945 self._virtuals_manager.add_depgraph_virtuals(mycpv, virts)
1948 """Reload things like /etc/profile.env that can change during runtime."""
1949 env_d_filename = os.path.join(self["EROOT"], "etc", "profile.env")
1950 self.configdict["env.d"].clear()
1951 env_d = getconfig(env_d_filename,
1952 tolerant=self._tolerant, expand=False)
1954 # env_d will be None if profile.env doesn't exist.
1955 for k in self._env_d_blacklist:
1957 self.configdict["env.d"].update(env_d)
1959 def regenerate(self, useonly=0, use_cache=None):
1962 This involves regenerating valid USE flags, re-expanding USE_EXPAND flags
1963 re-stacking USE flags (-flag and -*), as well as any other INCREMENTAL
1964 variables. This also updates the env.d configdict; useful in case an ebuild
1965 changes the environment.
1967 If FEATURES has already stacked, it is not stacked twice.
1969 @param useonly: Only regenerate USE flags (not any other incrementals)
1970 @type useonly: Boolean
1974 if use_cache is not None:
1975 warnings.warn("The use_cache parameter for config.regenerate() is deprecated and without effect.",
1976 DeprecationWarning, stacklevel=2)
1981 myincrementals=["USE"]
1983 myincrementals = self.incrementals
1984 myincrementals = set(myincrementals)
1986 # Process USE last because it depends on USE_EXPAND which is also
1988 myincrementals.discard("USE")
1990 mydbs = self.configlist[:-1]
1991 mydbs.append(self.backupenv)
1993 # ACCEPT_LICENSE is a lazily evaluated incremental, so that * can be
1994 # used to match all licenses without every having to explicitly expand
1995 # it to all licenses.
1996 if self.local_config:
1999 mysplit.extend(curdb.get('ACCEPT_LICENSE', '').split())
2000 mysplit = prune_incremental(mysplit)
2001 accept_license_str = ' '.join(mysplit)
2002 self.configlist[-1]['ACCEPT_LICENSE'] = accept_license_str
2003 self._license_manager.set_accept_license_str(accept_license_str)
2005 # repoman will accept any license
2006 self._license_manager.set_accept_license_str("*")
2008 # ACCEPT_PROPERTIES works like ACCEPT_LICENSE, without groups
2009 if self.local_config:
2012 mysplit.extend(curdb.get('ACCEPT_PROPERTIES', '').split())
2013 mysplit = prune_incremental(mysplit)
2014 self.configlist[-1]['ACCEPT_PROPERTIES'] = ' '.join(mysplit)
2015 if tuple(mysplit) != self._accept_properties:
2016 self._accept_properties = tuple(mysplit)
2018 # repoman will accept any property
2019 self._accept_properties = ('*',)
2021 increment_lists = {}
2022 for k in myincrementals:
2023 incremental_list = []
2024 increment_lists[k] = incremental_list
2028 incremental_list.append(v.split())
2030 if 'FEATURES' in increment_lists:
2031 increment_lists['FEATURES'].append(self._features_overrides)
2034 for mykey, incremental_list in increment_lists.items():
2037 for mysplit in incremental_list:
2041 # "-*" is a special "minus" var that means "unset all settings".
2042 # so USE="-* gnome" will have *just* gnome enabled.
2047 # Not legal. People assume too much. Complain.
2048 writemsg(colorize("BAD",
2049 _("%s values should not start with a '+': %s") % (mykey,x)) \
2050 + "\n", noiselevel=-1)
2056 myflags.discard(x[1:])
2059 # We got here, so add it now.
2062 #store setting in last element of configlist, the original environment:
2063 if myflags or mykey in self:
2064 self.configlist[-1][mykey] = " ".join(sorted(myflags))
2066 # Do the USE calculation last because it depends on USE_EXPAND.
2067 use_expand = self.get("USE_EXPAND", "").split()
2068 use_expand_dict = self._use_expand_dict
2069 use_expand_dict.clear()
2070 for k in use_expand:
2073 use_expand_dict[k] = v
2075 use_expand_unprefixed = self.get("USE_EXPAND_UNPREFIXED", "").split()
2077 # In order to best accomodate the long-standing practice of
2078 # setting default USE_EXPAND variables in the profile's
2079 # make.defaults, we translate these variables into their
2080 # equivalent USE flags so that useful incremental behavior
2081 # is enabled (for sub-profiles).
2082 configdict_defaults = self.configdict['defaults']
2083 if self._make_defaults is not None:
2084 for i, cfg in enumerate(self._make_defaults):
2086 self.make_defaults_use.append("")
2088 use = cfg.get("USE", "")
2091 for k in use_expand_unprefixed:
2094 expand_use.extend(v.split())
2096 for k in use_expand_dict:
2100 prefix = k.lower() + '_'
2101 if k in myincrementals:
2104 expand_use.append('-' + prefix + x[1:])
2106 expand_use.append(prefix + x)
2109 expand_use.append(prefix + x)
2111 expand_use.append(use)
2112 use = ' '.join(expand_use)
2113 self.make_defaults_use.append(use)
2114 self.make_defaults_use = tuple(self.make_defaults_use)
2115 configdict_defaults['USE'] = ' '.join(
2116 stack_lists([x.split() for x in self.make_defaults_use]))
2117 # Set to None so this code only runs once.
2118 self._make_defaults = None
2121 for x in self["USE_ORDER"].split(":"):
2122 if x in self.configdict:
2123 self.uvlist.append(self.configdict[x])
2124 self.uvlist.reverse()
2126 # For optimal performance, use slice
2127 # comparison instead of startswith().
2128 iuse = self.configdict["pkg"].get("IUSE")
2129 if iuse is not None:
2130 iuse = [x.lstrip("+-") for x in iuse.split()]
2132 for curdb in self.uvlist:
2134 for k in use_expand_unprefixed:
2140 myflags.discard(x[1:])
2144 cur_use_expand = [x for x in use_expand if x in curdb]
2145 mysplit = curdb.get("USE", "").split()
2146 if not mysplit and not cur_use_expand:
2154 writemsg(colorize("BAD", _("USE flags should not start "
2155 "with a '+': %s\n") % x), noiselevel=-1)
2163 prefix_len = len(prefix)
2164 myflags.difference_update(
2165 [y for y in myflags if \
2166 y[:prefix_len] == prefix])
2167 myflags.discard(x[1:])
2170 if iuse is not None and x[-2:] == '_*':
2171 # Expand wildcards here, so that cases like
2172 # USE="linguas_* -linguas_en_US" work correctly.
2174 prefix_len = len(prefix)
2177 if y[:prefix_len] == prefix:
2181 # There are no matching IUSE, so allow the
2182 # wildcard to pass through. This allows
2183 # linguas_* to trigger unset LINGUAS in
2184 # cases when no linguas_ flags are in IUSE.
2189 if curdb is configdict_defaults:
2190 # USE_EXPAND flags from make.defaults are handled
2191 # earlier, in order to provide useful incremental
2192 # behavior (for sub-profiles).
2195 for var in cur_use_expand:
2196 var_lower = var.lower()
2197 is_not_incremental = var not in myincrementals
2198 if is_not_incremental:
2199 prefix = var_lower + "_"
2200 prefix_len = len(prefix)
2201 for x in list(myflags):
2202 if x[:prefix_len] == prefix:
2204 for x in curdb[var].split():
2206 if is_not_incremental:
2207 writemsg(colorize("BAD", _("Invalid '+' "
2208 "operator in non-incremental variable "
2209 "'%s': '%s'\n") % (var, x)), noiselevel=-1)
2212 writemsg(colorize("BAD", _("Invalid '+' "
2213 "operator in incremental variable "
2214 "'%s': '%s'\n") % (var, x)), noiselevel=-1)
2217 if is_not_incremental:
2218 writemsg(colorize("BAD", _("Invalid '-' "
2219 "operator in non-incremental variable "
2220 "'%s': '%s'\n") % (var, x)), noiselevel=-1)
2222 myflags.discard(var_lower + "_" + x[1:])
2224 myflags.add(var_lower + "_" + x)
2226 if hasattr(self, "features"):
2227 self.features._features.clear()
2229 self.features = features_set(self)
2230 self.features._features.update(self.get('FEATURES', '').split())
2231 self.features._sync_env_var()
2232 self.features._validate()
2234 myflags.update(self.useforce)
2235 arch = self.configdict["defaults"].get("ARCH")
2239 myflags.difference_update(self.usemask)
2240 self.configlist[-1]["USE"]= " ".join(sorted(myflags))
2242 if self.mycpv is None:
2243 # Generate global USE_EXPAND variables settings that are
2244 # consistent with USE, for display by emerge --info. For
2245 # package instances, these are instead generated via
2247 for k in use_expand:
2248 prefix = k.lower() + '_'
2249 prefix_len = len(prefix)
2250 expand_flags = set( x[prefix_len:] for x in myflags \
2251 if x[:prefix_len] == prefix )
2252 var_split = use_expand_dict.get(k, '').split()
2253 var_split = [ x for x in var_split if x in expand_flags ]
2254 var_split.extend(sorted(expand_flags.difference(var_split)))
2256 self.configlist[-1][k] = ' '.join(var_split)
2258 self.configlist[-1][k] = ''
2260 for k in use_expand_unprefixed:
2261 var_split = self.get(k, '').split()
2262 var_split = [ x for x in var_split if x in myflags ]
2264 self.configlist[-1][k] = ' '.join(var_split)
2266 self.configlist[-1][k] = ''
2270 warnings.warn("portage config.virts_p attribute " + \
2271 "is deprecated, use config.get_virts_p()",
2272 DeprecationWarning, stacklevel=2)
2273 return self.get_virts_p()
2277 warnings.warn("portage config.virtuals attribute " + \
2278 "is deprecated, use config.getvirtuals()",
2279 DeprecationWarning, stacklevel=2)
2280 return self.getvirtuals()
2282 def get_virts_p(self):
2283 # Ensure that we don't trigger the _treeVirtuals
2284 # assertion in VirtualsManager._compile_virtuals().
2286 return self._virtuals_manager.get_virts_p()
2288 def getvirtuals(self):
2289 if self._virtuals_manager._treeVirtuals is None:
2290 #Hack around the fact that VirtualsManager needs a vartree
2291 #and vartree needs a config instance.
2292 #This code should be part of VirtualsManager.getvirtuals().
2293 if self.local_config:
2294 temp_vartree = vartree(settings=self)
2295 self._virtuals_manager._populate_treeVirtuals(temp_vartree)
2297 self._virtuals_manager._treeVirtuals = {}
2299 return self._virtuals_manager.getvirtuals()
2301 def _populate_treeVirtuals_if_needed(self, vartree):
2302 """Reduce the provides into a list by CP."""
2303 if self._virtuals_manager._treeVirtuals is None:
2304 if self.local_config:
2305 self._virtuals_manager._populate_treeVirtuals(vartree)
2307 self._virtuals_manager._treeVirtuals = {}
2309 def __delitem__(self,mykey):
2312 def __getitem__(self, key):
2314 return self._getitem(key)
2316 return '' # for backward compat, don't raise KeyError
2318 def _getitem(self, mykey):
2320 if mykey in self._constant_keys:
2321 # These two point to temporary values when
2322 # portage plans to update itself.
2323 if mykey == "PORTAGE_BIN_PATH":
2324 return portage._bin_path
2325 elif mykey == "PORTAGE_PYM_PATH":
2326 return portage._pym_path
2328 elif mykey == "PORTAGE_GID":
2329 return _unicode_decode(str(portage_gid))
2331 for d in self.lookuplist:
2337 raise KeyError(mykey)
2339 def get(self, k, x=None):
2341 return self._getitem(k)
2345 def pop(self, key, *args):
2349 "pop expected at most 2 arguments, got " + \
2350 repr(1 + len(args)))
2352 for d in reversed(self.lookuplist):
2360 def __contains__(self, mykey):
2361 """Called to implement membership test operators (in and not in)."""
2363 self._getitem(mykey)
2369 def setdefault(self, k, x=None):
2382 keys.update(self._constant_keys)
2383 for d in self.lookuplist:
2390 def iteritems(self):
2392 yield (k, self._getitem(k))
2395 return list(self.iteritems())
2397 def __setitem__(self,mykey,myvalue):
2398 "set a value; will be thrown away at reset() time"
2399 if not isinstance(myvalue, basestring):
2400 raise ValueError("Invalid type being used as a value: '%s': '%s'" % (str(mykey),str(myvalue)))
2402 # Avoid potential UnicodeDecodeError exceptions later.
2403 mykey = _unicode_decode(mykey)
2404 myvalue = _unicode_decode(myvalue)
2407 self.modifiedkeys.append(mykey)
2408 self.configdict["env"][mykey]=myvalue
2411 "return our locally-maintained environment"
2413 environ_filter = self._environ_filter
2415 eapi = self.get('EAPI')
2416 eapi_attrs = _get_eapi_attrs(eapi)
2417 phase = self.get('EBUILD_PHASE')
2418 filter_calling_env = False
2419 if self.mycpv is not None and \
2420 phase not in ('clean', 'cleanrm', 'depend', 'fetch'):
2421 temp_dir = self.get('T')
2422 if temp_dir is not None and \
2423 os.path.exists(os.path.join(temp_dir, 'environment')):
2424 filter_calling_env = True
2426 environ_whitelist = self._environ_whitelist
2428 if x in environ_filter:
2431 if not isinstance(myvalue, basestring):
2432 writemsg(_("!!! Non-string value in config: %s=%s\n") % \
2433 (x, myvalue), noiselevel=-1)
2435 if filter_calling_env and \
2436 x not in environ_whitelist and \
2437 not self._environ_whitelist_re.match(x):
2438 # Do not allow anything to leak into the ebuild
2439 # environment unless it is explicitly whitelisted.
2440 # This ensures that variables unset by the ebuild
2441 # remain unset (bug #189417).
2444 if "HOME" not in mydict and "BUILD_PREFIX" in mydict:
2445 writemsg("*** HOME not set. Setting to "+mydict["BUILD_PREFIX"]+"\n")
2446 mydict["HOME"]=mydict["BUILD_PREFIX"][:]
2448 if filter_calling_env:
2452 whitelist.append("RPMDIR")
2458 # At some point we may want to stop exporting FEATURES to the ebuild
2459 # environment, in order to prevent ebuilds from abusing it. In
2460 # preparation for that, export it as PORTAGE_FEATURES so that bashrc
2461 # users will be able to migrate any FEATURES conditional code to
2462 # use this alternative variable.
2463 mydict["PORTAGE_FEATURES"] = self["FEATURES"]
2465 # Filtered by IUSE and implicit IUSE.
2466 mydict["USE"] = self.get("PORTAGE_USE", "")
2468 # Don't export AA to the ebuild environment in EAPIs that forbid it
2469 if not eapi_exports_AA(eapi):
2470 mydict.pop("AA", None)
2472 if not eapi_exports_merge_type(eapi):
2473 mydict.pop("MERGE_TYPE", None)
2475 # Prefix variables are supported beginning with EAPI 3, or when
2476 # force-prefix is in FEATURES, since older EAPIs would otherwise be
2477 # useless with prefix configurations. This brings compatibility with
2478 # the prefix branch of portage, which also supports EPREFIX for all
2479 # EAPIs (for obvious reasons).
2480 if phase == 'depend' or \
2481 ('force-prefix' not in self.features and
2482 eapi is not None and not eapi_supports_prefix(eapi)):
2483 mydict.pop("ED", None)
2484 mydict.pop("EPREFIX", None)
2485 mydict.pop("EROOT", None)
2487 if phase == 'depend':
2488 mydict.pop('FILESDIR', None)
2490 if phase not in ("pretend", "setup", "preinst", "postinst") or \
2491 not eapi_exports_replace_vars(eapi):
2492 mydict.pop("REPLACING_VERSIONS", None)
2494 if phase not in ("prerm", "postrm") or \
2495 not eapi_exports_replace_vars(eapi):
2496 mydict.pop("REPLACED_BY_VERSION", None)
2498 if phase is not None and eapi_attrs.exports_EBUILD_PHASE_FUNC:
2499 phase_func = _phase_func_map.get(phase)
2500 if phase_func is not None:
2501 mydict["EBUILD_PHASE_FUNC"] = phase_func
2505 def thirdpartymirrors(self):
2506 if getattr(self, "_thirdpartymirrors", None) is None:
2507 profileroots = [os.path.join(self["PORTDIR"], "profiles")]
2508 for x in shlex_split(self.get("PORTDIR_OVERLAY", "")):
2509 profileroots.insert(0, os.path.join(x, "profiles"))
2510 thirdparty_lists = [grabdict(os.path.join(x, "thirdpartymirrors")) for x in profileroots]
2511 self._thirdpartymirrors = stack_dictlist(thirdparty_lists, incremental=True)
2512 return self._thirdpartymirrors
2516 for myarch in self["PORTAGE_ARCHLIST"].split():
2517 _archlist.append(myarch)
2518 _archlist.append("~" + myarch)
2521 def selinux_enabled(self):
2522 if getattr(self, "_selinux_enabled", None) is None:
2523 self._selinux_enabled = 0
2524 if "selinux" in self["USE"].split():
2526 if selinux.is_selinux_enabled() == 1:
2527 self._selinux_enabled = 1
2529 self._selinux_enabled = 0
2531 writemsg(_("!!! SELinux module not found. Please verify that it was installed.\n"),
2533 self._selinux_enabled = 0
2535 return self._selinux_enabled
2537 if sys.hexversion >= 0x3000000: