1ccaee7c8f7263b0a41fba19484bf8e32be59bbc
[portage.git] / pym / portage / package / ebuild / config.py
1 # Copyright 2010-2011 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3
4 __all__ = [
5         'autouse', 'best_from_dict', 'check_config_instance', 'config',
6 ]
7
8 import copy
9 from itertools import chain
10 import logging
11 import platform
12 import re
13 import sys
14 import warnings
15
16 from _emerge.Package import Package
17 import portage
18 portage.proxy.lazyimport.lazyimport(globals(),
19         'portage.data:portage_gid',
20 )
21 from portage import bsd_chflags, \
22         load_mod, os, selinux, _unicode_decode
23 from portage.const import CACHE_PATH, \
24         DEPCACHE_PATH, INCREMENTALS, MAKE_CONF_FILE, \
25         MODULES_FILE_PATH, \
26         PRIVATE_PATH, PROFILE_PATH, USER_CONFIG_PATH, \
27         USER_VIRTUALS_FILE
28 from portage.const import _SANDBOX_COMPAT_LEVEL
29 from portage.dbapi import dbapi
30 from portage.dbapi.porttree import portdbapi
31 from portage.dbapi.vartree import vartree
32 from portage.dep import Atom, isvalidatom, match_from_list, use_reduce, _repo_separator, _slot_separator
33 from portage.eapi import eapi_exports_AA, eapi_exports_merge_type, \
34         eapi_supports_prefix, eapi_exports_replace_vars
35 from portage.env.loaders import KeyValuePairFileLoader
36 from portage.exception import InvalidDependString, PortageException
37 from portage.localization import _
38 from portage.output import colorize
39 from portage.process import fakeroot_capable, sandbox_capable
40 from portage.repository.config import load_repository_config
41 from portage.util import ensure_dirs, getconfig, grabdict, \
42         grabdict_package, grabfile, grabfile_package, LazyItemsDict, \
43         normalize_path, shlex_split, stack_dictlist, stack_dicts, stack_lists, \
44         writemsg, writemsg_level
45 from portage.versions import catpkgsplit, catsplit, cpv_getkey
46
47 from portage.package.ebuild._config import special_env_vars
48 from portage.package.ebuild._config.env_var_validation import validate_cmd_var
49 from portage.package.ebuild._config.features_set import features_set
50 from portage.package.ebuild._config.KeywordsManager import KeywordsManager
51 from portage.package.ebuild._config.LicenseManager import LicenseManager
52 from portage.package.ebuild._config.UseManager import UseManager
53 from portage.package.ebuild._config.LocationsManager import LocationsManager
54 from portage.package.ebuild._config.MaskManager import MaskManager
55 from portage.package.ebuild._config.VirtualsManager import VirtualsManager
56 from portage.package.ebuild._config.helper import ordered_by_atom_specificity, prune_incremental
57
58 if sys.hexversion >= 0x3000000:
59         basestring = str
60
61 def autouse(myvartree, use_cache=1, mysettings=None):
62         warnings.warn("portage.autouse() is deprecated",
63                 DeprecationWarning, stacklevel=2)
64         return ""
65
66 def check_config_instance(test):
67         if not isinstance(test, config):
68                 raise TypeError("Invalid type for config object: %s (should be %s)" % (test.__class__, config))
69
70 def best_from_dict(key, top_dict, key_order, EmptyOnError=1, FullCopy=1, AllowEmpty=1):
71         for x in key_order:
72                 if x in top_dict and key in top_dict[x]:
73                         if FullCopy:
74                                 return copy.deepcopy(top_dict[x][key])
75                         else:
76                                 return top_dict[x][key]
77         if EmptyOnError:
78                 return ""
79         else:
80                 raise KeyError("Key not found in list; '%s'" % key)
81
82 def _lazy_iuse_regex(iuse_implicit):
83         """
84         The PORTAGE_IUSE value is lazily evaluated since re.escape() is slow
85         and the value is only used when an ebuild phase needs to be executed
86         (it's used only to generate QA notices).
87         """
88         # Escape anything except ".*" which is supposed to pass through from
89         # _get_implicit_iuse().
90         regex = sorted(re.escape(x) for x in iuse_implicit)
91         regex = "^(%s)$" % "|".join(regex)
92         regex = regex.replace("\\.\\*", ".*")
93         return regex
94
95 class _iuse_implicit_match_cache(object):
96
97         def __init__(self, settings):
98                 self._iuse_implicit_re = re.compile("^(%s)$" % \
99                         "|".join(settings._get_implicit_iuse()))
100                 self._cache = {}
101
102         def __call__(self, flag):
103                 """
104                 Returns True if the flag is matched, False otherwise.
105                 """
106                 try:
107                         return self._cache[flag]
108                 except KeyError:
109                         m = self._iuse_implicit_re.match(flag) is not None
110                         self._cache[flag] = m
111                         return m
112
113 class config(object):
114         """
115         This class encompasses the main portage configuration.  Data is pulled from
116         ROOT/PORTDIR/profiles/, from ROOT/etc/make.profile incrementally through all
117         parent profiles as well as from ROOT/PORTAGE_CONFIGROOT/* for user specified
118         overrides.
119
120         Generally if you need data like USE flags, FEATURES, environment variables,
121         virtuals ...etc you look in here.
122         """
123
124         _setcpv_aux_keys = ('DEFINED_PHASES', 'DEPEND', 'EAPI',
125                 'INHERITED', 'IUSE', 'REQUIRED_USE', 'KEYWORDS', 'LICENSE', 'PDEPEND',
126                 'PROPERTIES', 'PROVIDE', 'RDEPEND', 'SLOT',
127                 'repository', 'RESTRICT', 'LICENSE',)
128
129         _module_aliases = {
130                 "cache.metadata_overlay.database" : "portage.cache.flat_hash.database",
131                 "portage.cache.metadata_overlay.database" : "portage.cache.flat_hash.database",
132         }
133
134         _case_insensitive_vars = special_env_vars.case_insensitive_vars
135         _default_globals = special_env_vars.default_globals
136         _env_blacklist = special_env_vars.env_blacklist
137         _environ_filter = special_env_vars.environ_filter
138         _environ_whitelist = special_env_vars.environ_whitelist
139         _environ_whitelist_re = special_env_vars.environ_whitelist_re
140         _global_only_vars = special_env_vars.global_only_vars
141
142         def __init__(self, clone=None, mycpv=None, config_profile_path=None,
143                 config_incrementals=None, config_root=None, target_root=None,
144                 _eprefix=None, local_config=True, env=None, _unmatched_removal=False):
145                 """
146                 @param clone: If provided, init will use deepcopy to copy by value the instance.
147                 @type clone: Instance of config class.
148                 @param mycpv: CPV to load up (see setcpv), this is the same as calling init with mycpv=None
149                 and then calling instance.setcpv(mycpv).
150                 @type mycpv: String
151                 @param config_profile_path: Configurable path to the profile (usually PROFILE_PATH from portage.const)
152                 @type config_profile_path: String
153                 @param config_incrementals: List of incremental variables
154                         (defaults to portage.const.INCREMENTALS)
155                 @type config_incrementals: List
156                 @param config_root: path to read local config from (defaults to "/", see PORTAGE_CONFIGROOT)
157                 @type config_root: String
158                 @param target_root: __init__ override of $ROOT env variable.
159                 @type target_root: String
160                 @param _eprefix: set the EPREFIX variable (private, used by internal tests)
161                 @type _eprefix: String
162                 @param local_config: Enables loading of local config (/etc/portage); used most by repoman to
163                 ignore local config (keywording and unmasking)
164                 @type local_config: Boolean
165                 @param env: The calling environment which is used to override settings.
166                         Defaults to os.environ if unspecified.
167                 @type env: dict
168                 @param _unmatched_removal: Enabled by repoman when the
169                         --unmatched-removal option is given.
170                 @type _unmatched_removal: Boolean
171                 """
172
173                 # rename local _eprefix variable for convenience
174                 eprefix = _eprefix
175                 del _eprefix
176
177                 # When initializing the global portage.settings instance, avoid
178                 # raising exceptions whenever possible since exceptions thrown
179                 # from 'import portage' or 'import portage.exceptions' statements
180                 # can practically render the api unusable for api consumers.
181                 tolerant = hasattr(portage, '_initializing_globals')
182                 self._tolerant = tolerant
183
184                 self.locked   = 0
185                 self.mycpv    = None
186                 self._setcpv_args_hash = None
187                 self.puse     = ""
188                 self._penv    = []
189                 self.modifiedkeys = []
190                 self.uvlist = []
191                 self._accept_chost_re = None
192                 self._accept_properties = None
193                 self._features_overrides = []
194                 self._make_defaults = None
195
196                 # _unknown_features records unknown features that
197                 # have triggered warning messages, and ensures that
198                 # the same warning isn't shown twice.
199                 self._unknown_features = set()
200
201                 self.local_config = local_config
202
203                 if clone:
204                         # For immutable attributes, use shallow copy for
205                         # speed and memory conservation.
206                         self._tolerant = clone._tolerant
207                         self.categories = clone.categories
208                         self.depcachedir = clone.depcachedir
209                         self.incrementals = clone.incrementals
210                         self.module_priority = clone.module_priority
211                         self.profile_path = clone.profile_path
212                         self.profiles = clone.profiles
213                         self.packages = clone.packages
214                         self.repositories = clone.repositories
215                         self._iuse_implicit_match = clone._iuse_implicit_match
216                         self._non_user_variables = clone._non_user_variables
217                         self._env_d_blacklist = clone._env_d_blacklist
218                         self._repo_make_defaults = clone._repo_make_defaults
219                         self.usemask = clone.usemask
220                         self.useforce = clone.useforce
221                         self.puse = clone.puse
222                         self.user_profile_dir = clone.user_profile_dir
223                         self.local_config = clone.local_config
224                         self.make_defaults_use = clone.make_defaults_use
225                         self.mycpv = clone.mycpv
226                         self._setcpv_args_hash = clone._setcpv_args_hash
227
228                         # immutable attributes (internal policy ensures lack of mutation)
229                         self._keywords_manager = clone._keywords_manager
230                         self._use_manager = clone._use_manager
231                         self._mask_manager = clone._mask_manager
232
233                         # shared mutable attributes
234                         self._unknown_features = clone._unknown_features
235
236                         self.modules         = copy.deepcopy(clone.modules)
237                         self._penv = copy.deepcopy(clone._penv)
238
239                         self.configdict = copy.deepcopy(clone.configdict)
240                         self.configlist = [
241                                 self.configdict['env.d'],
242                                 self.configdict['repo'],
243                                 self.configdict['pkginternal'],
244                                 self.configdict['globals'],
245                                 self.configdict['defaults'],
246                                 self.configdict['conf'],
247                                 self.configdict['pkg'],
248                                 self.configdict['env'],
249                         ]
250                         self.lookuplist = self.configlist[:]
251                         self.lookuplist.reverse()
252                         self._use_expand_dict = copy.deepcopy(clone._use_expand_dict)
253                         self.backupenv  = self.configdict["backupenv"]
254                         self.prevmaskdict = copy.deepcopy(clone.prevmaskdict)
255                         self.pprovideddict = copy.deepcopy(clone.pprovideddict)
256                         self.features = features_set(self)
257                         self.features._features = copy.deepcopy(clone.features._features)
258                         self._features_overrides = copy.deepcopy(clone._features_overrides)
259
260                         #Strictly speaking _license_manager is not immutable. Users need to ensure that
261                         #extract_global_changes() is called right after __init__ (if at all).
262                         #It also has the mutable member _undef_lic_groups. It is used to track
263                         #undefined license groups, to not display an error message for the same
264                         #group again and again. Because of this, it's useful to share it between
265                         #all LicenseManager instances.
266                         self._license_manager = clone._license_manager
267
268                         self._virtuals_manager = copy.deepcopy(clone._virtuals_manager)
269
270                         self._accept_properties = copy.deepcopy(clone._accept_properties)
271                         self._ppropertiesdict = copy.deepcopy(clone._ppropertiesdict)
272                         self._penvdict = copy.deepcopy(clone._penvdict)
273                         self._expand_map = copy.deepcopy(clone._expand_map)
274
275                 else:
276                         locations_manager = LocationsManager(config_root=config_root,
277                                 config_profile_path=config_profile_path, eprefix=eprefix,
278                                 local_config=local_config, target_root=target_root)
279
280                         eprefix = locations_manager.eprefix
281                         config_root = locations_manager.config_root
282                         abs_user_config = locations_manager.abs_user_config
283
284                         make_conf = getconfig(
285                                 os.path.join(config_root, MAKE_CONF_FILE),
286                                 tolerant=tolerant, allow_sourcing=True) or {}
287
288                         make_conf.update(getconfig(
289                                 os.path.join(abs_user_config, 'make.conf'),
290                                 tolerant=tolerant, allow_sourcing=True,
291                                 expand=make_conf) or {})
292
293                         # Allow ROOT setting to come from make.conf if it's not overridden
294                         # by the constructor argument (from the calling environment).
295                         locations_manager.set_root_override(make_conf.get("ROOT"))
296                         target_root = locations_manager.target_root
297                         eroot = locations_manager.eroot
298                         self.global_config_path = locations_manager.global_config_path
299
300                         # The expand_map is used for variable substitution
301                         # in getconfig() calls, and the getconfig() calls
302                         # update expand_map with the value of each variable
303                         # assignment that occurs. Variable substitution occurs
304                         # in the following order, which corresponds to the
305                         # order of appearance in self.lookuplist:
306                         #
307                         #   * env.d
308                         #   * make.globals
309                         #   * make.defaults
310                         #   * make.conf
311                         #
312                         # Notably absent is "env", since we want to avoid any
313                         # interaction with the calling environment that might
314                         # lead to unexpected results.
315                         expand_map = {}
316                         self._expand_map = expand_map
317
318                         env_d = getconfig(os.path.join(eroot, "etc", "profile.env"),
319                                 expand=expand_map)
320
321                         make_globals = getconfig(os.path.join(
322                                 self.global_config_path, 'make.globals'), expand=expand_map)
323                         if make_globals is None:
324                                 make_globals = {}
325
326                         for k, v in self._default_globals.items():
327                                 make_globals.setdefault(k, v)
328
329                         if config_incrementals is None:
330                                 self.incrementals = INCREMENTALS
331                         else:
332                                 self.incrementals = config_incrementals
333                         if not isinstance(self.incrementals, frozenset):
334                                 self.incrementals = frozenset(self.incrementals)
335
336                         self.module_priority    = ("user", "default")
337                         self.modules            = {}
338                         modules_file = os.path.join(config_root, MODULES_FILE_PATH)
339                         modules_loader = KeyValuePairFileLoader(modules_file, None, None)
340                         modules_dict, modules_errors = modules_loader.load()
341                         self.modules["user"] = modules_dict
342                         if self.modules["user"] is None:
343                                 self.modules["user"] = {}
344                         user_auxdbmodule = \
345                                 self.modules["user"].get("portdbapi.auxdbmodule")
346                         if user_auxdbmodule is not None and \
347                                 user_auxdbmodule in self._module_aliases:
348                                 warnings.warn("'%s' is deprecated: %s" %
349                                 (user_auxdbmodule, modules_file))
350
351                         self.modules["default"] = {
352                                 "portdbapi.auxdbmodule":  "portage.cache.flat_hash.database",
353                         }
354
355                         self.configlist=[]
356
357                         # back up our incremental variables:
358                         self.configdict={}
359                         self._use_expand_dict = {}
360                         # configlist will contain: [ env.d, globals, defaults, conf, pkg, backupenv, env ]
361                         self.configlist.append({})
362                         self.configdict["env.d"] = self.configlist[-1]
363
364                         self.configlist.append({})
365                         self.configdict["repo"] = self.configlist[-1]
366
367                         self.configlist.append({})
368                         self.configdict["pkginternal"] = self.configlist[-1]
369
370                         # env_d will be None if profile.env doesn't exist.
371                         if env_d:
372                                 self.configdict["env.d"].update(env_d)
373
374                         # backupenv is used for calculating incremental variables.
375                         if env is None:
376                                 env = os.environ
377
378                         # Avoid potential UnicodeDecodeError exceptions later.
379                         env_unicode = dict((_unicode_decode(k), _unicode_decode(v))
380                                 for k, v in env.items())
381
382                         self.backupenv = env_unicode
383
384                         if env_d:
385                                 # Remove duplicate values so they don't override updated
386                                 # profile.env values later (profile.env is reloaded in each
387                                 # call to self.regenerate).
388                                 for k, v in env_d.items():
389                                         try:
390                                                 if self.backupenv[k] == v:
391                                                         del self.backupenv[k]
392                                         except KeyError:
393                                                 pass
394                                 del k, v
395
396                         self.configdict["env"] = LazyItemsDict(self.backupenv)
397
398                         self.configlist.append(make_globals)
399                         self.configdict["globals"]=self.configlist[-1]
400
401                         self.make_defaults_use = []
402
403                         known_repos = []
404                         for confs in [make_globals, make_conf, self.configdict["env"]]:
405                                 known_repos.extend(confs.get("PORTDIR", '').split())
406                                 known_repos.extend(confs.get("PORTDIR_OVERLAY", '').split())
407                         known_repos = frozenset(known_repos)
408
409                         locations_manager.load_profiles(known_repos)
410
411                         profiles_complex = locations_manager.profiles_complex
412                         self.profiles = locations_manager.profiles
413                         self.profile_path = locations_manager.profile_path
414                         self.user_profile_dir = locations_manager.user_profile_dir
415
416                         packages_list = [grabfile_package(os.path.join(x, "packages"),
417                                 verify_eapi=True) for x in self.profiles]
418                         self.packages = tuple(stack_lists(packages_list, incremental=1))
419
420                         # revmaskdict
421                         self.prevmaskdict={}
422                         for x in self.packages:
423                                 # Negative atoms are filtered by the above stack_lists() call.
424                                 if not isinstance(x, Atom):
425                                         x = Atom(x.lstrip('*'))
426                                 self.prevmaskdict.setdefault(x.cp, []).append(x)
427
428
429                         mygcfg = {}
430                         if self.profiles:
431                                 mygcfg_dlists = [getconfig(os.path.join(x, "make.defaults"),
432                                         expand=expand_map) for x in self.profiles]
433                                 self._make_defaults = mygcfg_dlists
434                                 mygcfg = stack_dicts(mygcfg_dlists,
435                                         incrementals=self.incrementals)
436                                 if mygcfg is None:
437                                         mygcfg = {}
438                         self.configlist.append(mygcfg)
439                         self.configdict["defaults"]=self.configlist[-1]
440
441                         mygcfg = getconfig(
442                                 os.path.join(config_root, MAKE_CONF_FILE),
443                                 tolerant=tolerant, allow_sourcing=True,
444                                 expand=expand_map) or {}
445
446                         mygcfg.update(getconfig(
447                                 os.path.join(abs_user_config, 'make.conf'),
448                                 tolerant=tolerant, allow_sourcing=True,
449                                 expand=expand_map) or {})
450
451                         # Don't allow the user to override certain variables in make.conf
452                         profile_only_variables = self.configdict["defaults"].get(
453                                 "PROFILE_ONLY_VARIABLES", "").split()
454                         profile_only_variables = stack_lists([profile_only_variables])
455                         non_user_variables = set()
456                         non_user_variables.update(profile_only_variables)
457                         non_user_variables.update(self._env_blacklist)
458                         non_user_variables.update(self._global_only_vars)
459                         non_user_variables = frozenset(non_user_variables)
460                         self._non_user_variables = non_user_variables
461
462                         self._env_d_blacklist = frozenset(chain(
463                                 profile_only_variables,
464                                 self._env_blacklist,
465                         ))
466                         env_d = self.configdict["env.d"]
467                         for k in self._env_d_blacklist:
468                                 env_d.pop(k, None)
469
470                         for k in profile_only_variables:
471                                 mygcfg.pop(k, None)
472
473                         self.configlist.append(mygcfg)
474                         self.configdict["conf"]=self.configlist[-1]
475
476                         self.configlist.append(LazyItemsDict())
477                         self.configdict["pkg"]=self.configlist[-1]
478
479                         self.configdict["backupenv"] = self.backupenv
480
481                         # Don't allow the user to override certain variables in the env
482                         for k in profile_only_variables:
483                                 self.backupenv.pop(k, None)
484
485                         self.configlist.append(self.configdict["env"])
486
487                         # make lookuplist for loading package.*
488                         self.lookuplist=self.configlist[:]
489                         self.lookuplist.reverse()
490
491                         # Blacklist vars that could interfere with portage internals.
492                         for blacklisted in self._env_blacklist:
493                                 for cfg in self.lookuplist:
494                                         cfg.pop(blacklisted, None)
495                                 self.backupenv.pop(blacklisted, None)
496                         del blacklisted, cfg
497
498                         self["PORTAGE_CONFIGROOT"] = config_root
499                         self.backup_changes("PORTAGE_CONFIGROOT")
500                         self["ROOT"] = target_root
501                         self.backup_changes("ROOT")
502
503                         self["EPREFIX"] = eprefix
504                         self.backup_changes("EPREFIX")
505                         self["EROOT"] = eroot
506                         self.backup_changes("EROOT")
507
508                         self["PORTAGE_SANDBOX_COMPAT_LEVEL"] = _SANDBOX_COMPAT_LEVEL
509                         self.backup_changes("PORTAGE_SANDBOX_COMPAT_LEVEL")
510
511                         self._ppropertiesdict = portage.dep.ExtendedAtomDict(dict)
512                         self._penvdict = portage.dep.ExtendedAtomDict(dict)
513
514                         #Loading Repositories
515                         self.repositories = load_repository_config(self)
516
517                         #filling PORTDIR and PORTDIR_OVERLAY variable for compatibility
518                         main_repo = self.repositories.mainRepo()
519                         if main_repo is not None:
520                                 main_repo = main_repo.user_location
521                                 self["PORTDIR"] = main_repo
522                                 self.backup_changes("PORTDIR")
523
524                         # repoman controls PORTDIR_OVERLAY via the environment, so no
525                         # special cases are needed here.
526                         portdir_overlay = list(self.repositories.repoUserLocationList())
527                         if portdir_overlay and portdir_overlay[0] == self["PORTDIR"]:
528                                 portdir_overlay = portdir_overlay[1:]
529
530                         new_ov = []
531                         if portdir_overlay:
532                                 shell_quote_re = re.compile(r"[\s\\\"'$`]")
533                                 for ov in portdir_overlay:
534                                         ov = normalize_path(ov)
535                                         if os.path.isdir(ov):
536                                                 if shell_quote_re.search(ov) is not None:
537                                                         ov = portage._shell_quote(ov)
538                                                 new_ov.append(ov)
539                                         else:
540                                                 writemsg(_("!!! Invalid PORTDIR_OVERLAY"
541                                                         " (not a dir): '%s'\n") % ov, noiselevel=-1)
542
543                         self["PORTDIR_OVERLAY"] = " ".join(new_ov)
544                         self.backup_changes("PORTDIR_OVERLAY")
545
546                         locations_manager.set_port_dirs(self["PORTDIR"], self["PORTDIR_OVERLAY"])
547
548                         self._repo_make_defaults = {}
549                         for repo in self.repositories.repos_with_profiles():
550                                 d = getconfig(os.path.join(repo.location, "profiles", "make.defaults"),
551                                         expand=self.configdict["globals"].copy()) or {}
552                                 if d:
553                                         for k in chain(self._env_blacklist,
554                                                 profile_only_variables, self._global_only_vars):
555                                                 d.pop(k, None)
556                                 self._repo_make_defaults[repo.name] = d
557
558                         #Read package.keywords and package.accept_keywords.
559                         self._keywords_manager = KeywordsManager(profiles_complex, abs_user_config, \
560                                 local_config, global_accept_keywords=self.configdict["defaults"].get("ACCEPT_KEYWORDS", ""))
561
562                         #Read all USE related files from profiles and optionally from user config.
563                         self._use_manager = UseManager(self.repositories, profiles_complex, abs_user_config, user_config=local_config)
564                         #Initialize all USE related variables we track ourselves.
565                         self.usemask = self._use_manager.getUseMask()
566                         self.useforce = self._use_manager.getUseForce()
567                         self.configdict["conf"]["USE"] = \
568                                 self._use_manager.extract_global_USE_changes( \
569                                         self.configdict["conf"].get("USE", ""))
570
571                         #Read license_groups and optionally license_groups and package.license from user config
572                         self._license_manager = LicenseManager(locations_manager.profile_locations, \
573                                 abs_user_config, user_config=local_config)
574                         #Extract '*/*' entries from package.license
575                         self.configdict["conf"]["ACCEPT_LICENSE"] = \
576                                 self._license_manager.extract_global_changes( \
577                                         self.configdict["conf"].get("ACCEPT_LICENSE", ""))
578
579                         #Read package.mask and package.unmask from profiles and optionally from user config
580                         self._mask_manager = MaskManager(self.repositories, profiles_complex,
581                                 abs_user_config, user_config=local_config,
582                                 strict_umatched_removal=_unmatched_removal)
583
584                         self._virtuals_manager = VirtualsManager(self.profiles)
585
586                         if local_config:
587                                 #package.properties
588                                 propdict = grabdict_package(os.path.join(
589                                         abs_user_config, "package.properties"), recursive=1, allow_wildcard=True, \
590                                         allow_repo=True, verify_eapi=False)
591                                 v = propdict.pop("*/*", None)
592                                 if v is not None:
593                                         if "ACCEPT_PROPERTIES" in self.configdict["conf"]:
594                                                 self.configdict["conf"]["ACCEPT_PROPERTIES"] += " " + " ".join(v)
595                                         else:
596                                                 self.configdict["conf"]["ACCEPT_PROPERTIES"] = " ".join(v)
597                                 for k, v in propdict.items():
598                                         self._ppropertiesdict.setdefault(k.cp, {})[k] = v
599
600                                 #package.env
601                                 penvdict = grabdict_package(os.path.join(
602                                         abs_user_config, "package.env"), recursive=1, allow_wildcard=True, \
603                                         allow_repo=True, verify_eapi=False)
604                                 v = penvdict.pop("*/*", None)
605                                 if v is not None:
606                                         global_wildcard_conf = {}
607                                         self._grab_pkg_env(v, global_wildcard_conf)
608                                         incrementals = self.incrementals
609                                         conf_configdict = self.configdict["conf"]
610                                         for k, v in global_wildcard_conf.items():
611                                                 if k in incrementals:
612                                                         if k in conf_configdict:
613                                                                 conf_configdict[k] = \
614                                                                         conf_configdict[k] + " " + v
615                                                         else:
616                                                                 conf_configdict[k] = v
617                                                 else:
618                                                         conf_configdict[k] = v
619                                                 expand_map[k] = v
620
621                                 for k, v in penvdict.items():
622                                         self._penvdict.setdefault(k.cp, {})[k] = v
623
624                         #getting categories from an external file now
625                         self.categories = [grabfile(os.path.join(x, "categories")) \
626                                 for x in locations_manager.profile_and_user_locations]
627                         category_re = dbapi._category_re
628                         # categories used to be a tuple, but now we use a frozenset
629                         # for hashed category validation in pordbapi.cp_list()
630                         self.categories = frozenset(
631                                 x for x in stack_lists(self.categories, incremental=1)
632                                 if category_re.match(x) is not None)
633
634                         archlist = [grabfile(os.path.join(x, "arch.list")) \
635                                 for x in locations_manager.profile_and_user_locations]
636                         archlist = stack_lists(archlist, incremental=1)
637                         self.configdict["conf"]["PORTAGE_ARCHLIST"] = " ".join(archlist)
638
639                         pkgprovidedlines = [grabfile(
640                                 os.path.join(x.location, "package.provided"),
641                                 recursive=x.portage1_directories)
642                                 for x in profiles_complex]
643                         pkgprovidedlines = stack_lists(pkgprovidedlines, incremental=1)
644                         has_invalid_data = False
645                         for x in range(len(pkgprovidedlines)-1, -1, -1):
646                                 myline = pkgprovidedlines[x]
647                                 if not isvalidatom("=" + myline):
648                                         writemsg(_("Invalid package name in package.provided: %s\n") % \
649                                                 myline, noiselevel=-1)
650                                         has_invalid_data = True
651                                         del pkgprovidedlines[x]
652                                         continue
653                                 cpvr = catpkgsplit(pkgprovidedlines[x])
654                                 if not cpvr or cpvr[0] == "null":
655                                         writemsg(_("Invalid package name in package.provided: ")+pkgprovidedlines[x]+"\n",
656                                                 noiselevel=-1)
657                                         has_invalid_data = True
658                                         del pkgprovidedlines[x]
659                                         continue
660                                 if cpvr[0] == "virtual":
661                                         writemsg(_("Virtual package in package.provided: %s\n") % \
662                                                 myline, noiselevel=-1)
663                                         has_invalid_data = True
664                                         del pkgprovidedlines[x]
665                                         continue
666                         if has_invalid_data:
667                                 writemsg(_("See portage(5) for correct package.provided usage.\n"),
668                                         noiselevel=-1)
669                         self.pprovideddict = {}
670                         for x in pkgprovidedlines:
671                                 x_split = catpkgsplit(x)
672                                 if x_split is None:
673                                         continue
674                                 mycatpkg = cpv_getkey(x)
675                                 if mycatpkg in self.pprovideddict:
676                                         self.pprovideddict[mycatpkg].append(x)
677                                 else:
678                                         self.pprovideddict[mycatpkg]=[x]
679
680                         # reasonable defaults; this is important as without USE_ORDER,
681                         # USE will always be "" (nothing set)!
682                         if "USE_ORDER" not in self:
683                                 self.backupenv["USE_ORDER"] = "env:pkg:conf:defaults:pkginternal:repo:env.d"
684
685                         self["PORTAGE_GID"] = str(portage_gid)
686                         self.backup_changes("PORTAGE_GID")
687
688                         self.depcachedir = DEPCACHE_PATH
689                         if eprefix:
690                                 # See comments about make.globals and EPREFIX
691                                 # above. DEPCACHE_PATH is similar.
692                                 if target_root == "/":
693                                         # case (1) above
694                                         self.depcachedir = os.path.join(eprefix,
695                                                 DEPCACHE_PATH.lstrip(os.sep))
696                                 else:
697                                         # case (2) above
698                                         # For now, just assume DEPCACHE_PATH is relative
699                                         # to EPREFIX.
700                                         # TODO: Pass in more info to the constructor,
701                                         # so we know the host system configuration.
702                                         self.depcachedir = os.path.join(eprefix,
703                                                 DEPCACHE_PATH.lstrip(os.sep))
704
705                         if self.get("PORTAGE_DEPCACHEDIR", None):
706                                 self.depcachedir = self["PORTAGE_DEPCACHEDIR"]
707                         self["PORTAGE_DEPCACHEDIR"] = self.depcachedir
708                         self.backup_changes("PORTAGE_DEPCACHEDIR")
709
710                         if "CBUILD" not in self and "CHOST" in self:
711                                 self["CBUILD"] = self["CHOST"]
712                                 self.backup_changes("CBUILD")
713
714                         if "USERLAND" not in self:
715                                 # Set default USERLAND so that our test cases can assume that
716                                 # it's always set. This allows isolated-functions.sh to avoid
717                                 # calling uname -s when sourced.
718                                 system = platform.system()
719                                 if system is not None and \
720                                         (system.endswith("BSD") or system == "DragonFly"):
721                                         self["USERLAND"] = "BSD"
722                                 else:
723                                         self["USERLAND"] = "GNU"
724                                 self.backup_changes("USERLAND")
725
726                         for var in ("PORTAGE_INST_UID", "PORTAGE_INST_GID"):
727                                 try:
728                                         self[var] = str(int(self.get(var, "0")))
729                                 except ValueError:
730                                         writemsg(_("!!! %s='%s' is not a valid integer.  "
731                                                 "Falling back to '0'.\n") % (var, self[var]),
732                                                 noiselevel=-1)
733                                         self[var] = "0"
734                                 self.backup_changes(var)
735
736                         # initialize self.features
737                         self.regenerate()
738
739                         if bsd_chflags:
740                                 self.features.add('chflags')
741
742                         if 'parse-eapi-ebuild-head' in self.features:
743                                 portage._validate_cache_for_unsupported_eapis = False
744
745                         self._iuse_implicit_match = _iuse_implicit_match_cache(self)
746
747                         self._validate_commands()
748
749                 for k in self._case_insensitive_vars:
750                         if k in self:
751                                 self[k] = self[k].lower()
752                                 self.backup_changes(k)
753
754                 if mycpv:
755                         self.setcpv(mycpv)
756
757         @property
758         def mygcfg(self):
759                 warnings.warn("portage.config.mygcfg is deprecated", stacklevel=3)
760                 return {}
761
762         def _validate_commands(self):
763                 for k in special_env_vars.validate_commands:
764                         v = self.get(k)
765                         if v is not None:
766                                 valid, v_split = validate_cmd_var(v)
767
768                                 if not valid:
769                                         if v_split:
770                                                 writemsg_level(_("%s setting is invalid: '%s'\n") % \
771                                                         (k, v), level=logging.ERROR, noiselevel=-1)
772
773                                         # before deleting the invalid setting, backup
774                                         # the default value if available
775                                         v = self.configdict['globals'].get(k)
776                                         if v is not None:
777                                                 default_valid, v_split = validate_cmd_var(v)
778                                                 if not default_valid:
779                                                         if v_split:
780                                                                 writemsg_level(
781                                                                         _("%s setting from make.globals" + \
782                                                                         " is invalid: '%s'\n") % \
783                                                                         (k, v), level=logging.ERROR, noiselevel=-1)
784                                                         # make.globals seems corrupt, so try for
785                                                         # a hardcoded default instead
786                                                         v = self._default_globals.get(k)
787
788                                         # delete all settings for this key,
789                                         # including the invalid one
790                                         del self[k]
791                                         self.backupenv.pop(k, None)
792                                         if v:
793                                                 # restore validated default
794                                                 self.configdict['globals'][k] = v
795
796         def _init_dirs(self):
797                 """
798                 Create a few directories that are critical to portage operation
799                 """
800                 if not os.access(self["EROOT"], os.W_OK):
801                         return
802
803                 #                                gid, mode, mask, preserve_perms
804                 dir_mode_map = {
805                         "tmp"             : (         -1, 0o1777,  0,  True),
806                         "var/tmp"         : (         -1, 0o1777,  0,  True),
807                         PRIVATE_PATH      : (portage_gid, 0o2750, 0o2, False),
808                         CACHE_PATH        : (portage_gid,  0o755, 0o2, False)
809                 }
810
811                 for mypath, (gid, mode, modemask, preserve_perms) \
812                         in dir_mode_map.items():
813                         mydir = os.path.join(self["EROOT"], mypath)
814                         if preserve_perms and os.path.isdir(mydir):
815                                 # Only adjust permissions on some directories if
816                                 # they don't exist yet. This gives freedom to the
817                                 # user to adjust permissions to suit their taste.
818                                 continue
819                         try:
820                                 ensure_dirs(mydir, gid=gid, mode=mode, mask=modemask)
821                         except PortageException as e:
822                                 writemsg(_("!!! Directory initialization failed: '%s'\n") % mydir,
823                                         noiselevel=-1)
824                                 writemsg("!!! %s\n" % str(e),
825                                         noiselevel=-1)
826
827         @property
828         def pkeywordsdict(self):
829                 result = self._keywords_manager.pkeywordsdict.copy()
830                 for k, v in result.items():
831                         result[k] = v.copy()
832                 return result
833
834         @property
835         def pmaskdict(self):
836                 return self._mask_manager._pmaskdict.copy()
837
838         @property
839         def punmaskdict(self):
840                 return self._mask_manager._punmaskdict.copy()
841
842         def expandLicenseTokens(self, tokens):
843                 """ Take a token from ACCEPT_LICENSE or package.license and expand it
844                 if it's a group token (indicated by @) or just return it if it's not a
845                 group.  If a group is negated then negate all group elements."""
846                 return self._license_manager.expandLicenseTokens(tokens)
847
848         def validate(self):
849                 """Validate miscellaneous settings and display warnings if necessary.
850                 (This code was previously in the global scope of portage.py)"""
851
852                 groups = self["ACCEPT_KEYWORDS"].split()
853                 archlist = self.archlist()
854                 if not archlist:
855                         writemsg(_("--- 'profiles/arch.list' is empty or "
856                                 "not available. Empty portage tree?\n"), noiselevel=1)
857                 else:
858                         for group in groups:
859                                 if group not in archlist and \
860                                         not (group.startswith("-") and group[1:] in archlist) and \
861                                         group not in ("*", "~*", "**"):
862                                         writemsg(_("!!! INVALID ACCEPT_KEYWORDS: %s\n") % str(group),
863                                                 noiselevel=-1)
864
865                 abs_profile_path = os.path.join(self["PORTAGE_CONFIGROOT"],
866                         PROFILE_PATH)
867                 if (not self.profile_path or \
868                         not os.path.exists(os.path.join(self.profile_path, "parent"))) and \
869                         os.path.exists(os.path.join(self["PORTDIR"], "profiles")):
870                         writemsg(_("\n\n!!! %s is not a symlink and will probably prevent most merges.\n") % abs_profile_path,
871                                 noiselevel=-1)
872                         writemsg(_("!!! It should point into a profile within %s/profiles/\n") % self["PORTDIR"])
873                         writemsg(_("!!! (You can safely ignore this message when syncing. It's harmless.)\n\n\n"))
874
875                 abs_user_virtuals = os.path.join(self["PORTAGE_CONFIGROOT"],
876                         USER_VIRTUALS_FILE)
877                 if os.path.exists(abs_user_virtuals):
878                         writemsg("\n!!! /etc/portage/virtuals is deprecated in favor of\n")
879                         writemsg("!!! /etc/portage/profile/virtuals. Please move it to\n")
880                         writemsg("!!! this new location.\n\n")
881
882                 if not sandbox_capable and \
883                         ("sandbox" in self.features or "usersandbox" in self.features):
884                         if self.profile_path is not None and \
885                                 os.path.realpath(self.profile_path) == \
886                                 os.path.realpath(os.path.join(
887                                 self["PORTAGE_CONFIGROOT"], PROFILE_PATH)):
888                                 # Don't show this warning when running repoman and the
889                                 # sandbox feature came from a profile that doesn't belong
890                                 # to the user.
891                                 writemsg(colorize("BAD", _("!!! Problem with sandbox"
892                                         " binary. Disabling...\n\n")), noiselevel=-1)
893
894                 if "fakeroot" in self.features and \
895                         not fakeroot_capable:
896                         writemsg(_("!!! FEATURES=fakeroot is enabled, but the "
897                                 "fakeroot binary is not installed.\n"), noiselevel=-1)
898
899         def load_best_module(self,property_string):
900                 best_mod = best_from_dict(property_string,self.modules,self.module_priority)
901                 mod = None
902                 try:
903                         mod = load_mod(best_mod)
904                 except ImportError:
905                         if best_mod in self._module_aliases:
906                                 mod = load_mod(self._module_aliases[best_mod])
907                         elif not best_mod.startswith("cache."):
908                                 raise
909                         else:
910                                 best_mod = "portage." + best_mod
911                                 try:
912                                         mod = load_mod(best_mod)
913                                 except ImportError:
914                                         raise
915                 return mod
916
917         def lock(self):
918                 self.locked = 1
919
920         def unlock(self):
921                 self.locked = 0
922
923         def modifying(self):
924                 if self.locked:
925                         raise Exception(_("Configuration is locked."))
926
927         def backup_changes(self,key=None):
928                 self.modifying()
929                 if key and key in self.configdict["env"]:
930                         self.backupenv[key] = copy.deepcopy(self.configdict["env"][key])
931                 else:
932                         raise KeyError(_("No such key defined in environment: %s") % key)
933
934         def reset(self, keeping_pkg=0, use_cache=None):
935                 """
936                 Restore environment from self.backupenv, call self.regenerate()
937                 @param keeping_pkg: Should we keep the setcpv() data or delete it.
938                 @type keeping_pkg: Boolean
939                 @rype: None
940                 """
941
942                 if use_cache is not None:
943                         warnings.warn("The use_cache parameter for config.reset() is deprecated and without effect.",
944                                 DeprecationWarning, stacklevel=2)
945
946                 self.modifying()
947                 self.configdict["env"].clear()
948                 self.configdict["env"].update(self.backupenv)
949
950                 self.modifiedkeys = []
951                 if not keeping_pkg:
952                         self.mycpv = None
953                         self._setcpv_args_hash = None
954                         self.puse = ""
955                         del self._penv[:]
956                         self.configdict["pkg"].clear()
957                         self.configdict["pkginternal"].clear()
958                         self.configdict["repo"].clear()
959                         self.configdict["defaults"]["USE"] = \
960                                 " ".join(self.make_defaults_use)
961                         self.usemask = self._use_manager.getUseMask()
962                         self.useforce = self._use_manager.getUseForce()
963                 self.regenerate()
964
965         class _lazy_vars(object):
966
967                 __slots__ = ('built_use', 'settings', 'values')
968
969                 def __init__(self, built_use, settings):
970                         self.built_use = built_use
971                         self.settings = settings
972                         self.values = None
973
974                 def __getitem__(self, k):
975                         if self.values is None:
976                                 self.values = self._init_values()
977                         return self.values[k]
978
979                 def _init_values(self):
980                         values = {}
981                         settings = self.settings
982                         use = self.built_use
983                         if use is None:
984                                 use = frozenset(settings['PORTAGE_USE'].split())
985
986                         values['ACCEPT_LICENSE'] = settings._license_manager.get_prunned_accept_license( \
987                                 settings.mycpv, use, settings['LICENSE'], settings['SLOT'], settings.get('PORTAGE_REPO_NAME'))
988                         values['PORTAGE_RESTRICT'] = self._restrict(use, settings)
989                         return values
990
991                 def _restrict(self, use, settings):
992                         try:
993                                 restrict = set(use_reduce(settings['RESTRICT'], uselist=use, flat=True))
994                         except InvalidDependString:
995                                 restrict = set()
996                         return ' '.join(sorted(restrict))
997
998         class _lazy_use_expand(object):
999                 """
1000                 Lazily evaluate USE_EXPAND variables since they are only needed when
1001                 an ebuild shell is spawned. Variables values are made consistent with
1002                 the previously calculated USE settings.
1003                 """
1004
1005                 def __init__(self, use, usemask, iuse_implicit,
1006                         use_expand_split, use_expand_dict):
1007                         self._use = use
1008                         self._usemask = usemask
1009                         self._iuse_implicit = iuse_implicit
1010                         self._use_expand_split = use_expand_split
1011                         self._use_expand_dict = use_expand_dict
1012
1013                 def __getitem__(self, key):
1014                         prefix = key.lower() + '_'
1015                         prefix_len = len(prefix)
1016                         expand_flags = set( x[prefix_len:] for x in self._use \
1017                                 if x[:prefix_len] == prefix )
1018                         var_split = self._use_expand_dict.get(key, '').split()
1019                         # Preserve the order of var_split because it can matter for things
1020                         # like LINGUAS.
1021                         var_split = [ x for x in var_split if x in expand_flags ]
1022                         var_split.extend(expand_flags.difference(var_split))
1023                         has_wildcard = '*' in expand_flags
1024                         if has_wildcard:
1025                                 var_split = [ x for x in var_split if x != "*" ]
1026                         has_iuse = set()
1027                         for x in self._iuse_implicit:
1028                                 if x[:prefix_len] == prefix:
1029                                         has_iuse.add(x[prefix_len:])
1030                         if has_wildcard:
1031                                 # * means to enable everything in IUSE that's not masked
1032                                 if has_iuse:
1033                                         usemask = self._usemask
1034                                         for suffix in has_iuse:
1035                                                 x = prefix + suffix
1036                                                 if x not in usemask:
1037                                                         if suffix not in expand_flags:
1038                                                                 var_split.append(suffix)
1039                                 else:
1040                                         # If there is a wildcard and no matching flags in IUSE then
1041                                         # LINGUAS should be unset so that all .mo files are
1042                                         # installed.
1043                                         var_split = []
1044                         # Make the flags unique and filter them according to IUSE.
1045                         # Also, continue to preserve order for things like LINGUAS
1046                         # and filter any duplicates that variable may contain.
1047                         filtered_var_split = []
1048                         remaining = has_iuse.intersection(var_split)
1049                         for x in var_split:
1050                                 if x in remaining:
1051                                         remaining.remove(x)
1052                                         filtered_var_split.append(x)
1053                         var_split = filtered_var_split
1054
1055                         if var_split:
1056                                 value = ' '.join(var_split)
1057                         else:
1058                                 # Don't export empty USE_EXPAND vars unless the user config
1059                                 # exports them as empty.  This is required for vars such as
1060                                 # LINGUAS, where unset and empty have different meanings.
1061                                 if has_wildcard:
1062                                         # ebuild.sh will see this and unset the variable so
1063                                         # that things like LINGUAS work properly
1064                                         value = '*'
1065                                 else:
1066                                         if has_iuse:
1067                                                 value = ''
1068                                         else:
1069                                                 # It's not in IUSE, so just allow the variable content
1070                                                 # to pass through if it is defined somewhere.  This
1071                                                 # allows packages that support LINGUAS but don't
1072                                                 # declare it in IUSE to use the variable outside of the
1073                                                 # USE_EXPAND context.
1074                                                 value = None
1075
1076                         return value
1077
1078         def setcpv(self, mycpv, use_cache=None, mydb=None):
1079                 """
1080                 Load a particular CPV into the config, this lets us see the
1081                 Default USE flags for a particular ebuild as well as the USE
1082                 flags from package.use.
1083
1084                 @param mycpv: A cpv to load
1085                 @type mycpv: string
1086                 @param mydb: a dbapi instance that supports aux_get with the IUSE key.
1087                 @type mydb: dbapi or derivative.
1088                 @rtype: None
1089                 """
1090
1091                 if use_cache is not None:
1092                         warnings.warn("The use_cache parameter for config.setcpv() is deprecated and without effect.",
1093                                 DeprecationWarning, stacklevel=2)
1094
1095                 self.modifying()
1096
1097                 pkg = None
1098                 built_use = None
1099                 explicit_iuse = None
1100                 if not isinstance(mycpv, basestring):
1101                         pkg = mycpv
1102                         mycpv = pkg.cpv
1103                         mydb = pkg.metadata
1104                         explicit_iuse = pkg.iuse.all
1105                         args_hash = (mycpv, id(pkg))
1106                         if pkg.built:
1107                                 built_use = pkg.use.enabled
1108                 else:
1109                         args_hash = (mycpv, id(mydb))
1110
1111                 if args_hash == self._setcpv_args_hash:
1112                         return
1113                 self._setcpv_args_hash = args_hash
1114
1115                 has_changed = False
1116                 self.mycpv = mycpv
1117                 cat, pf = catsplit(mycpv)
1118                 cp = cpv_getkey(mycpv)
1119                 cpv_slot = self.mycpv
1120                 pkginternaluse = ""
1121                 iuse = ""
1122                 pkg_configdict = self.configdict["pkg"]
1123                 previous_iuse = pkg_configdict.get("IUSE")
1124                 previous_features = pkg_configdict.get("FEATURES")
1125
1126                 aux_keys = self._setcpv_aux_keys
1127
1128                 # Discard any existing metadata and package.env settings from
1129                 # the previous package instance.
1130                 pkg_configdict.clear()
1131
1132                 pkg_configdict["CATEGORY"] = cat
1133                 pkg_configdict["PF"] = pf
1134                 repository = None
1135                 if mydb:
1136                         if not hasattr(mydb, "aux_get"):
1137                                 for k in aux_keys:
1138                                         if k in mydb:
1139                                                 # Make these lazy, since __getitem__ triggers
1140                                                 # evaluation of USE conditionals which can't
1141                                                 # occur until PORTAGE_USE is calculated below.
1142                                                 pkg_configdict.addLazySingleton(k,
1143                                                         mydb.__getitem__, k)
1144                         else:
1145                                 # When calling dbapi.aux_get(), grab USE for built/installed
1146                                 # packages since we want to save it PORTAGE_BUILT_USE for
1147                                 # evaluating conditional USE deps in atoms passed via IPC to
1148                                 # helpers like has_version and best_version.
1149                                 aux_keys = list(aux_keys)
1150                                 aux_keys.append('USE')
1151                                 for k, v in zip(aux_keys, mydb.aux_get(self.mycpv, aux_keys)):
1152                                         pkg_configdict[k] = v
1153                                 built_use = frozenset(pkg_configdict.pop('USE').split())
1154                                 if not built_use:
1155                                         # Empty USE means this dbapi instance does not contain
1156                                         # built packages.
1157                                         built_use = None
1158
1159                         repository = pkg_configdict.pop("repository", None)
1160                         if repository is not None:
1161                                 pkg_configdict["PORTAGE_REPO_NAME"] = repository
1162                         slot = pkg_configdict["SLOT"]
1163                         iuse = pkg_configdict["IUSE"]
1164                         if pkg is None:
1165                                 cpv_slot = "%s:%s" % (self.mycpv, slot)
1166                         else:
1167                                 cpv_slot = pkg
1168                         pkginternaluse = []
1169                         for x in iuse.split():
1170                                 if x.startswith("+"):
1171                                         pkginternaluse.append(x[1:])
1172                                 elif x.startswith("-"):
1173                                         pkginternaluse.append(x)
1174                         pkginternaluse = " ".join(pkginternaluse)
1175                 if pkginternaluse != self.configdict["pkginternal"].get("USE", ""):
1176                         self.configdict["pkginternal"]["USE"] = pkginternaluse
1177                         has_changed = True
1178
1179                 repo_env = []
1180                 if repository and repository != Package.UNKNOWN_REPO:
1181                         repos = []
1182                         try:
1183                                 repos.extend(repo.name for repo in
1184                                         self.repositories[repository].masters)
1185                         except KeyError:
1186                                 pass
1187                         repos.append(repository)
1188                         for repo in repos:
1189                                 d = self._repo_make_defaults.get(repo)
1190                                 if d is None:
1191                                         d = {}
1192                                 else:
1193                                         # make a copy, since we might modify it with
1194                                         # package.use settings
1195                                         d = d.copy()
1196                                 cpdict = self._use_manager._repo_puse_dict.get(repo, {}).get(cp)
1197                                 if cpdict:
1198                                         repo_puse = ordered_by_atom_specificity(cpdict, cpv_slot)
1199                                         if repo_puse:
1200                                                 for x in repo_puse:
1201                                                         d["USE"] = d.get("USE", "") + " " + " ".join(x)
1202                                 if d:
1203                                         repo_env.append(d)
1204
1205                 if repo_env or self.configdict["repo"]:
1206                         self.configdict["repo"].clear()
1207                         self.configdict["repo"].update(stack_dicts(repo_env,
1208                                 incrementals=self.incrementals))
1209                         has_changed = True
1210
1211                 defaults = []
1212                 for i, pkgprofileuse_dict in enumerate(self._use_manager._pkgprofileuse):
1213                         if self.make_defaults_use[i]:
1214                                 defaults.append(self.make_defaults_use[i])
1215                         cpdict = pkgprofileuse_dict.get(cp)
1216                         if cpdict:
1217                                 pkg_defaults = ordered_by_atom_specificity(cpdict, cpv_slot)
1218                                 if pkg_defaults:
1219                                         defaults.extend(pkg_defaults)
1220                 defaults = " ".join(defaults)
1221                 if defaults != self.configdict["defaults"].get("USE",""):
1222                         self.configdict["defaults"]["USE"] = defaults
1223                         has_changed = True
1224
1225                 useforce = self._use_manager.getUseForce(cpv_slot)
1226                 if useforce != self.useforce:
1227                         self.useforce = useforce
1228                         has_changed = True
1229
1230                 usemask = self._use_manager.getUseMask(cpv_slot)
1231                 if usemask != self.usemask:
1232                         self.usemask = usemask
1233                         has_changed = True
1234
1235                 oldpuse = self.puse
1236                 self.puse = self._use_manager.getPUSE(cpv_slot)
1237                 if oldpuse != self.puse:
1238                         has_changed = True
1239                 self.configdict["pkg"]["PKGUSE"] = self.puse[:] # For saving to PUSE file
1240                 self.configdict["pkg"]["USE"]    = self.puse[:] # this gets appended to USE
1241
1242                 if previous_features:
1243                         # The package from the previous setcpv call had package.env
1244                         # settings which modified FEATURES. Therefore, trigger a
1245                         # regenerate() call in order to ensure that self.features
1246                         # is accurate.
1247                         has_changed = True
1248
1249                 self._penv = []
1250                 cpdict = self._penvdict.get(cp)
1251                 if cpdict:
1252                         penv_matches = ordered_by_atom_specificity(cpdict, cpv_slot)
1253                         if penv_matches:
1254                                 for x in penv_matches:
1255                                         self._penv.extend(x)
1256
1257                 protected_pkg_keys = set(pkg_configdict)
1258                 protected_pkg_keys.discard('USE')
1259
1260                 # If there are _any_ package.env settings for this package
1261                 # then it automatically triggers config.reset(), in order
1262                 # to account for possible incremental interaction between
1263                 # package.use, package.env, and overrides from the calling
1264                 # environment (configdict['env']).
1265                 if self._penv:
1266                         has_changed = True
1267                         # USE is special because package.use settings override
1268                         # it. Discard any package.use settings here and they'll
1269                         # be added back later.
1270                         pkg_configdict.pop('USE', None)
1271                         self._grab_pkg_env(self._penv, pkg_configdict,
1272                                 protected_keys=protected_pkg_keys)
1273
1274                         # Now add package.use settings, which override USE from
1275                         # package.env
1276                         if self.puse:
1277                                 if 'USE' in pkg_configdict:
1278                                         pkg_configdict['USE'] = \
1279                                                 pkg_configdict['USE'] + " " + self.puse
1280                                 else:
1281                                         pkg_configdict['USE'] = self.puse
1282
1283                 if has_changed:
1284                         self.reset(keeping_pkg=1)
1285
1286                 env_configdict = self.configdict['env']
1287
1288                 # Ensure that "pkg" values are always preferred over "env" values.
1289                 # This must occur _after_ the above reset() call, since reset()
1290                 # copies values from self.backupenv.
1291                 for k in protected_pkg_keys:
1292                         env_configdict.pop(k, None)
1293
1294                 lazy_vars = self._lazy_vars(built_use, self)
1295                 env_configdict.addLazySingleton('ACCEPT_LICENSE',
1296                         lazy_vars.__getitem__, 'ACCEPT_LICENSE')
1297                 env_configdict.addLazySingleton('PORTAGE_RESTRICT',
1298                         lazy_vars.__getitem__, 'PORTAGE_RESTRICT')
1299
1300                 if built_use is not None:
1301                         pkg_configdict['PORTAGE_BUILT_USE'] = ' '.join(built_use)
1302
1303                 # If reset() has not been called, it's safe to return
1304                 # early if IUSE has not changed.
1305                 if not has_changed and previous_iuse == iuse:
1306                         return
1307
1308                 # Filter out USE flags that aren't part of IUSE. This has to
1309                 # be done for every setcpv() call since practically every
1310                 # package has different IUSE.
1311                 use = set(self["USE"].split())
1312                 if explicit_iuse is None:
1313                         explicit_iuse = frozenset(x.lstrip("+-") for x in iuse.split())
1314                 iuse_implicit_match = self._iuse_implicit_match
1315                 portage_iuse = self._get_implicit_iuse()
1316                 portage_iuse.update(explicit_iuse)
1317
1318                 # PORTAGE_IUSE is not always needed so it's lazily evaluated.
1319                 self.configdict["env"].addLazySingleton(
1320                         "PORTAGE_IUSE", _lazy_iuse_regex, portage_iuse)
1321
1322                 ebuild_force_test = self.get("EBUILD_FORCE_TEST") == "1"
1323                 if ebuild_force_test and \
1324                         not hasattr(self, "_ebuild_force_test_msg_shown"):
1325                                 self._ebuild_force_test_msg_shown = True
1326                                 writemsg(_("Forcing test.\n"), noiselevel=-1)
1327                 if "test" in self.features:
1328                         if "test" in self.usemask and not ebuild_force_test:
1329                                 # "test" is in IUSE and USE=test is masked, so execution
1330                                 # of src_test() probably is not reliable. Therefore,
1331                                 # temporarily disable FEATURES=test just for this package.
1332                                 self["FEATURES"] = " ".join(x for x in self.features \
1333                                         if x != "test")
1334                                 use.discard("test")
1335                         else:
1336                                 use.add("test")
1337                                 if ebuild_force_test and "test" in self.usemask:
1338                                         self.usemask = \
1339                                                 frozenset(x for x in self.usemask if x != "test")
1340
1341                 # Allow _* flags from USE_EXPAND wildcards to pass through here.
1342                 use.difference_update([x for x in use \
1343                         if (x not in explicit_iuse and \
1344                         not iuse_implicit_match(x)) and x[-2:] != '_*'])
1345
1346                 # Use the calculated USE flags to regenerate the USE_EXPAND flags so
1347                 # that they are consistent. For optimal performance, use slice
1348                 # comparison instead of startswith().
1349                 use_expand_split = set(x.lower() for \
1350                         x in self.get('USE_EXPAND', '').split())
1351                 lazy_use_expand = self._lazy_use_expand(use, self.usemask,
1352                         portage_iuse, use_expand_split, self._use_expand_dict)
1353
1354                 use_expand_iuses = {}
1355                 for x in portage_iuse:
1356                         x_split = x.split('_')
1357                         if len(x_split) == 1:
1358                                 continue
1359                         for i in range(len(x_split) - 1):
1360                                 k = '_'.join(x_split[:i+1])
1361                                 if k in use_expand_split:
1362                                         v = use_expand_iuses.get(k)
1363                                         if v is None:
1364                                                 v = set()
1365                                                 use_expand_iuses[k] = v
1366                                         v.add(x)
1367                                         break
1368
1369                 # If it's not in IUSE, variable content is allowed
1370                 # to pass through if it is defined somewhere.  This
1371                 # allows packages that support LINGUAS but don't
1372                 # declare it in IUSE to use the variable outside of the
1373                 # USE_EXPAND context.
1374                 for k, use_expand_iuse in use_expand_iuses.items():
1375                         if k + '_*' in use:
1376                                 use.update( x for x in use_expand_iuse if x not in usemask )
1377                         k = k.upper()
1378                         self.configdict['env'].addLazySingleton(k,
1379                                 lazy_use_expand.__getitem__, k)
1380
1381                 # Filtered for the ebuild environment. Store this in a separate
1382                 # attribute since we still want to be able to see global USE
1383                 # settings for things like emerge --info.
1384
1385                 self.configdict["env"]["PORTAGE_USE"] = \
1386                         " ".join(sorted(x for x in use if x[-2:] != '_*'))
1387
1388         def _grab_pkg_env(self, penv, container, protected_keys=None):
1389                 if protected_keys is None:
1390                         protected_keys = ()
1391                 abs_user_config = os.path.join(
1392                         self['PORTAGE_CONFIGROOT'], USER_CONFIG_PATH)
1393                 non_user_variables = self._non_user_variables
1394                 # Make a copy since we don't want per-package settings
1395                 # to pollute the global expand_map.
1396                 expand_map = self._expand_map.copy()
1397                 incrementals = self.incrementals
1398                 for envname in penv:
1399                         penvfile = os.path.join(abs_user_config, "env", envname)
1400                         penvconfig = getconfig(penvfile, tolerant=self._tolerant,
1401                                 allow_sourcing=True, expand=expand_map)
1402                         if penvconfig is None:
1403                                 writemsg("!!! %s references non-existent file: %s\n" % \
1404                                         (os.path.join(abs_user_config, 'package.env'), penvfile),
1405                                         noiselevel=-1)
1406                         else:
1407                                 for k, v in penvconfig.items():
1408                                         if k in protected_keys or \
1409                                                 k in non_user_variables:
1410                                                 writemsg("!!! Illegal variable " + \
1411                                                         "'%s' assigned in '%s'\n" % \
1412                                                         (k, penvfile), noiselevel=-1)
1413                                         elif k in incrementals:
1414                                                 if k in container:
1415                                                         container[k] = container[k] + " " + v
1416                                                 else:
1417                                                         container[k] = v
1418                                         else:
1419                                                 container[k] = v
1420
1421         def _get_implicit_iuse(self):
1422                 """
1423                 Some flags are considered to
1424                 be implicit members of IUSE:
1425                   * Flags derived from ARCH
1426                   * Flags derived from USE_EXPAND_HIDDEN variables
1427                   * Masked flags, such as those from {,package}use.mask
1428                   * Forced flags, such as those from {,package}use.force
1429                   * build and bootstrap flags used by bootstrap.sh
1430                 """
1431                 iuse_implicit = set()
1432                 # Flags derived from ARCH.
1433                 arch = self.configdict["defaults"].get("ARCH")
1434                 if arch:
1435                         iuse_implicit.add(arch)
1436                 iuse_implicit.update(self.get("PORTAGE_ARCHLIST", "").split())
1437
1438                 # Flags derived from USE_EXPAND_HIDDEN variables
1439                 # such as ELIBC, KERNEL, and USERLAND.
1440                 use_expand_hidden = self.get("USE_EXPAND_HIDDEN", "").split()
1441                 for x in use_expand_hidden:
1442                         iuse_implicit.add(x.lower() + "_.*")
1443
1444                 # Flags that have been masked or forced.
1445                 iuse_implicit.update(self.usemask)
1446                 iuse_implicit.update(self.useforce)
1447
1448                 # build and bootstrap flags used by bootstrap.sh
1449                 iuse_implicit.add("build")
1450                 iuse_implicit.add("bootstrap")
1451
1452                 # Controlled by FEATURES=test. Make this implicit, so handling
1453                 # of FEATURES=test is consistent regardless of explicit IUSE.
1454                 # Users may use use.mask/package.use.mask to control
1455                 # FEATURES=test for all ebuilds, regardless of explicit IUSE.
1456                 iuse_implicit.add("test")
1457
1458                 return iuse_implicit
1459
1460         def _getUseMask(self, pkg):
1461                 return self._use_manager.getUseMask(pkg)
1462
1463         def _getUseForce(self, pkg):
1464                 return self._use_manager.getUseForce(pkg)
1465
1466         def _getMaskAtom(self, cpv, metadata):
1467                 """
1468                 Take a package and return a matching package.mask atom, or None if no
1469                 such atom exists or it has been cancelled by package.unmask. PROVIDE
1470                 is not checked, so atoms will not be found for old-style virtuals.
1471
1472                 @param cpv: The package name
1473                 @type cpv: String
1474                 @param metadata: A dictionary of raw package metadata
1475                 @type metadata: dict
1476                 @rtype: String
1477                 @return: A matching atom string or None if one is not found.
1478                 """
1479                 return self._mask_manager.getMaskAtom(cpv, metadata["SLOT"], metadata.get('repository'))
1480
1481         def _getRawMaskAtom(self, cpv, metadata):
1482                 """
1483                 Take a package and return a matching package.mask atom, or None if no
1484                 such atom exists or it has been cancelled by package.unmask. PROVIDE
1485                 is not checked, so atoms will not be found for old-style virtuals.
1486
1487                 @param cpv: The package name
1488                 @type cpv: String
1489                 @param metadata: A dictionary of raw package metadata
1490                 @type metadata: dict
1491                 @rtype: String
1492                 @return: A matching atom string or None if one is not found.
1493                 """
1494                 return self._mask_manager.getRawMaskAtom(cpv, metadata["SLOT"], metadata.get('repository'))
1495
1496
1497         def _getProfileMaskAtom(self, cpv, metadata):
1498                 """
1499                 Take a package and return a matching profile atom, or None if no
1500                 such atom exists. Note that a profile atom may or may not have a "*"
1501                 prefix. PROVIDE is not checked, so atoms will not be found for
1502                 old-style virtuals.
1503
1504                 @param cpv: The package name
1505                 @type cpv: String
1506                 @param metadata: A dictionary of raw package metadata
1507                 @type metadata: dict
1508                 @rtype: String
1509                 @return: A matching profile atom string or None if one is not found.
1510                 """
1511
1512                 warnings.warn("The config._getProfileMaskAtom() method is deprecated.",
1513                         DeprecationWarning, stacklevel=2)
1514
1515                 cp = cpv_getkey(cpv)
1516                 profile_atoms = self.prevmaskdict.get(cp)
1517                 if profile_atoms:
1518                         pkg = "".join((cpv, _slot_separator, metadata["SLOT"]))
1519                         repo = metadata.get("repository")
1520                         if repo and repo != Package.UNKNOWN_REPO:
1521                                 pkg = "".join((pkg, _repo_separator, repo))
1522                         pkg_list = [pkg]
1523                         for x in profile_atoms:
1524                                 if match_from_list(x, pkg_list):
1525                                         continue
1526                                 return x
1527                 return None
1528
1529         def _getKeywords(self, cpv, metadata):
1530                 return self._keywords_manager.getKeywords(cpv, metadata["SLOT"], \
1531                         metadata.get("KEYWORDS", ""), metadata.get("repository"))
1532
1533         def _getMissingKeywords(self, cpv, metadata):
1534                 """
1535                 Take a package and return a list of any KEYWORDS that the user may
1536                 need to accept for the given package. If the KEYWORDS are empty
1537                 and the the ** keyword has not been accepted, the returned list will
1538                 contain ** alone (in order to distinguish from the case of "none
1539                 missing").
1540
1541                 @param cpv: The package name (for package.keywords support)
1542                 @type cpv: String
1543                 @param metadata: A dictionary of raw package metadata
1544                 @type metadata: dict
1545                 @rtype: List
1546                 @return: A list of KEYWORDS that have not been accepted.
1547                 """
1548
1549                 # Hack: Need to check the env directly here as otherwise stacking
1550                 # doesn't work properly as negative values are lost in the config
1551                 # object (bug #139600)
1552                 backuped_accept_keywords = self.configdict["backupenv"].get("ACCEPT_KEYWORDS", "")
1553                 global_accept_keywords = self["ACCEPT_KEYWORDS"]
1554
1555                 return self._keywords_manager.getMissingKeywords(cpv, metadata["SLOT"], \
1556                         metadata.get("KEYWORDS", ""), metadata.get('repository'), \
1557                         global_accept_keywords, backuped_accept_keywords)
1558
1559         def _getRawMissingKeywords(self, cpv, metadata):
1560                 """
1561                 Take a package and return a list of any KEYWORDS that the user may
1562                 need to accept for the given package. If the KEYWORDS are empty,
1563                 the returned list will contain ** alone (in order to distinguish
1564                 from the case of "none missing").  This DOES NOT apply any user config
1565                 package.accept_keywords acceptance.
1566
1567                 @param cpv: The package name (for package.keywords support)
1568                 @type cpv: String
1569                 @param metadata: A dictionary of raw package metadata
1570                 @type metadata: dict
1571                 @rtype: List
1572                 @return: lists of KEYWORDS that have not been accepted
1573                 and the keywords it looked for.
1574                 """
1575                 return self._keywords_manager.getRawMissingKeywords(cpv, metadata["SLOT"], \
1576                         metadata.get("KEYWORDS", ""), metadata.get('repository'), \
1577                         self.get("ACCEPT_KEYWORDS", ""))
1578
1579         def _getPKeywords(self, cpv, metadata):
1580                 global_accept_keywords = self.get("ACCEPT_KEYWORDS", "")
1581
1582                 return self._keywords_manager.getPKeywords(cpv, metadata["SLOT"], \
1583                         metadata.get('repository'), global_accept_keywords)
1584
1585         def _getMissingLicenses(self, cpv, metadata):
1586                 """
1587                 Take a LICENSE string and return a list of any licenses that the user
1588                 may need to accept for the given package.  The returned list will not
1589                 contain any licenses that have already been accepted.  This method
1590                 can throw an InvalidDependString exception.
1591
1592                 @param cpv: The package name (for package.license support)
1593                 @type cpv: String
1594                 @param metadata: A dictionary of raw package metadata
1595                 @type metadata: dict
1596                 @rtype: List
1597                 @return: A list of licenses that have not been accepted.
1598                 """
1599                 return self._license_manager.getMissingLicenses( \
1600                         cpv, metadata["USE"], metadata["LICENSE"], metadata["SLOT"], metadata.get('repository'))
1601
1602         def _getMissingProperties(self, cpv, metadata):
1603                 """
1604                 Take a PROPERTIES string and return a list of any properties the user
1605                 may need to accept for the given package.  The returned list will not
1606                 contain any properties that have already been accepted.  This method
1607                 can throw an InvalidDependString exception.
1608
1609                 @param cpv: The package name (for package.properties support)
1610                 @type cpv: String
1611                 @param metadata: A dictionary of raw package metadata
1612                 @type metadata: dict
1613                 @rtype: List
1614                 @return: A list of properties that have not been accepted.
1615                 """
1616                 accept_properties = self._accept_properties
1617                 cp = cpv_getkey(cpv)
1618                 cpdict = self._ppropertiesdict.get(cp)
1619                 if cpdict:
1620                         cpv_slot = "%s:%s" % (cpv, metadata["SLOT"])
1621                         pproperties_list = ordered_by_atom_specificity(cpdict, cpv_slot, repo=metadata.get('repository'))
1622                         if pproperties_list:
1623                                 accept_properties = list(self._accept_properties)
1624                                 for x in pproperties_list:
1625                                         accept_properties.extend(x)
1626
1627                 properties_str = metadata.get("PROPERTIES", "")
1628                 properties = set(use_reduce(properties_str, matchall=1, flat=True))
1629                 properties.discard('||')
1630
1631                 acceptable_properties = set()
1632                 for x in accept_properties:
1633                         if x == '*':
1634                                 acceptable_properties.update(properties)
1635                         elif x == '-*':
1636                                 acceptable_properties.clear()
1637                         elif x[:1] == '-':
1638                                 acceptable_properties.discard(x[1:])
1639                         else:
1640                                 acceptable_properties.add(x)
1641
1642                 if "?" in properties_str:
1643                         use = metadata["USE"].split()
1644                 else:
1645                         use = []
1646
1647                 properties_struct = use_reduce(properties_str, uselist=use, opconvert=True)
1648                 return self._getMaskedProperties(properties_struct, acceptable_properties)
1649
1650         def _getMaskedProperties(self, properties_struct, acceptable_properties):
1651                 if not properties_struct:
1652                         return []
1653                 if properties_struct[0] == "||":
1654                         ret = []
1655                         for element in properties_struct[1:]:
1656                                 if isinstance(element, list):
1657                                         if element:
1658                                                 tmp = self._getMaskedProperties(
1659                                                         element, acceptable_properties)
1660                                                 if not tmp:
1661                                                         return []
1662                                                 ret.extend(tmp)
1663                                 else:
1664                                         if element in acceptable_properties:
1665                                                 return[]
1666                                         ret.append(element)
1667                         # Return all masked properties, since we don't know which combination
1668                         # (if any) the user will decide to unmask
1669                         return ret
1670
1671                 ret = []
1672                 for element in properties_struct:
1673                         if isinstance(element, list):
1674                                 if element:
1675                                         ret.extend(self._getMaskedProperties(element,
1676                                                 acceptable_properties))
1677                         else:
1678                                 if element not in acceptable_properties:
1679                                         ret.append(element)
1680                 return ret
1681
1682         def _accept_chost(self, cpv, metadata):
1683                 """
1684                 @return True if pkg CHOST is accepted, False otherwise.
1685                 """
1686                 if self._accept_chost_re is None:
1687                         accept_chost = self.get("ACCEPT_CHOSTS", "").split()
1688                         if not accept_chost:
1689                                 chost = self.get("CHOST")
1690                                 if chost:
1691                                         accept_chost.append(chost)
1692                         if not accept_chost:
1693                                 self._accept_chost_re = re.compile(".*")
1694                         elif len(accept_chost) == 1:
1695                                 try:
1696                                         self._accept_chost_re = re.compile(r'^%s$' % accept_chost[0])
1697                                 except re.error as e:
1698                                         writemsg(_("!!! Invalid ACCEPT_CHOSTS value: '%s': %s\n") % \
1699                                                 (accept_chost[0], e), noiselevel=-1)
1700                                         self._accept_chost_re = re.compile("^$")
1701                         else:
1702                                 try:
1703                                         self._accept_chost_re = re.compile(
1704                                                 r'^(%s)$' % "|".join(accept_chost))
1705                                 except re.error as e:
1706                                         writemsg(_("!!! Invalid ACCEPT_CHOSTS value: '%s': %s\n") % \
1707                                                 (" ".join(accept_chost), e), noiselevel=-1)
1708                                         self._accept_chost_re = re.compile("^$")
1709
1710                 pkg_chost = metadata.get('CHOST', '')
1711                 return not pkg_chost or \
1712                         self._accept_chost_re.match(pkg_chost) is not None
1713
1714         def setinst(self, mycpv, mydbapi):
1715                 """This updates the preferences for old-style virtuals,
1716                 affecting the behavior of dep_expand() and dep_check()
1717                 calls. It can change dbapi.match() behavior since that
1718                 calls dep_expand(). However, dbapi instances have
1719                 internal match caches that are not invalidated when
1720                 preferences are updated here. This can potentially
1721                 lead to some inconsistency (relevant to bug #1343)."""
1722                 self.modifying()
1723
1724                 # Grab the virtuals this package provides and add them into the tree virtuals.
1725                 if not hasattr(mydbapi, "aux_get"):
1726                         provides = mydbapi["PROVIDE"]
1727                 else:
1728                         provides = mydbapi.aux_get(mycpv, ["PROVIDE"])[0]
1729                 if not provides:
1730                         return
1731                 if isinstance(mydbapi, portdbapi):
1732                         self.setcpv(mycpv, mydb=mydbapi)
1733                         myuse = self["PORTAGE_USE"]
1734                 elif not hasattr(mydbapi, "aux_get"):
1735                         myuse = mydbapi["USE"]
1736                 else:
1737                         myuse = mydbapi.aux_get(mycpv, ["USE"])[0]
1738                 virts = use_reduce(provides, uselist=myuse.split(), flat=True)
1739
1740                 # Ensure that we don't trigger the _treeVirtuals
1741                 # assertion in VirtualsManager._compile_virtuals().
1742                 self.getvirtuals()
1743                 self._virtuals_manager.add_depgraph_virtuals(mycpv, virts)
1744
1745         def reload(self):
1746                 """Reload things like /etc/profile.env that can change during runtime."""
1747                 env_d_filename = os.path.join(self["EROOT"], "etc", "profile.env")
1748                 self.configdict["env.d"].clear()
1749                 env_d = getconfig(env_d_filename, expand=False)
1750                 if env_d:
1751                         # env_d will be None if profile.env doesn't exist.
1752                         for k in self._env_d_blacklist:
1753                                 env_d.pop(k, None)
1754                         self.configdict["env.d"].update(env_d)
1755
1756         def regenerate(self, useonly=0, use_cache=None):
1757                 """
1758                 Regenerate settings
1759                 This involves regenerating valid USE flags, re-expanding USE_EXPAND flags
1760                 re-stacking USE flags (-flag and -*), as well as any other INCREMENTAL
1761                 variables.  This also updates the env.d configdict; useful in case an ebuild
1762                 changes the environment.
1763
1764                 If FEATURES has already stacked, it is not stacked twice.
1765
1766                 @param useonly: Only regenerate USE flags (not any other incrementals)
1767                 @type useonly: Boolean
1768                 @rtype: None
1769                 """
1770
1771                 if use_cache is not None:
1772                         warnings.warn("The use_cache parameter for config.regenerate() is deprecated and without effect.",
1773                                 DeprecationWarning, stacklevel=2)
1774
1775                 self.modifying()
1776
1777                 if useonly:
1778                         myincrementals=["USE"]
1779                 else:
1780                         myincrementals = self.incrementals
1781                 myincrementals = set(myincrementals)
1782
1783                 # Process USE last because it depends on USE_EXPAND which is also
1784                 # an incremental!
1785                 myincrementals.discard("USE")
1786
1787                 mydbs = self.configlist[:-1]
1788                 mydbs.append(self.backupenv)
1789
1790                 # ACCEPT_LICENSE is a lazily evaluated incremental, so that * can be
1791                 # used to match all licenses without every having to explicitly expand
1792                 # it to all licenses.
1793                 if self.local_config:
1794                         mysplit = []
1795                         for curdb in mydbs:
1796                                 mysplit.extend(curdb.get('ACCEPT_LICENSE', '').split())
1797                         mysplit = prune_incremental(mysplit)
1798                         accept_license_str = ' '.join(mysplit)
1799                         self.configlist[-1]['ACCEPT_LICENSE'] = accept_license_str
1800                         self._license_manager.set_accept_license_str(accept_license_str)
1801                 else:
1802                         # repoman will accept any license
1803                         self._license_manager.set_accept_license_str("*")
1804
1805                 # ACCEPT_PROPERTIES works like ACCEPT_LICENSE, without groups
1806                 if self.local_config:
1807                         mysplit = []
1808                         for curdb in mydbs:
1809                                 mysplit.extend(curdb.get('ACCEPT_PROPERTIES', '').split())
1810                         mysplit = prune_incremental(mysplit)
1811                         self.configlist[-1]['ACCEPT_PROPERTIES'] = ' '.join(mysplit)
1812                         if tuple(mysplit) != self._accept_properties:
1813                                 self._accept_properties = tuple(mysplit)
1814                 else:
1815                         # repoman will accept any property
1816                         self._accept_properties = ('*',)
1817
1818                 increment_lists = {}
1819                 for k in myincrementals:
1820                         incremental_list = []
1821                         increment_lists[k] = incremental_list
1822                         for curdb in mydbs:
1823                                 v = curdb.get(k)
1824                                 if v is not None:
1825                                         incremental_list.append(v.split())
1826
1827                 if 'FEATURES' in increment_lists:
1828                         increment_lists['FEATURES'].append(self._features_overrides)
1829
1830                 myflags = set()
1831                 for mykey, incremental_list in increment_lists.items():
1832
1833                         myflags.clear()
1834                         for mysplit in incremental_list:
1835
1836                                 for x in mysplit:
1837                                         if x=="-*":
1838                                                 # "-*" is a special "minus" var that means "unset all settings".
1839                                                 # so USE="-* gnome" will have *just* gnome enabled.
1840                                                 myflags.clear()
1841                                                 continue
1842
1843                                         if x[0]=="+":
1844                                                 # Not legal. People assume too much. Complain.
1845                                                 writemsg(colorize("BAD",
1846                                                         _("%s values should not start with a '+': %s") % (mykey,x)) \
1847                                                         + "\n", noiselevel=-1)
1848                                                 x=x[1:]
1849                                                 if not x:
1850                                                         continue
1851
1852                                         if (x[0]=="-"):
1853                                                 myflags.discard(x[1:])
1854                                                 continue
1855
1856                                         # We got here, so add it now.
1857                                         myflags.add(x)
1858
1859                         #store setting in last element of configlist, the original environment:
1860                         if myflags or mykey in self:
1861                                 self.configlist[-1][mykey] = " ".join(sorted(myflags))
1862
1863                 # Do the USE calculation last because it depends on USE_EXPAND.
1864                 use_expand = self.get("USE_EXPAND", "").split()
1865                 use_expand_dict = self._use_expand_dict
1866                 use_expand_dict.clear()
1867                 for k in use_expand:
1868                         v = self.get(k)
1869                         if v is not None:
1870                                 use_expand_dict[k] = v
1871
1872                 # In order to best accomodate the long-standing practice of
1873                 # setting default USE_EXPAND variables in the profile's
1874                 # make.defaults, we translate these variables into their
1875                 # equivalent USE flags so that useful incremental behavior
1876                 # is enabled (for sub-profiles).
1877                 configdict_defaults = self.configdict['defaults']
1878                 if self._make_defaults is not None:
1879                         for i, cfg in enumerate(self._make_defaults):
1880                                 if not cfg:
1881                                         self.make_defaults_use.append("")
1882                                         continue
1883                                 use = cfg.get("USE", "")
1884                                 expand_use = []
1885                                 for k in use_expand_dict:
1886                                         v = cfg.get(k)
1887                                         if v is None:
1888                                                 continue
1889                                         prefix = k.lower() + '_'
1890                                         if k in myincrementals:
1891                                                 for x in v.split():
1892                                                         if x[:1] == '-':
1893                                                                 expand_use.append('-' + prefix + x[1:])
1894                                                         else:
1895                                                                 expand_use.append(prefix + x)
1896                                         else:
1897                                                 for x in v.split():
1898                                                         expand_use.append(prefix + x)
1899                                 if expand_use:
1900                                         expand_use.append(use)
1901                                         use  = ' '.join(expand_use)
1902                                 self.make_defaults_use.append(use)
1903                         self.make_defaults_use = tuple(self.make_defaults_use)
1904                         configdict_defaults['USE'] = ' '.join(
1905                                 stack_lists([x.split() for x in self.make_defaults_use]))
1906                         # Set to None so this code only runs once.
1907                         self._make_defaults = None
1908
1909                 if not self.uvlist:
1910                         for x in self["USE_ORDER"].split(":"):
1911                                 if x in self.configdict:
1912                                         self.uvlist.append(self.configdict[x])
1913                         self.uvlist.reverse()
1914
1915                 # For optimal performance, use slice
1916                 # comparison instead of startswith().
1917                 iuse = self.configdict["pkg"].get("IUSE")
1918                 if iuse is not None:
1919                         iuse = [x.lstrip("+-") for x in iuse.split()]
1920                 myflags = set()
1921                 for curdb in self.uvlist:
1922                         cur_use_expand = [x for x in use_expand if x in curdb]
1923                         mysplit = curdb.get("USE", "").split()
1924                         if not mysplit and not cur_use_expand:
1925                                 continue
1926                         for x in mysplit:
1927                                 if x == "-*":
1928                                         myflags.clear()
1929                                         continue
1930
1931                                 if x[0] == "+":
1932                                         writemsg(colorize("BAD", _("USE flags should not start "
1933                                                 "with a '+': %s\n") % x), noiselevel=-1)
1934                                         x = x[1:]
1935                                         if not x:
1936                                                 continue
1937
1938                                 if x[0] == "-":
1939                                         if x[-2:] == '_*':
1940                                                 prefix = x[1:-1]
1941                                                 prefix_len = len(prefix)
1942                                                 myflags.difference_update(
1943                                                         [y for y in myflags if \
1944                                                         y[:prefix_len] == prefix])
1945                                         myflags.discard(x[1:])
1946                                         continue
1947
1948                                 if iuse is not None and x[-2:] == '_*':
1949                                         # Expand wildcards here, so that cases like
1950                                         # USE="linguas_* -linguas_en_US" work correctly.
1951                                         prefix = x[:-1]
1952                                         prefix_len = len(prefix)
1953                                         has_iuse = False
1954                                         for y in iuse:
1955                                                 if y[:prefix_len] == prefix:
1956                                                         has_iuse = True
1957                                                         myflags.add(y)
1958                                         if not has_iuse:
1959                                                 # There are no matching IUSE, so allow the
1960                                                 # wildcard to pass through. This allows
1961                                                 # linguas_* to trigger unset LINGUAS in
1962                                                 # cases when no linguas_ flags are in IUSE.
1963                                                 myflags.add(x)
1964                                 else:
1965                                         myflags.add(x)
1966
1967                         if curdb is configdict_defaults:
1968                                 # USE_EXPAND flags from make.defaults are handled
1969                                 # earlier, in order to provide useful incremental
1970                                 # behavior (for sub-profiles).
1971                                 continue
1972
1973                         for var in cur_use_expand:
1974                                 var_lower = var.lower()
1975                                 is_not_incremental = var not in myincrementals
1976                                 if is_not_incremental:
1977                                         prefix = var_lower + "_"
1978                                         prefix_len = len(prefix)
1979                                         for x in list(myflags):
1980                                                 if x[:prefix_len] == prefix:
1981                                                         myflags.remove(x)
1982                                 for x in curdb[var].split():
1983                                         if x[0] == "+":
1984                                                 if is_not_incremental:
1985                                                         writemsg(colorize("BAD", _("Invalid '+' "
1986                                                                 "operator in non-incremental variable "
1987                                                                  "'%s': '%s'\n") % (var, x)), noiselevel=-1)
1988                                                         continue
1989                                                 else:
1990                                                         writemsg(colorize("BAD", _("Invalid '+' "
1991                                                                 "operator in incremental variable "
1992                                                                  "'%s': '%s'\n") % (var, x)), noiselevel=-1)
1993                                                 x = x[1:]
1994                                         if x[0] == "-":
1995                                                 if is_not_incremental:
1996                                                         writemsg(colorize("BAD", _("Invalid '-' "
1997                                                                 "operator in non-incremental variable "
1998                                                                  "'%s': '%s'\n") % (var, x)), noiselevel=-1)
1999                                                         continue
2000                                                 myflags.discard(var_lower + "_" + x[1:])
2001                                                 continue
2002                                         myflags.add(var_lower + "_" + x)
2003
2004                 if hasattr(self, "features"):
2005                         self.features._features.clear()
2006                 else:
2007                         self.features = features_set(self)
2008                 self.features._features.update(self.get('FEATURES', '').split())
2009                 self.features._sync_env_var()
2010                 self.features._validate()
2011
2012                 myflags.update(self.useforce)
2013                 arch = self.configdict["defaults"].get("ARCH")
2014                 if arch:
2015                         myflags.add(arch)
2016
2017                 myflags.difference_update(self.usemask)
2018                 self.configlist[-1]["USE"]= " ".join(sorted(myflags))
2019
2020                 if self.mycpv is None:
2021                         # Generate global USE_EXPAND variables settings that are
2022                         # consistent with USE, for display by emerge --info. For
2023                         # package instances, these are instead generated via
2024                         # setcpv().
2025                         for k in use_expand:
2026                                 prefix = k.lower() + '_'
2027                                 prefix_len = len(prefix)
2028                                 expand_flags = set( x[prefix_len:] for x in myflags \
2029                                         if x[:prefix_len] == prefix )
2030                                 var_split = use_expand_dict.get(k, '').split()
2031                                 var_split = [ x for x in var_split if x in expand_flags ]
2032                                 var_split.extend(sorted(expand_flags.difference(var_split)))
2033                                 if var_split:
2034                                         self.configlist[-1][k] = ' '.join(var_split)
2035                                 elif k in self:
2036                                         self.configlist[-1][k] = ''
2037
2038         @property
2039         def virts_p(self):
2040                 warnings.warn("portage config.virts_p attribute " + \
2041                         "is deprecated, use config.get_virts_p()",
2042                         DeprecationWarning, stacklevel=2)
2043                 return self.get_virts_p()
2044
2045         @property
2046         def virtuals(self):
2047                 warnings.warn("portage config.virtuals attribute " + \
2048                         "is deprecated, use config.getvirtuals()",
2049                         DeprecationWarning, stacklevel=2)
2050                 return self.getvirtuals()
2051
2052         def get_virts_p(self):
2053                 # Ensure that we don't trigger the _treeVirtuals
2054                 # assertion in VirtualsManager._compile_virtuals().
2055                 self.getvirtuals()
2056                 return self._virtuals_manager.get_virts_p()
2057
2058         def getvirtuals(self):
2059                 if self._virtuals_manager._treeVirtuals is None:
2060                         #Hack around the fact that VirtualsManager needs a vartree
2061                         #and vartree needs a config instance.
2062                         #This code should be part of VirtualsManager.getvirtuals().
2063                         if self.local_config:
2064                                 temp_vartree = vartree(settings=self)
2065                                 self._virtuals_manager._populate_treeVirtuals(temp_vartree)
2066                         else:
2067                                 self._virtuals_manager._treeVirtuals = {}
2068
2069                 return self._virtuals_manager.getvirtuals()
2070
2071         def _populate_treeVirtuals_if_needed(self, vartree):
2072                 """Reduce the provides into a list by CP."""
2073                 if self._virtuals_manager._treeVirtuals is None:
2074                         if self.local_config:
2075                                 self._virtuals_manager._populate_treeVirtuals(vartree)
2076                         else:
2077                                 self._virtuals_manager._treeVirtuals = {}
2078
2079         def __delitem__(self,mykey):
2080                 self.pop(mykey)
2081
2082         def __getitem__(self, key):
2083                 try:
2084                         return self._getitem(key)
2085                 except KeyError:
2086                         return '' # for backward compat, don't raise KeyError
2087
2088         def _getitem(self, mykey):
2089
2090                 # These ones point to temporary values when
2091                 # portage plans to update itself.
2092                 if mykey == "PORTAGE_BIN_PATH":
2093                         return portage._bin_path
2094                 elif mykey == "PORTAGE_PYM_PATH":
2095                         return portage._pym_path
2096
2097                 for d in self.lookuplist:
2098                         try:
2099                                 return d[mykey]
2100                         except KeyError:
2101                                 pass
2102
2103                 raise KeyError(mykey)
2104
2105         def get(self, k, x=None):
2106                 try:
2107                         return self._getitem(k)
2108                 except KeyError:
2109                         return x
2110
2111         def pop(self, key, *args):
2112                 self.modifying()
2113                 if len(args) > 1:
2114                         raise TypeError(
2115                                 "pop expected at most 2 arguments, got " + \
2116                                 repr(1 + len(args)))
2117                 v = self
2118                 for d in reversed(self.lookuplist):
2119                         v = d.pop(key, v)
2120                 if v is self:
2121                         if args:
2122                                 return args[0]
2123                         raise KeyError(key)
2124                 return v
2125
2126         def __contains__(self, mykey):
2127                 """Called to implement membership test operators (in and not in)."""
2128                 try:
2129                          self._getitem(mykey)
2130                 except KeyError:
2131                         return False
2132                 else:
2133                         return True
2134
2135         def setdefault(self, k, x=None):
2136                 v = self.get(k)
2137                 if v is not None:
2138                         return v
2139                 else:
2140                         self[k] = x
2141                         return x
2142
2143         def keys(self):
2144                 return list(self)
2145
2146         def __iter__(self):
2147                 keys = set()
2148                 keys.add("PORTAGE_BIN_PATH")
2149                 keys.add("PORTAGE_PYM_PATH")
2150                 for d in self.lookuplist:
2151                         keys.update(d)
2152                 return iter(keys)
2153
2154         def iterkeys(self):
2155                 return iter(self)
2156
2157         def iteritems(self):
2158                 for k in self:
2159                         yield (k, self._getitem(k))
2160
2161         def items(self):
2162                 return list(self.iteritems())
2163
2164         def __setitem__(self,mykey,myvalue):
2165                 "set a value; will be thrown away at reset() time"
2166                 if not isinstance(myvalue, basestring):
2167                         raise ValueError("Invalid type being used as a value: '%s': '%s'" % (str(mykey),str(myvalue)))
2168
2169                 # Avoid potential UnicodeDecodeError exceptions later.
2170                 mykey = _unicode_decode(mykey)
2171                 myvalue = _unicode_decode(myvalue)
2172
2173                 self.modifying()
2174                 self.modifiedkeys.append(mykey)
2175                 self.configdict["env"][mykey]=myvalue
2176
2177         def environ(self):
2178                 "return our locally-maintained environment"
2179                 mydict={}
2180                 environ_filter = self._environ_filter
2181
2182                 eapi = self.get('EAPI')
2183                 phase = self.get('EBUILD_PHASE')
2184                 filter_calling_env = False
2185                 if self.mycpv is not None and \
2186                         phase not in ('clean', 'cleanrm', 'depend', 'fetch'):
2187                         temp_dir = self.get('T')
2188                         if temp_dir is not None and \
2189                                 os.path.exists(os.path.join(temp_dir, 'environment')):
2190                                 filter_calling_env = True
2191
2192                 environ_whitelist = self._environ_whitelist
2193                 for x in self:
2194                         if x in environ_filter:
2195                                 continue
2196                         myvalue = self[x]
2197                         if not isinstance(myvalue, basestring):
2198                                 writemsg(_("!!! Non-string value in config: %s=%s\n") % \
2199                                         (x, myvalue), noiselevel=-1)
2200                                 continue
2201                         if filter_calling_env and \
2202                                 x not in environ_whitelist and \
2203                                 not self._environ_whitelist_re.match(x):
2204                                 # Do not allow anything to leak into the ebuild
2205                                 # environment unless it is explicitly whitelisted.
2206                                 # This ensures that variables unset by the ebuild
2207                                 # remain unset (bug #189417).
2208                                 continue
2209                         mydict[x] = myvalue
2210                 if "HOME" not in mydict and "BUILD_PREFIX" in mydict:
2211                         writemsg("*** HOME not set. Setting to "+mydict["BUILD_PREFIX"]+"\n")
2212                         mydict["HOME"]=mydict["BUILD_PREFIX"][:]
2213
2214                 if filter_calling_env:
2215                         if phase:
2216                                 whitelist = []
2217                                 if "rpm" == phase:
2218                                         whitelist.append("RPMDIR")
2219                                 for k in whitelist:
2220                                         v = self.get(k)
2221                                         if v is not None:
2222                                                 mydict[k] = v
2223
2224                 # At some point we may want to stop exporting FEATURES to the ebuild
2225                 # environment, in order to prevent ebuilds from abusing it. In
2226                 # preparation for that, export it as PORTAGE_FEATURES so that bashrc
2227                 # users will be able to migrate any FEATURES conditional code to
2228                 # use this alternative variable.
2229                 mydict["PORTAGE_FEATURES"] = self["FEATURES"]
2230
2231                 # Filtered by IUSE and implicit IUSE.
2232                 mydict["USE"] = self.get("PORTAGE_USE", "")
2233
2234                 # Don't export AA to the ebuild environment in EAPIs that forbid it
2235                 if not eapi_exports_AA(eapi):
2236                         mydict.pop("AA", None)
2237
2238                 if not eapi_exports_merge_type(eapi):
2239                         mydict.pop("MERGE_TYPE", None)
2240
2241                 # Prefix variables are supported beginning with EAPI 3, or when EPREFIX
2242                 # is non-empty (implying that EPREFIX support is required in the
2243                 # current environment, regardless of EAPI). For EAPIs prior to 3,
2244                 # ebuild helpers rely on these variables only when USE=prefix is
2245                 # enabled. This is safe because the prefix flag should be masked in all
2246                 # non-prefix profiles, and older EAPIs would otherwise be useless with
2247                 # prefix configurations. This brings compatibility with the prefix
2248                 # branch of portage, which also supports EPREFIX for all EAPIs (for
2249                 # obvious reasons).
2250                 if phase == 'depend' or eapi is None or \
2251                         (not eapi_supports_prefix(eapi) and not mydict.get("EPREFIX")):
2252                         mydict.pop("ED", None)
2253                         mydict.pop("EPREFIX", None)
2254                         mydict.pop("EROOT", None)
2255
2256                 if phase == 'depend':
2257                         mydict.pop('FILESDIR', None)
2258
2259                 if phase not in ("pretend", "setup", "preinst", "postinst") or \
2260                         not eapi_exports_replace_vars(eapi):
2261                         mydict.pop("REPLACING_VERSIONS", None)
2262
2263                 if phase not in ("prerm", "postrm") or \
2264                         not eapi_exports_replace_vars(eapi):
2265                         mydict.pop("REPLACED_BY_VERSION", None)
2266
2267                 return mydict
2268
2269         def thirdpartymirrors(self):
2270                 if getattr(self, "_thirdpartymirrors", None) is None:
2271                         profileroots = [os.path.join(self["PORTDIR"], "profiles")]
2272                         for x in shlex_split(self.get("PORTDIR_OVERLAY", "")):
2273                                 profileroots.insert(0, os.path.join(x, "profiles"))
2274                         thirdparty_lists = [grabdict(os.path.join(x, "thirdpartymirrors")) for x in profileroots]
2275                         self._thirdpartymirrors = stack_dictlist(thirdparty_lists, incremental=True)
2276                 return self._thirdpartymirrors
2277
2278         def archlist(self):
2279                 _archlist = []
2280                 for myarch in self["PORTAGE_ARCHLIST"].split():
2281                         _archlist.append(myarch)
2282                         _archlist.append("~" + myarch)
2283                 return _archlist
2284
2285         def selinux_enabled(self):
2286                 if getattr(self, "_selinux_enabled", None) is None:
2287                         self._selinux_enabled = 0
2288                         if "selinux" in self["USE"].split():
2289                                 if selinux:
2290                                         if selinux.is_selinux_enabled() == 1:
2291                                                 self._selinux_enabled = 1
2292                                         else:
2293                                                 self._selinux_enabled = 0
2294                                 else:
2295                                         writemsg(_("!!! SELinux module not found. Please verify that it was installed.\n"),
2296                                                 noiselevel=-1)
2297                                         self._selinux_enabled = 0
2298
2299                 return self._selinux_enabled
2300
2301         if sys.hexversion >= 0x3000000:
2302                 keys = __iter__
2303                 items = iteritems