Gentoo Archives: gentoo-commits

From: "Zac Medico (zmedico)" <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r15424 - in main/trunk/pym/portage: . package package/ebuild
Date: Mon, 22 Feb 2010 04:13:42
Message-Id: E1NjPfl-00088n-LV@stork.gentoo.org
1 Author: zmedico
2 Date: 2010-02-22 04:13:28 +0000 (Mon, 22 Feb 2010)
3 New Revision: 15424
4
5 Added:
6 main/trunk/pym/portage/package/
7 main/trunk/pym/portage/package/__init__.py
8 main/trunk/pym/portage/package/ebuild/
9 main/trunk/pym/portage/package/ebuild/__init__.py
10 main/trunk/pym/portage/package/ebuild/config.py
11 Modified:
12 main/trunk/pym/portage/__init__.py
13 Log:
14 Move portage.config class to portage.package.ebuild.config.config.
15
16
17 Modified: main/trunk/pym/portage/__init__.py
18 ===================================================================
19 --- main/trunk/pym/portage/__init__.py 2010-02-22 02:50:49 UTC (rev 15423)
20 +++ main/trunk/pym/portage/__init__.py 2010-02-22 04:13:28 UTC (rev 15424)
21 @@ -102,6 +102,8 @@
22 'portage.mail',
23 'portage.output',
24 'portage.output:bold,colorize',
25 + 'portage.package.ebuild.config:autouse,best_from_dict,' + \
26 + 'check_config_instance,config',
27 'portage.process',
28 'portage.process:atexit_register,run_exitfuncs',
29 'portage.update:dep_transform,fixdbentries,grab_updates,' + \
30 @@ -512,18 +514,6 @@
31 mod = getattr(mod, comp)
32 return mod
33
34 -def best_from_dict(key, top_dict, key_order, EmptyOnError=1, FullCopy=1, AllowEmpty=1):
35 - for x in key_order:
36 - if x in top_dict and key in top_dict[x]:
37 - if FullCopy:
38 - return copy.deepcopy(top_dict[x][key])
39 - else:
40 - return top_dict[x][key]
41 - if EmptyOnError:
42 - return ""
43 - else:
44 - raise KeyError("Key not found in list; '%s'" % key)
45 -
46 def getcwd():
47 "this fixes situations where the current directory doesn't exist"
48 try:
49 @@ -1008,2560 +998,6 @@
50
51 return (version,None)
52
53 -def autouse(myvartree, use_cache=1, mysettings=None):
54 - """
55 - autuse returns a list of USE variables auto-enabled to packages being installed
56 -
57 - @param myvartree: Instance of the vartree class (from /var/db/pkg...)
58 - @type myvartree: vartree
59 - @param use_cache: read values from cache
60 - @type use_cache: Boolean
61 - @param mysettings: Instance of config
62 - @type mysettings: config
63 - @rtype: string
64 - @returns: A string containing a list of USE variables that are enabled via use.defaults
65 - """
66 - if mysettings is None:
67 - global settings
68 - mysettings = settings
69 - if mysettings.profile_path is None:
70 - return ""
71 - myusevars=""
72 - usedefaults = mysettings.use_defs
73 - for myuse in usedefaults:
74 - dep_met = True
75 - for mydep in usedefaults[myuse]:
76 - if not myvartree.dep_match(mydep,use_cache=True):
77 - dep_met = False
78 - break
79 - if dep_met:
80 - myusevars += " "+myuse
81 - return myusevars
82 -
83 -def check_config_instance(test):
84 - if not isinstance(test, config):
85 - raise TypeError("Invalid type for config object: %s (should be %s)" % (test.__class__, config))
86 -
87 -def _lazy_iuse_regex(iuse_implicit):
88 - """
89 - The PORTAGE_IUSE value is lazily evaluated since re.escape() is slow
90 - and the value is only used when an ebuild phase needs to be executed
91 - (it's used only to generate QA notices).
92 - """
93 - # Escape anything except ".*" which is supposed to pass through from
94 - # _get_implicit_iuse().
95 - regex = sorted(re.escape(x) for x in iuse_implicit)
96 - regex = "^(%s)$" % "|".join(regex)
97 - regex = regex.replace("\\.\\*", ".*")
98 - return regex
99 -
100 -class _local_repo_config(object):
101 - __slots__ = ('aliases', 'eclass_overrides', 'masters', 'name',)
102 - def __init__(self, name, repo_opts):
103 - self.name = name
104 -
105 - aliases = repo_opts.get('aliases')
106 - if aliases is not None:
107 - aliases = tuple(aliases.split())
108 - self.aliases = aliases
109 -
110 - eclass_overrides = repo_opts.get('eclass-overrides')
111 - if eclass_overrides is not None:
112 - eclass_overrides = tuple(eclass_overrides.split())
113 - self.eclass_overrides = eclass_overrides
114 -
115 - masters = repo_opts.get('masters')
116 - if masters is not None:
117 - masters = tuple(masters.split())
118 - self.masters = masters
119 -
120 -class config(object):
121 - """
122 - This class encompasses the main portage configuration. Data is pulled from
123 - ROOT/PORTDIR/profiles/, from ROOT/etc/make.profile incrementally through all
124 - parent profiles as well as from ROOT/PORTAGE_CONFIGROOT/* for user specified
125 - overrides.
126 -
127 - Generally if you need data like USE flags, FEATURES, environment variables,
128 - virtuals ...etc you look in here.
129 - """
130 -
131 - _setcpv_aux_keys = ('DEFINED_PHASES', 'DEPEND', 'EAPI',
132 - 'INHERITED', 'IUSE', 'KEYWORDS', 'LICENSE', 'PDEPEND',
133 - 'PROPERTIES', 'PROVIDE', 'RDEPEND', 'SLOT',
134 - 'repository', 'RESTRICT', 'LICENSE',)
135 -
136 - _env_blacklist = [
137 - "A", "AA", "CATEGORY", "DEPEND", "DESCRIPTION", "EAPI",
138 - "EBUILD_PHASE", "ED", "EMERGE_FROM", "EPREFIX", "EROOT",
139 - "HOMEPAGE", "INHERITED", "IUSE",
140 - "KEYWORDS", "LICENSE", "PDEPEND", "PF", "PKGUSE",
141 - "PORTAGE_CONFIGROOT", "PORTAGE_IUSE",
142 - "PORTAGE_NONFATAL", "PORTAGE_REPO_NAME",
143 - "PORTAGE_USE", "PROPERTIES", "PROVIDE", "RDEPEND", "RESTRICT",
144 - "ROOT", "SLOT", "SRC_URI"
145 - ]
146 -
147 - _environ_whitelist = []
148 -
149 - # Whitelisted variables are always allowed to enter the ebuild
150 - # environment. Generally, this only includes special portage
151 - # variables. Ebuilds can unset variables that are not whitelisted
152 - # and rely on them remaining unset for future phases, without them
153 - # leaking back in from various locations (bug #189417). It's very
154 - # important to set our special BASH_ENV variable in the ebuild
155 - # environment in order to prevent sandbox from sourcing /etc/profile
156 - # in it's bashrc (causing major leakage).
157 - _environ_whitelist += [
158 - "ACCEPT_LICENSE", "BASH_ENV", "BUILD_PREFIX", "D",
159 - "DISTDIR", "DOC_SYMLINKS_DIR", "EAPI", "EBUILD",
160 - "EBUILD_EXIT_STATUS_FILE", "EBUILD_FORCE_TEST",
161 - "EBUILD_PHASE", "ECLASSDIR", "ECLASS_DEPTH", "ED",
162 - "EMERGE_FROM", "EPREFIX", "EROOT",
163 - "FEATURES", "FILESDIR", "HOME", "NOCOLOR", "PATH",
164 - "PKGDIR",
165 - "PKGUSE", "PKG_LOGDIR", "PKG_TMPDIR",
166 - "PORTAGE_ACTUAL_DISTDIR", "PORTAGE_ARCHLIST",
167 - "PORTAGE_BASHRC",
168 - "PORTAGE_BINPKG_FILE", "PORTAGE_BINPKG_TAR_OPTS",
169 - "PORTAGE_BINPKG_TMPFILE",
170 - "PORTAGE_BIN_PATH",
171 - "PORTAGE_BUILDDIR", "PORTAGE_COLORMAP",
172 - "PORTAGE_CONFIGROOT", "PORTAGE_DEBUG", "PORTAGE_DEPCACHEDIR",
173 - "PORTAGE_GID", "PORTAGE_INST_GID", "PORTAGE_INST_UID",
174 - "PORTAGE_IUSE",
175 - "PORTAGE_LOG_FILE", "PORTAGE_MASTER_PID",
176 - "PORTAGE_PYM_PATH", "PORTAGE_QUIET",
177 - "PORTAGE_REPO_NAME", "PORTAGE_RESTRICT",
178 - "PORTAGE_TMPDIR", "PORTAGE_UPDATE_ENV",
179 - "PORTAGE_VERBOSE", "PORTAGE_WORKDIR_MODE",
180 - "PORTDIR", "PORTDIR_OVERLAY", "PREROOTPATH", "PROFILE_PATHS",
181 - "ROOT", "ROOTPATH", "T", "TMP", "TMPDIR",
182 - "USE_EXPAND", "USE_ORDER", "WORKDIR",
183 - "XARGS",
184 - ]
185 -
186 - # user config variables
187 - _environ_whitelist += [
188 - "DOC_SYMLINKS_DIR", "INSTALL_MASK", "PKG_INSTALL_MASK"
189 - ]
190 -
191 - _environ_whitelist += [
192 - "A", "AA", "CATEGORY", "P", "PF", "PN", "PR", "PV", "PVR"
193 - ]
194 -
195 - # misc variables inherited from the calling environment
196 - _environ_whitelist += [
197 - "COLORTERM", "DISPLAY", "EDITOR", "LESS",
198 - "LESSOPEN", "LOGNAME", "LS_COLORS", "PAGER",
199 - "TERM", "TERMCAP", "USER",
200 - ]
201 -
202 - # tempdir settings
203 - _environ_whitelist += [
204 - "TMPDIR", "TEMP", "TMP",
205 - ]
206 -
207 - # localization settings
208 - _environ_whitelist += [
209 - "LANG", "LC_COLLATE", "LC_CTYPE", "LC_MESSAGES",
210 - "LC_MONETARY", "LC_NUMERIC", "LC_TIME", "LC_PAPER",
211 - "LC_ALL",
212 - ]
213 -
214 - # other variables inherited from the calling environment
215 - _environ_whitelist += [
216 - "CVS_RSH", "ECHANGELOG_USER",
217 - "GPG_AGENT_INFO",
218 - "SSH_AGENT_PID", "SSH_AUTH_SOCK",
219 - "STY", "WINDOW", "XAUTHORITY",
220 - ]
221 -
222 - _environ_whitelist = frozenset(_environ_whitelist)
223 -
224 - _environ_whitelist_re = re.compile(r'^(CCACHE_|DISTCC_).*')
225 -
226 - # Filter selected variables in the config.environ() method so that
227 - # they don't needlessly propagate down into the ebuild environment.
228 - _environ_filter = []
229 -
230 - # Exclude anything that could be extremely long here (like SRC_URI)
231 - # since that could cause execve() calls to fail with E2BIG errors. For
232 - # example, see bug #262647.
233 - _environ_filter += [
234 - 'DEPEND', 'RDEPEND', 'PDEPEND', 'SRC_URI',
235 - ]
236 -
237 - # misc variables inherited from the calling environment
238 - _environ_filter += [
239 - "INFOPATH", "MANPATH", "USER",
240 - ]
241 -
242 - # variables that break bash
243 - _environ_filter += [
244 - "HISTFILE", "POSIXLY_CORRECT",
245 - ]
246 -
247 - # portage config variables and variables set directly by portage
248 - _environ_filter += [
249 - "ACCEPT_KEYWORDS", "ACCEPT_PROPERTIES", "AUTOCLEAN",
250 - "CLEAN_DELAY", "COLLISION_IGNORE", "CONFIG_PROTECT",
251 - "CONFIG_PROTECT_MASK", "EGENCACHE_DEFAULT_OPTS", "EMERGE_DEFAULT_OPTS",
252 - "EMERGE_LOG_DIR",
253 - "EMERGE_WARNING_DELAY", "FETCHCOMMAND", "FETCHCOMMAND_FTP",
254 - "FETCHCOMMAND_HTTP", "FETCHCOMMAND_SFTP",
255 - "GENTOO_MIRRORS", "NOCONFMEM", "O",
256 - "PORTAGE_BACKGROUND",
257 - "PORTAGE_BINHOST_CHUNKSIZE", "PORTAGE_CALLER",
258 - "PORTAGE_ELOG_CLASSES",
259 - "PORTAGE_ELOG_MAILFROM", "PORTAGE_ELOG_MAILSUBJECT",
260 - "PORTAGE_ELOG_MAILURI", "PORTAGE_ELOG_SYSTEM",
261 - "PORTAGE_FETCH_CHECKSUM_TRY_MIRRORS", "PORTAGE_FETCH_RESUME_MIN_SIZE",
262 - "PORTAGE_GPG_DIR",
263 - "PORTAGE_GPG_KEY", "PORTAGE_IONICE_COMMAND",
264 - "PORTAGE_PACKAGE_EMPTY_ABORT",
265 - "PORTAGE_REPO_DUPLICATE_WARN",
266 - "PORTAGE_RO_DISTDIRS",
267 - "PORTAGE_RSYNC_EXTRA_OPTS", "PORTAGE_RSYNC_OPTS",
268 - "PORTAGE_RSYNC_RETRIES", "PORTAGE_USE", "PORT_LOGDIR",
269 - "QUICKPKG_DEFAULT_OPTS",
270 - "RESUMECOMMAND", "RESUMECOMMAND_HTTP", "RESUMECOMMAND_HTTP",
271 - "RESUMECOMMAND_SFTP", "SYNC", "USE_EXPAND_HIDDEN", "USE_ORDER",
272 - ]
273 -
274 - _environ_filter = frozenset(_environ_filter)
275 -
276 - _undef_lic_groups = set()
277 - _default_globals = (
278 - ('ACCEPT_LICENSE', '* -@EULA'),
279 - ('ACCEPT_PROPERTIES', '*'),
280 - )
281 -
282 - # To enhance usability, make some vars case insensitive
283 - # by forcing them to lower case.
284 - _case_insensitive_vars = ('AUTOCLEAN', 'NOCOLOR',)
285 -
286 - def __init__(self, clone=None, mycpv=None, config_profile_path=None,
287 - config_incrementals=None, config_root=None, target_root=None,
288 - local_config=True, env=None):
289 - """
290 - @param clone: If provided, init will use deepcopy to copy by value the instance.
291 - @type clone: Instance of config class.
292 - @param mycpv: CPV to load up (see setcpv), this is the same as calling init with mycpv=None
293 - and then calling instance.setcpv(mycpv).
294 - @type mycpv: String
295 - @param config_profile_path: Configurable path to the profile (usually PROFILE_PATH from portage.const)
296 - @type config_profile_path: String
297 - @param config_incrementals: List of incremental variables
298 - (defaults to portage.const.INCREMENTALS)
299 - @type config_incrementals: List
300 - @param config_root: path to read local config from (defaults to "/", see PORTAGE_CONFIGROOT)
301 - @type config_root: String
302 - @param target_root: __init__ override of $ROOT env variable.
303 - @type target_root: String
304 - @param local_config: Enables loading of local config (/etc/portage); used most by repoman to
305 - ignore local config (keywording and unmasking)
306 - @type local_config: Boolean
307 - @param env: The calling environment which is used to override settings.
308 - Defaults to os.environ if unspecified.
309 - @type env: dict
310 - """
311 -
312 - # When initializing the global portage.settings instance, avoid
313 - # raising exceptions whenever possible since exceptions thrown
314 - # from 'import portage' or 'import portage.exceptions' statements
315 - # can practically render the api unusable for api consumers.
316 - tolerant = "_initializing_globals" in globals()
317 -
318 - self.already_in_regenerate = 0
319 -
320 - self.locked = 0
321 - self.mycpv = None
322 - self._setcpv_args_hash = None
323 - self.puse = []
324 - self.modifiedkeys = []
325 - self.uvlist = []
326 - self._accept_chost_re = None
327 - self._accept_license = None
328 - self._accept_license_str = None
329 - self._license_groups = {}
330 - self._accept_properties = None
331 -
332 - self.virtuals = {}
333 - self.virts_p = {}
334 - self.dirVirtuals = None
335 - self.v_count = 0
336 -
337 - # Virtuals obtained from the vartree
338 - self.treeVirtuals = {}
339 - # Virtuals by user specification. Includes negatives.
340 - self.userVirtuals = {}
341 - # Virtual negatives from user specifications.
342 - self.negVirtuals = {}
343 - # Virtuals added by the depgraph via self.setinst().
344 - self._depgraphVirtuals = {}
345 -
346 - self.user_profile_dir = None
347 - self.local_config = local_config
348 - self._local_repo_configs = None
349 - self._local_repo_conf_path = None
350 -
351 - if clone:
352 - # For immutable attributes, use shallow copy for
353 - # speed and memory conservation.
354 - self.categories = clone.categories
355 - self.depcachedir = clone.depcachedir
356 - self.incrementals = clone.incrementals
357 - self.module_priority = clone.module_priority
358 - self.profile_path = clone.profile_path
359 - self.profiles = clone.profiles
360 - self.packages = clone.packages
361 - self.useforce_list = clone.useforce_list
362 - self.usemask_list = clone.usemask_list
363 -
364 - self.user_profile_dir = copy.deepcopy(clone.user_profile_dir)
365 - self.local_config = copy.deepcopy(clone.local_config)
366 - self._local_repo_configs = \
367 - copy.deepcopy(clone._local_repo_configs)
368 - self._local_repo_conf_path = \
369 - copy.deepcopy(clone._local_repo_conf_path)
370 - self.modules = copy.deepcopy(clone.modules)
371 - self.virtuals = copy.deepcopy(clone.virtuals)
372 - self.dirVirtuals = copy.deepcopy(clone.dirVirtuals)
373 - self.treeVirtuals = copy.deepcopy(clone.treeVirtuals)
374 - self.userVirtuals = copy.deepcopy(clone.userVirtuals)
375 - self.negVirtuals = copy.deepcopy(clone.negVirtuals)
376 - self._depgraphVirtuals = copy.deepcopy(clone._depgraphVirtuals)
377 -
378 - self.use_defs = copy.deepcopy(clone.use_defs)
379 - self.usemask = copy.deepcopy(clone.usemask)
380 - self.pusemask_list = copy.deepcopy(clone.pusemask_list)
381 - self.useforce = copy.deepcopy(clone.useforce)
382 - self.puseforce_list = copy.deepcopy(clone.puseforce_list)
383 - self.puse = copy.deepcopy(clone.puse)
384 - self.make_defaults_use = copy.deepcopy(clone.make_defaults_use)
385 - self.pkgprofileuse = copy.deepcopy(clone.pkgprofileuse)
386 - self.mycpv = copy.deepcopy(clone.mycpv)
387 - self._setcpv_args_hash = copy.deepcopy(clone._setcpv_args_hash)
388 -
389 - self.configdict = copy.deepcopy(clone.configdict)
390 - self.configlist = [
391 - self.configdict['env.d'],
392 - self.configdict['pkginternal'],
393 - self.configdict['globals'],
394 - self.configdict['defaults'],
395 - self.configdict['conf'],
396 - self.configdict['pkg'],
397 - self.configdict['auto'],
398 - self.configdict['env'],
399 - ]
400 - self.lookuplist = self.configlist[:]
401 - self.lookuplist.reverse()
402 - self._use_expand_dict = copy.deepcopy(clone._use_expand_dict)
403 - self.backupenv = self.configdict["backupenv"]
404 - self.pusedict = copy.deepcopy(clone.pusedict)
405 - self.pkeywordsdict = copy.deepcopy(clone.pkeywordsdict)
406 - self._pkeywords_list = copy.deepcopy(clone._pkeywords_list)
407 - self.pmaskdict = copy.deepcopy(clone.pmaskdict)
408 - self.punmaskdict = copy.deepcopy(clone.punmaskdict)
409 - self.prevmaskdict = copy.deepcopy(clone.prevmaskdict)
410 - self.pprovideddict = copy.deepcopy(clone.pprovideddict)
411 - self.features = copy.deepcopy(clone.features)
412 -
413 - self._accept_license = copy.deepcopy(clone._accept_license)
414 - self._plicensedict = copy.deepcopy(clone._plicensedict)
415 - self._license_groups = copy.deepcopy(clone._license_groups)
416 - self._accept_properties = copy.deepcopy(clone._accept_properties)
417 - self._ppropertiesdict = copy.deepcopy(clone._ppropertiesdict)
418 - else:
419 -
420 - def check_var_directory(varname, var):
421 - if not os.path.isdir(var):
422 - writemsg(_("!!! Error: %s='%s' is not a directory. "
423 - "Please correct this.\n") % (varname, var),
424 - noiselevel=-1)
425 - raise portage.exception.DirectoryNotFound(var)
426 -
427 - if config_root is None:
428 - config_root = "/"
429 -
430 - config_root = normalize_path(os.path.abspath(
431 - config_root)).rstrip(os.path.sep) + os.path.sep
432 -
433 - check_var_directory("PORTAGE_CONFIGROOT", config_root)
434 -
435 - self.depcachedir = DEPCACHE_PATH
436 -
437 - if not config_profile_path:
438 - config_profile_path = \
439 - os.path.join(config_root, PROFILE_PATH)
440 - if os.path.isdir(config_profile_path):
441 - self.profile_path = config_profile_path
442 - else:
443 - self.profile_path = None
444 - else:
445 - self.profile_path = config_profile_path
446 -
447 - if config_incrementals is None:
448 - self.incrementals = portage.const.INCREMENTALS
449 - else:
450 - self.incrementals = config_incrementals
451 - if not isinstance(self.incrementals, tuple):
452 - self.incrementals = tuple(self.incrementals)
453 -
454 - self.module_priority = ("user", "default")
455 - self.modules = {}
456 - modules_loader = portage.env.loaders.KeyValuePairFileLoader(
457 - os.path.join(config_root, MODULES_FILE_PATH), None, None)
458 - modules_dict, modules_errors = modules_loader.load()
459 - self.modules["user"] = modules_dict
460 - if self.modules["user"] is None:
461 - self.modules["user"] = {}
462 - self.modules["default"] = {
463 - "portdbapi.metadbmodule": "portage.cache.metadata.database",
464 - "portdbapi.auxdbmodule": "portage.cache.flat_hash.database",
465 - }
466 -
467 - self.usemask=[]
468 - self.configlist=[]
469 -
470 - # back up our incremental variables:
471 - self.configdict={}
472 - self._use_expand_dict = {}
473 - # configlist will contain: [ env.d, globals, defaults, conf, pkg, auto, backupenv, env ]
474 - self.configlist.append({})
475 - self.configdict["env.d"] = self.configlist[-1]
476 -
477 - self.configlist.append({})
478 - self.configdict["pkginternal"] = self.configlist[-1]
479 -
480 - # The symlink might not exist or might not be a symlink.
481 - if self.profile_path is None:
482 - self.profiles = []
483 - else:
484 - self.profiles = []
485 - def addProfile(currentPath):
486 - parentsFile = os.path.join(currentPath, "parent")
487 - eapi_file = os.path.join(currentPath, "eapi")
488 - try:
489 - eapi = codecs.open(_unicode_encode(eapi_file,
490 - encoding=_encodings['fs'], errors='strict'),
491 - mode='r', encoding=_encodings['content'], errors='replace'
492 - ).readline().strip()
493 - except IOError:
494 - pass
495 - else:
496 - if not eapi_is_supported(eapi):
497 - raise portage.exception.ParseError(_(
498 - "Profile contains unsupported "
499 - "EAPI '%s': '%s'") % \
500 - (eapi, os.path.realpath(eapi_file),))
501 - if os.path.exists(parentsFile):
502 - parents = grabfile(parentsFile)
503 - if not parents:
504 - raise portage.exception.ParseError(
505 - _("Empty parent file: '%s'") % parentsFile)
506 - for parentPath in parents:
507 - parentPath = normalize_path(os.path.join(
508 - currentPath, parentPath))
509 - if os.path.exists(parentPath):
510 - addProfile(parentPath)
511 - else:
512 - raise portage.exception.ParseError(
513 - _("Parent '%s' not found: '%s'") % \
514 - (parentPath, parentsFile))
515 - self.profiles.append(currentPath)
516 - try:
517 - addProfile(os.path.realpath(self.profile_path))
518 - except portage.exception.ParseError as e:
519 - writemsg(_("!!! Unable to parse profile: '%s'\n") % \
520 - self.profile_path, noiselevel=-1)
521 - writemsg("!!! ParseError: %s\n" % str(e), noiselevel=-1)
522 - del e
523 - self.profiles = []
524 - if local_config and self.profiles:
525 - custom_prof = os.path.join(
526 - config_root, CUSTOM_PROFILE_PATH)
527 - if os.path.exists(custom_prof):
528 - self.user_profile_dir = custom_prof
529 - self.profiles.append(custom_prof)
530 - del custom_prof
531 -
532 - self.profiles = tuple(self.profiles)
533 - self.packages_list = [grabfile_package(os.path.join(x, "packages")) for x in self.profiles]
534 - self.packages = tuple(stack_lists(self.packages_list, incremental=1))
535 - del self.packages_list
536 - #self.packages = grab_stacked("packages", self.profiles, grabfile, incremental_lines=1)
537 -
538 - # revmaskdict
539 - self.prevmaskdict={}
540 - for x in self.packages:
541 - # Negative atoms are filtered by the above stack_lists() call.
542 - if not isinstance(x, dep.Atom):
543 - x = dep.Atom(x.lstrip('*'))
544 - self.prevmaskdict.setdefault(x.cp, []).append(x)
545 -
546 - self._pkeywords_list = []
547 - rawpkeywords = [grabdict_package(
548 - os.path.join(x, "package.keywords"), recursive=1) \
549 - for x in self.profiles]
550 - for pkeyworddict in rawpkeywords:
551 - cpdict = {}
552 - for k, v in pkeyworddict.items():
553 - cpdict.setdefault(k.cp, {})[k] = v
554 - self._pkeywords_list.append(cpdict)
555 -
556 - # get profile-masked use flags -- INCREMENTAL Child over parent
557 - self.usemask_list = tuple(
558 - tuple(grabfile(os.path.join(x, "use.mask"), recursive=1))
559 - for x in self.profiles)
560 - self.usemask = set(stack_lists(
561 - self.usemask_list, incremental=True))
562 - use_defs_lists = [grabdict(os.path.join(x, "use.defaults")) for x in self.profiles]
563 - self.use_defs = stack_dictlist(use_defs_lists, incremental=True)
564 - del use_defs_lists
565 -
566 - self.pusemask_list = []
567 - rawpusemask = [grabdict_package(os.path.join(x, "package.use.mask"),
568 - recursive=1) for x in self.profiles]
569 - for pusemaskdict in rawpusemask:
570 - cpdict = {}
571 - for k, v in pusemaskdict.items():
572 - cpdict.setdefault(k.cp, {})[k] = v
573 - self.pusemask_list.append(cpdict)
574 - del rawpusemask
575 -
576 - self.pkgprofileuse = []
577 - rawprofileuse = [grabdict_package(os.path.join(x, "package.use"),
578 - juststrings=True, recursive=1) for x in self.profiles]
579 - for rawpusedict in rawprofileuse:
580 - cpdict = {}
581 - for k, v in rawpusedict.items():
582 - cpdict.setdefault(k.cp, {})[k] = v
583 - self.pkgprofileuse.append(cpdict)
584 - del rawprofileuse
585 -
586 - self.useforce_list = tuple(
587 - tuple(grabfile(os.path.join(x, "use.force"), recursive=1))
588 - for x in self.profiles)
589 - self.useforce = set(stack_lists(
590 - self.useforce_list, incremental=True))
591 -
592 - self.puseforce_list = []
593 - rawpuseforce = [grabdict_package(
594 - os.path.join(x, "package.use.force"), recursive=1) \
595 - for x in self.profiles]
596 - for rawpusefdict in rawpuseforce:
597 - cpdict = {}
598 - for k, v in rawpusefdict.items():
599 - cpdict.setdefault(k.cp, {})[k] = v
600 - self.puseforce_list.append(cpdict)
601 - del rawpuseforce
602 -
603 - make_conf = getconfig(
604 - os.path.join(config_root, MAKE_CONF_FILE),
605 - tolerant=tolerant, allow_sourcing=True)
606 - if make_conf is None:
607 - make_conf = {}
608 -
609 - # Allow ROOT setting to come from make.conf if it's not overridden
610 - # by the constructor argument (from the calling environment).
611 - if target_root is None and "ROOT" in make_conf:
612 - target_root = make_conf["ROOT"]
613 - if not target_root.strip():
614 - target_root = None
615 - if target_root is None:
616 - target_root = "/"
617 -
618 - target_root = normalize_path(os.path.abspath(
619 - target_root)).rstrip(os.path.sep) + os.path.sep
620 -
621 - portage.util.ensure_dirs(target_root)
622 - check_var_directory("ROOT", target_root)
623 -
624 - # The expand_map is used for variable substitution
625 - # in getconfig() calls, and the getconfig() calls
626 - # update expand_map with the value of each variable
627 - # assignment that occurs. Variable substitution occurs
628 - # in the following order, which corresponds to the
629 - # order of appearance in self.lookuplist:
630 - #
631 - # * env.d
632 - # * make.globals
633 - # * make.defaults
634 - # * make.conf
635 - #
636 - # Notably absent is "env", since we want to avoid any
637 - # interaction with the calling environment that might
638 - # lead to unexpected results.
639 - expand_map = {}
640 -
641 - env_d = getconfig(os.path.join(target_root, "etc", "profile.env"),
642 - expand=expand_map)
643 - # env_d will be None if profile.env doesn't exist.
644 - if env_d:
645 - self.configdict["env.d"].update(env_d)
646 - expand_map.update(env_d)
647 -
648 - # backupenv is used for calculating incremental variables.
649 - if env is None:
650 - env = os.environ
651 -
652 - # Avoid potential UnicodeDecodeError exceptions later.
653 - env_unicode = dict((_unicode_decode(k), _unicode_decode(v))
654 - for k, v in env.items())
655 -
656 - self.backupenv = env_unicode
657 -
658 - if env_d:
659 - # Remove duplicate values so they don't override updated
660 - # profile.env values later (profile.env is reloaded in each
661 - # call to self.regenerate).
662 - for k, v in env_d.items():
663 - try:
664 - if self.backupenv[k] == v:
665 - del self.backupenv[k]
666 - except KeyError:
667 - pass
668 - del k, v
669 -
670 - self.configdict["env"] = util.LazyItemsDict(self.backupenv)
671 -
672 - # make.globals should not be relative to config_root
673 - # because it only contains constants.
674 - for x in (portage.const.GLOBAL_CONFIG_PATH, "/etc"):
675 - self.mygcfg = getconfig(os.path.join(x, "make.globals"),
676 - expand=expand_map)
677 - if self.mygcfg:
678 - break
679 -
680 - if self.mygcfg is None:
681 - self.mygcfg = {}
682 -
683 - for k, v in self._default_globals:
684 - self.mygcfg.setdefault(k, v)
685 -
686 - self.configlist.append(self.mygcfg)
687 - self.configdict["globals"]=self.configlist[-1]
688 -
689 - self.make_defaults_use = []
690 - self.mygcfg = {}
691 - if self.profiles:
692 - mygcfg_dlists = [getconfig(os.path.join(x, "make.defaults"),
693 - expand=expand_map) for x in self.profiles]
694 -
695 - for cfg in mygcfg_dlists:
696 - if cfg:
697 - self.make_defaults_use.append(cfg.get("USE", ""))
698 - else:
699 - self.make_defaults_use.append("")
700 - self.mygcfg = stack_dicts(mygcfg_dlists,
701 - incrementals=portage.const.INCREMENTALS)
702 - if self.mygcfg is None:
703 - self.mygcfg = {}
704 - self.configlist.append(self.mygcfg)
705 - self.configdict["defaults"]=self.configlist[-1]
706 -
707 - self.mygcfg = getconfig(
708 - os.path.join(config_root, MAKE_CONF_FILE),
709 - tolerant=tolerant, allow_sourcing=True, expand=expand_map)
710 - if self.mygcfg is None:
711 - self.mygcfg = {}
712 -
713 - # Don't allow the user to override certain variables in make.conf
714 - profile_only_variables = self.configdict["defaults"].get(
715 - "PROFILE_ONLY_VARIABLES", "").split()
716 - for k in profile_only_variables:
717 - self.mygcfg.pop(k, None)
718 -
719 - self.configlist.append(self.mygcfg)
720 - self.configdict["conf"]=self.configlist[-1]
721 -
722 - self.configlist.append(util.LazyItemsDict())
723 - self.configdict["pkg"]=self.configlist[-1]
724 -
725 - #auto-use:
726 - self.configlist.append({})
727 - self.configdict["auto"]=self.configlist[-1]
728 -
729 - self.configdict["backupenv"] = self.backupenv
730 -
731 - # Don't allow the user to override certain variables in the env
732 - for k in profile_only_variables:
733 - self.backupenv.pop(k, None)
734 -
735 - self.configlist.append(self.configdict["env"])
736 -
737 - # make lookuplist for loading package.*
738 - self.lookuplist=self.configlist[:]
739 - self.lookuplist.reverse()
740 -
741 - # Blacklist vars that could interfere with portage internals.
742 - for blacklisted in self._env_blacklist:
743 - for cfg in self.lookuplist:
744 - cfg.pop(blacklisted, None)
745 - self.backupenv.pop(blacklisted, None)
746 - del blacklisted, cfg
747 -
748 - self["PORTAGE_CONFIGROOT"] = config_root
749 - self.backup_changes("PORTAGE_CONFIGROOT")
750 - self["ROOT"] = target_root
751 - self.backup_changes("ROOT")
752 -
753 - # Prefix forward compatability, set EPREFIX to the empty string
754 - self["EPREFIX"] = ''
755 - self.backup_changes("EPREFIX")
756 - self["EROOT"] = target_root
757 - self.backup_changes("EROOT")
758 -
759 - self.pusedict = {}
760 - self.pkeywordsdict = {}
761 - self._plicensedict = {}
762 - self._ppropertiesdict = {}
763 - self.punmaskdict = {}
764 - abs_user_config = os.path.join(config_root, USER_CONFIG_PATH)
765 -
766 - # locations for "categories" and "arch.list" files
767 - locations = [os.path.join(self["PORTDIR"], "profiles")]
768 - pmask_locations = [os.path.join(self["PORTDIR"], "profiles")]
769 - pmask_locations.extend(self.profiles)
770 -
771 - """ repoman controls PORTDIR_OVERLAY via the environment, so no
772 - special cases are needed here."""
773 - overlay_profiles = []
774 - for ov in self["PORTDIR_OVERLAY"].split():
775 - ov = normalize_path(ov)
776 - profiles_dir = os.path.join(ov, "profiles")
777 - if os.path.isdir(profiles_dir):
778 - overlay_profiles.append(profiles_dir)
779 - locations += overlay_profiles
780 -
781 - pmask_locations.extend(overlay_profiles)
782 -
783 - if local_config:
784 - locations.append(abs_user_config)
785 - pmask_locations.append(abs_user_config)
786 - pusedict = grabdict_package(
787 - os.path.join(abs_user_config, "package.use"), recursive=1)
788 - for k, v in pusedict.items():
789 - self.pusedict.setdefault(k.cp, {})[k] = v
790 -
791 - #package.keywords
792 - pkgdict = grabdict_package(
793 - os.path.join(abs_user_config, "package.keywords"),
794 - recursive=1)
795 - for k, v in pkgdict.items():
796 - # default to ~arch if no specific keyword is given
797 - if not v:
798 - mykeywordlist = []
799 - if self.configdict["defaults"] and \
800 - "ACCEPT_KEYWORDS" in self.configdict["defaults"]:
801 - groups = self.configdict["defaults"]["ACCEPT_KEYWORDS"].split()
802 - else:
803 - groups = []
804 - for keyword in groups:
805 - if not keyword[0] in "~-":
806 - mykeywordlist.append("~"+keyword)
807 - v = mykeywordlist
808 - self.pkeywordsdict.setdefault(k.cp, {})[k] = v
809 -
810 - #package.license
811 - licdict = grabdict_package(os.path.join(
812 - abs_user_config, "package.license"), recursive=1)
813 - for k, v in licdict.items():
814 - cp = k.cp
815 - cp_dict = self._plicensedict.get(cp)
816 - if not cp_dict:
817 - cp_dict = {}
818 - self._plicensedict[cp] = cp_dict
819 - cp_dict[k] = self.expandLicenseTokens(v)
820 -
821 - #package.properties
822 - propdict = grabdict_package(os.path.join(
823 - abs_user_config, "package.properties"), recursive=1)
824 - for k, v in propdict.items():
825 - cp = k.cp
826 - cp_dict = self._ppropertiesdict.get(cp)
827 - if not cp_dict:
828 - cp_dict = {}
829 - self._ppropertiesdict[cp] = cp_dict
830 - cp_dict[k] = v
831 -
832 - self._local_repo_configs = {}
833 - self._local_repo_conf_path = \
834 - os.path.join(abs_user_config, 'repos.conf')
835 - try:
836 - from configparser import SafeConfigParser, ParsingError
837 - except ImportError:
838 - from ConfigParser import SafeConfigParser, ParsingError
839 - repo_conf_parser = SafeConfigParser()
840 - try:
841 - repo_conf_parser.readfp(
842 - codecs.open(
843 - _unicode_encode(self._local_repo_conf_path,
844 - encoding=_encodings['fs'], errors='strict'),
845 - mode='r', encoding=_encodings['content'], errors='replace')
846 - )
847 - except EnvironmentError as e:
848 - if e.errno != errno.ENOENT:
849 - raise
850 - del e
851 - except ParsingError as e:
852 - portage.util.writemsg_level(
853 - _("!!! Error parsing '%s': %s\n") % \
854 - (self._local_repo_conf_path, e),
855 - level=logging.ERROR, noiselevel=-1)
856 - del e
857 - else:
858 - repo_defaults = repo_conf_parser.defaults()
859 - if repo_defaults:
860 - self._local_repo_configs['DEFAULT'] = \
861 - _local_repo_config('DEFAULT', repo_defaults)
862 - for repo_name in repo_conf_parser.sections():
863 - repo_opts = repo_defaults.copy()
864 - for opt_name in repo_conf_parser.options(repo_name):
865 - repo_opts[opt_name] = \
866 - repo_conf_parser.get(repo_name, opt_name)
867 - self._local_repo_configs[repo_name] = \
868 - _local_repo_config(repo_name, repo_opts)
869 -
870 - #getting categories from an external file now
871 - categories = [grabfile(os.path.join(x, "categories")) for x in locations]
872 - category_re = dbapi.dbapi._category_re
873 - self.categories = tuple(sorted(
874 - x for x in stack_lists(categories, incremental=1)
875 - if category_re.match(x) is not None))
876 - del categories
877 -
878 - archlist = [grabfile(os.path.join(x, "arch.list")) for x in locations]
879 - archlist = stack_lists(archlist, incremental=1)
880 - self.configdict["conf"]["PORTAGE_ARCHLIST"] = " ".join(archlist)
881 -
882 - # package.mask and package.unmask
883 - pkgmasklines = []
884 - pkgunmasklines = []
885 - for x in pmask_locations:
886 - pkgmasklines.append(grabfile_package(
887 - os.path.join(x, "package.mask"), recursive=1))
888 - pkgunmasklines.append(grabfile_package(
889 - os.path.join(x, "package.unmask"), recursive=1))
890 - pkgmasklines = stack_lists(pkgmasklines, incremental=1)
891 - pkgunmasklines = stack_lists(pkgunmasklines, incremental=1)
892 -
893 - self.pmaskdict = {}
894 - for x in pkgmasklines:
895 - self.pmaskdict.setdefault(x.cp, []).append(x)
896 -
897 - for x in pkgunmasklines:
898 - self.punmaskdict.setdefault(x.cp, []).append(x)
899 -
900 - pkgprovidedlines = [grabfile(os.path.join(x, "package.provided"), recursive=1) for x in self.profiles]
901 - pkgprovidedlines = stack_lists(pkgprovidedlines, incremental=1)
902 - has_invalid_data = False
903 - for x in range(len(pkgprovidedlines)-1, -1, -1):
904 - myline = pkgprovidedlines[x]
905 - if not isvalidatom("=" + myline):
906 - writemsg(_("Invalid package name in package.provided: %s\n") % \
907 - myline, noiselevel=-1)
908 - has_invalid_data = True
909 - del pkgprovidedlines[x]
910 - continue
911 - cpvr = catpkgsplit(pkgprovidedlines[x])
912 - if not cpvr or cpvr[0] == "null":
913 - writemsg(_("Invalid package name in package.provided: ")+pkgprovidedlines[x]+"\n",
914 - noiselevel=-1)
915 - has_invalid_data = True
916 - del pkgprovidedlines[x]
917 - continue
918 - if cpvr[0] == "virtual":
919 - writemsg(_("Virtual package in package.provided: %s\n") % \
920 - myline, noiselevel=-1)
921 - has_invalid_data = True
922 - del pkgprovidedlines[x]
923 - continue
924 - if has_invalid_data:
925 - writemsg(_("See portage(5) for correct package.provided usage.\n"),
926 - noiselevel=-1)
927 - self.pprovideddict = {}
928 - for x in pkgprovidedlines:
929 - cpv=catpkgsplit(x)
930 - if not x:
931 - continue
932 - mycatpkg = cpv_getkey(x)
933 - if mycatpkg in self.pprovideddict:
934 - self.pprovideddict[mycatpkg].append(x)
935 - else:
936 - self.pprovideddict[mycatpkg]=[x]
937 -
938 - # parse licensegroups
939 - license_groups = self._license_groups
940 - for x in locations:
941 - for k, v in grabdict(
942 - os.path.join(x, "license_groups")).items():
943 - license_groups.setdefault(k, []).extend(v)
944 -
945 - # reasonable defaults; this is important as without USE_ORDER,
946 - # USE will always be "" (nothing set)!
947 - if "USE_ORDER" not in self:
948 - self.backupenv["USE_ORDER"] = "env:pkg:conf:defaults:pkginternal:env.d"
949 -
950 - self["PORTAGE_GID"] = str(portage_gid)
951 - self.backup_changes("PORTAGE_GID")
952 -
953 - if self.get("PORTAGE_DEPCACHEDIR", None):
954 - self.depcachedir = self["PORTAGE_DEPCACHEDIR"]
955 - self["PORTAGE_DEPCACHEDIR"] = self.depcachedir
956 - self.backup_changes("PORTAGE_DEPCACHEDIR")
957 -
958 - overlays = self.get("PORTDIR_OVERLAY","").split()
959 - if overlays:
960 - new_ov = []
961 - for ov in overlays:
962 - ov = normalize_path(ov)
963 - if os.path.isdir(ov):
964 - new_ov.append(ov)
965 - else:
966 - writemsg(_("!!! Invalid PORTDIR_OVERLAY"
967 - " (not a dir): '%s'\n") % ov, noiselevel=-1)
968 - self["PORTDIR_OVERLAY"] = " ".join(new_ov)
969 - self.backup_changes("PORTDIR_OVERLAY")
970 -
971 - if "CBUILD" not in self and "CHOST" in self:
972 - self["CBUILD"] = self["CHOST"]
973 - self.backup_changes("CBUILD")
974 -
975 - self["PORTAGE_BIN_PATH"] = PORTAGE_BIN_PATH
976 - self.backup_changes("PORTAGE_BIN_PATH")
977 - self["PORTAGE_PYM_PATH"] = PORTAGE_PYM_PATH
978 - self.backup_changes("PORTAGE_PYM_PATH")
979 -
980 - for var in ("PORTAGE_INST_UID", "PORTAGE_INST_GID"):
981 - try:
982 - self[var] = str(int(self.get(var, "0")))
983 - except ValueError:
984 - writemsg(_("!!! %s='%s' is not a valid integer. "
985 - "Falling back to '0'.\n") % (var, self[var]),
986 - noiselevel=-1)
987 - self[var] = "0"
988 - self.backup_changes(var)
989 -
990 - # initialize self.features
991 - self.regenerate()
992 -
993 - if bsd_chflags:
994 - self.features.add('chflags')
995 -
996 - self["FEATURES"] = " ".join(sorted(self.features))
997 - self.backup_changes("FEATURES")
998 - global _glep_55_enabled, _validate_cache_for_unsupported_eapis
999 - if 'parse-eapi-ebuild-head' in self.features:
1000 - _validate_cache_for_unsupported_eapis = False
1001 - if 'parse-eapi-glep-55' in self.features:
1002 - _validate_cache_for_unsupported_eapis = False
1003 - _glep_55_enabled = True
1004 -
1005 - for k in self._case_insensitive_vars:
1006 - if k in self:
1007 - self[k] = self[k].lower()
1008 - self.backup_changes(k)
1009 -
1010 - if mycpv:
1011 - self.setcpv(mycpv)
1012 -
1013 - def _init_dirs(self):
1014 - """
1015 - Create a few directories that are critical to portage operation
1016 - """
1017 - if not os.access(self["ROOT"], os.W_OK):
1018 - return
1019 -
1020 - # gid, mode, mask, preserve_perms
1021 - dir_mode_map = {
1022 - "tmp" : ( -1, 0o1777, 0, True),
1023 - "var/tmp" : ( -1, 0o1777, 0, True),
1024 - PRIVATE_PATH : (portage_gid, 0o2750, 0o2, False),
1025 - CACHE_PATH : (portage_gid, 0o755, 0o2, False)
1026 - }
1027 -
1028 - for mypath, (gid, mode, modemask, preserve_perms) \
1029 - in dir_mode_map.items():
1030 - mydir = os.path.join(self["ROOT"], mypath)
1031 - if preserve_perms and os.path.isdir(mydir):
1032 - # Only adjust permissions on some directories if
1033 - # they don't exist yet. This gives freedom to the
1034 - # user to adjust permissions to suit their taste.
1035 - continue
1036 - try:
1037 - portage.util.ensure_dirs(mydir, gid=gid, mode=mode, mask=modemask)
1038 - except portage.exception.PortageException as e:
1039 - writemsg(_("!!! Directory initialization failed: '%s'\n") % mydir,
1040 - noiselevel=-1)
1041 - writemsg("!!! %s\n" % str(e),
1042 - noiselevel=-1)
1043 -
1044 - def expandLicenseTokens(self, tokens):
1045 - """ Take a token from ACCEPT_LICENSE or package.license and expand it
1046 - if it's a group token (indicated by @) or just return it if it's not a
1047 - group. If a group is negated then negate all group elements."""
1048 - expanded_tokens = []
1049 - for x in tokens:
1050 - expanded_tokens.extend(self._expandLicenseToken(x, None))
1051 - return expanded_tokens
1052 -
1053 - def _expandLicenseToken(self, token, traversed_groups):
1054 - negate = False
1055 - rValue = []
1056 - if token.startswith("-"):
1057 - negate = True
1058 - license_name = token[1:]
1059 - else:
1060 - license_name = token
1061 - if not license_name.startswith("@"):
1062 - rValue.append(token)
1063 - return rValue
1064 - group_name = license_name[1:]
1065 - if traversed_groups is None:
1066 - traversed_groups = set()
1067 - license_group = self._license_groups.get(group_name)
1068 - if group_name in traversed_groups:
1069 - writemsg(_("Circular license group reference"
1070 - " detected in '%s'\n") % group_name, noiselevel=-1)
1071 - rValue.append("@"+group_name)
1072 - elif license_group:
1073 - traversed_groups.add(group_name)
1074 - for l in license_group:
1075 - if l.startswith("-"):
1076 - writemsg(_("Skipping invalid element %s"
1077 - " in license group '%s'\n") % (l, group_name),
1078 - noiselevel=-1)
1079 - else:
1080 - rValue.extend(self._expandLicenseToken(l, traversed_groups))
1081 - else:
1082 - if self._license_groups and \
1083 - group_name not in self._undef_lic_groups:
1084 - self._undef_lic_groups.add(group_name)
1085 - writemsg(_("Undefined license group '%s'\n") % group_name,
1086 - noiselevel=-1)
1087 - rValue.append("@"+group_name)
1088 - if negate:
1089 - rValue = ["-" + token for token in rValue]
1090 - return rValue
1091 -
1092 - def validate(self):
1093 - """Validate miscellaneous settings and display warnings if necessary.
1094 - (This code was previously in the global scope of portage.py)"""
1095 -
1096 - groups = self["ACCEPT_KEYWORDS"].split()
1097 - archlist = self.archlist()
1098 - if not archlist:
1099 - writemsg(_("--- 'profiles/arch.list' is empty or "
1100 - "not available. Empty portage tree?\n"), noiselevel=1)
1101 - else:
1102 - for group in groups:
1103 - if group not in archlist and \
1104 - not (group.startswith("-") and group[1:] in archlist) and \
1105 - group not in ("*", "~*", "**"):
1106 - writemsg(_("!!! INVALID ACCEPT_KEYWORDS: %s\n") % str(group),
1107 - noiselevel=-1)
1108 -
1109 - abs_profile_path = os.path.join(self["PORTAGE_CONFIGROOT"],
1110 - PROFILE_PATH)
1111 - if not self.profile_path or (not os.path.islink(abs_profile_path) and \
1112 - not os.path.exists(os.path.join(abs_profile_path, "parent")) and \
1113 - os.path.exists(os.path.join(self["PORTDIR"], "profiles"))):
1114 - writemsg(_("\a\n\n!!! %s is not a symlink and will probably prevent most merges.\n") % abs_profile_path,
1115 - noiselevel=-1)
1116 - writemsg(_("!!! It should point into a profile within %s/profiles/\n") % self["PORTDIR"])
1117 - writemsg(_("!!! (You can safely ignore this message when syncing. It's harmless.)\n\n\n"))
1118 -
1119 - abs_user_virtuals = os.path.join(self["PORTAGE_CONFIGROOT"],
1120 - USER_VIRTUALS_FILE)
1121 - if os.path.exists(abs_user_virtuals):
1122 - writemsg("\n!!! /etc/portage/virtuals is deprecated in favor of\n")
1123 - writemsg("!!! /etc/portage/profile/virtuals. Please move it to\n")
1124 - writemsg("!!! this new location.\n\n")
1125 -
1126 - if not process.sandbox_capable and \
1127 - ("sandbox" in self.features or "usersandbox" in self.features):
1128 - if self.profile_path is not None and \
1129 - os.path.realpath(self.profile_path) == \
1130 - os.path.realpath(os.path.join(
1131 - self["PORTAGE_CONFIGROOT"], PROFILE_PATH)):
1132 - # Don't show this warning when running repoman and the
1133 - # sandbox feature came from a profile that doesn't belong
1134 - # to the user.
1135 - writemsg(colorize("BAD", _("!!! Problem with sandbox"
1136 - " binary. Disabling...\n\n")), noiselevel=-1)
1137 -
1138 - if "fakeroot" in self.features and \
1139 - not portage.process.fakeroot_capable:
1140 - writemsg(_("!!! FEATURES=fakeroot is enabled, but the "
1141 - "fakeroot binary is not installed.\n"), noiselevel=-1)
1142 -
1143 - def loadVirtuals(self,root):
1144 - """Not currently used by portage."""
1145 - writemsg("DEPRECATED: portage.config.loadVirtuals\n")
1146 - self.getvirtuals(root)
1147 -
1148 - def load_best_module(self,property_string):
1149 - best_mod = best_from_dict(property_string,self.modules,self.module_priority)
1150 - mod = None
1151 - try:
1152 - mod = load_mod(best_mod)
1153 - except ImportError:
1154 - if best_mod.startswith("cache."):
1155 - best_mod = "portage." + best_mod
1156 - try:
1157 - mod = load_mod(best_mod)
1158 - except ImportError:
1159 - pass
1160 - if mod is None:
1161 - raise
1162 - return mod
1163 -
1164 - def lock(self):
1165 - self.locked = 1
1166 -
1167 - def unlock(self):
1168 - self.locked = 0
1169 -
1170 - def modifying(self):
1171 - if self.locked:
1172 - raise Exception(_("Configuration is locked."))
1173 -
1174 - def backup_changes(self,key=None):
1175 - self.modifying()
1176 - if key and key in self.configdict["env"]:
1177 - self.backupenv[key] = copy.deepcopy(self.configdict["env"][key])
1178 - else:
1179 - raise KeyError(_("No such key defined in environment: %s") % key)
1180 -
1181 - def reset(self,keeping_pkg=0,use_cache=1):
1182 - """
1183 - Restore environment from self.backupenv, call self.regenerate()
1184 - @param keeping_pkg: Should we keep the set_cpv() data or delete it.
1185 - @type keeping_pkg: Boolean
1186 - @param use_cache: Should self.regenerate use the cache or not
1187 - @type use_cache: Boolean
1188 - @rype: None
1189 - """
1190 - self.modifying()
1191 - self.configdict["env"].clear()
1192 - self.configdict["env"].update(self.backupenv)
1193 -
1194 - self.modifiedkeys = []
1195 - if not keeping_pkg:
1196 - self.mycpv = None
1197 - self.puse = ""
1198 - self.configdict["pkg"].clear()
1199 - self.configdict["pkginternal"].clear()
1200 - self.configdict["defaults"]["USE"] = \
1201 - " ".join(self.make_defaults_use)
1202 - self.usemask = set(stack_lists(
1203 - self.usemask_list, incremental=True))
1204 - self.useforce = set(stack_lists(
1205 - self.useforce_list, incremental=True))
1206 - self.regenerate(use_cache=use_cache)
1207 -
1208 - class _lazy_vars(object):
1209 -
1210 - __slots__ = ('built_use', 'settings', 'values')
1211 -
1212 - def __init__(self, built_use, settings):
1213 - self.built_use = built_use
1214 - self.settings = settings
1215 - self.values = None
1216 -
1217 - def __getitem__(self, k):
1218 - if self.values is None:
1219 - self.values = self._init_values()
1220 - return self.values[k]
1221 -
1222 - def _init_values(self):
1223 - values = {}
1224 - settings = self.settings
1225 - use = self.built_use
1226 - if use is None:
1227 - use = frozenset(settings['PORTAGE_USE'].split())
1228 - values['ACCEPT_LICENSE'] = self._accept_license(use, settings)
1229 - values['PORTAGE_RESTRICT'] = self._restrict(use, settings)
1230 - return values
1231 -
1232 - def _accept_license(self, use, settings):
1233 - """
1234 - Generate a pruned version of ACCEPT_LICENSE, by intersection with
1235 - LICENSE. This is required since otherwise ACCEPT_LICENSE might be
1236 - too big (bigger than ARG_MAX), causing execve() calls to fail with
1237 - E2BIG errors as in bug #262647.
1238 - """
1239 - try:
1240 - licenses = set(flatten(
1241 - dep.use_reduce(dep.paren_reduce(
1242 - settings['LICENSE']),
1243 - uselist=use)))
1244 - except exception.InvalidDependString:
1245 - licenses = set()
1246 - licenses.discard('||')
1247 - if settings._accept_license:
1248 - acceptable_licenses = set()
1249 - for x in settings._accept_license:
1250 - if x == '*':
1251 - acceptable_licenses.update(licenses)
1252 - elif x == '-*':
1253 - acceptable_licenses.clear()
1254 - elif x[:1] == '-':
1255 - acceptable_licenses.discard(x[1:])
1256 - elif x in licenses:
1257 - acceptable_licenses.add(x)
1258 -
1259 - licenses = acceptable_licenses
1260 - return ' '.join(sorted(licenses))
1261 -
1262 - def _restrict(self, use, settings):
1263 - try:
1264 - restrict = set(flatten(
1265 - dep.use_reduce(dep.paren_reduce(
1266 - settings['RESTRICT']),
1267 - uselist=use)))
1268 - except exception.InvalidDependString:
1269 - restrict = set()
1270 - return ' '.join(sorted(restrict))
1271 -
1272 - class _lazy_use_expand(object):
1273 - """
1274 - Lazily evaluate USE_EXPAND variables since they are only needed when
1275 - an ebuild shell is spawned. Variables values are made consistent with
1276 - the previously calculated USE settings.
1277 - """
1278 -
1279 - def __init__(self, use, usemask, iuse_implicit,
1280 - use_expand_split, use_expand_dict):
1281 - self._use = use
1282 - self._usemask = usemask
1283 - self._iuse_implicit = iuse_implicit
1284 - self._use_expand_split = use_expand_split
1285 - self._use_expand_dict = use_expand_dict
1286 -
1287 - def __getitem__(self, key):
1288 - prefix = key.lower() + '_'
1289 - prefix_len = len(prefix)
1290 - expand_flags = set( x[prefix_len:] for x in self._use \
1291 - if x[:prefix_len] == prefix )
1292 - var_split = self._use_expand_dict.get(key, '').split()
1293 - # Preserve the order of var_split because it can matter for things
1294 - # like LINGUAS.
1295 - var_split = [ x for x in var_split if x in expand_flags ]
1296 - var_split.extend(expand_flags.difference(var_split))
1297 - has_wildcard = '*' in expand_flags
1298 - if has_wildcard:
1299 - var_split = [ x for x in var_split if x != "*" ]
1300 - has_iuse = set()
1301 - for x in self._iuse_implicit:
1302 - if x[:prefix_len] == prefix:
1303 - has_iuse.add(x[prefix_len:])
1304 - if has_wildcard:
1305 - # * means to enable everything in IUSE that's not masked
1306 - if has_iuse:
1307 - usemask = self._usemask
1308 - for suffix in has_iuse:
1309 - x = prefix + suffix
1310 - if x not in usemask:
1311 - if suffix not in expand_flags:
1312 - var_split.append(suffix)
1313 - else:
1314 - # If there is a wildcard and no matching flags in IUSE then
1315 - # LINGUAS should be unset so that all .mo files are
1316 - # installed.
1317 - var_split = []
1318 - # Make the flags unique and filter them according to IUSE.
1319 - # Also, continue to preserve order for things like LINGUAS
1320 - # and filter any duplicates that variable may contain.
1321 - filtered_var_split = []
1322 - remaining = has_iuse.intersection(var_split)
1323 - for x in var_split:
1324 - if x in remaining:
1325 - remaining.remove(x)
1326 - filtered_var_split.append(x)
1327 - var_split = filtered_var_split
1328 -
1329 - if var_split:
1330 - value = ' '.join(var_split)
1331 - else:
1332 - # Don't export empty USE_EXPAND vars unless the user config
1333 - # exports them as empty. This is required for vars such as
1334 - # LINGUAS, where unset and empty have different meanings.
1335 - if has_wildcard:
1336 - # ebuild.sh will see this and unset the variable so
1337 - # that things like LINGUAS work properly
1338 - value = '*'
1339 - else:
1340 - if has_iuse:
1341 - value = ''
1342 - else:
1343 - # It's not in IUSE, so just allow the variable content
1344 - # to pass through if it is defined somewhere. This
1345 - # allows packages that support LINGUAS but don't
1346 - # declare it in IUSE to use the variable outside of the
1347 - # USE_EXPAND context.
1348 - value = None
1349 -
1350 - return value
1351 -
1352 - def setcpv(self, mycpv, use_cache=1, mydb=None):
1353 - """
1354 - Load a particular CPV into the config, this lets us see the
1355 - Default USE flags for a particular ebuild as well as the USE
1356 - flags from package.use.
1357 -
1358 - @param mycpv: A cpv to load
1359 - @type mycpv: string
1360 - @param use_cache: Enables caching
1361 - @type use_cache: Boolean
1362 - @param mydb: a dbapi instance that supports aux_get with the IUSE key.
1363 - @type mydb: dbapi or derivative.
1364 - @rtype: None
1365 - """
1366 -
1367 - self.modifying()
1368 -
1369 - pkg = None
1370 - built_use = None
1371 - if not isinstance(mycpv, basestring):
1372 - pkg = mycpv
1373 - mycpv = pkg.cpv
1374 - mydb = pkg.metadata
1375 - args_hash = (mycpv, id(pkg))
1376 - if pkg.built:
1377 - built_use = pkg.use.enabled
1378 - else:
1379 - args_hash = (mycpv, id(mydb))
1380 -
1381 - if args_hash == self._setcpv_args_hash:
1382 - return
1383 - self._setcpv_args_hash = args_hash
1384 -
1385 - has_changed = False
1386 - self.mycpv = mycpv
1387 - cat, pf = catsplit(mycpv)
1388 - cp = cpv_getkey(mycpv)
1389 - cpv_slot = self.mycpv
1390 - pkginternaluse = ""
1391 - iuse = ""
1392 - pkg_configdict = self.configdict["pkg"]
1393 - previous_iuse = pkg_configdict.get("IUSE")
1394 -
1395 - aux_keys = self._setcpv_aux_keys
1396 -
1397 - # Discard any existing metadata from the previous package, but
1398 - # preserve things like USE_EXPAND values and PORTAGE_USE which
1399 - # might be reused.
1400 - for k in aux_keys:
1401 - pkg_configdict.pop(k, None)
1402 -
1403 - pkg_configdict["CATEGORY"] = cat
1404 - pkg_configdict["PF"] = pf
1405 - if mydb:
1406 - if not hasattr(mydb, "aux_get"):
1407 - for k in aux_keys:
1408 - if k in mydb:
1409 - # Make these lazy, since __getitem__ triggers
1410 - # evaluation of USE conditionals which can't
1411 - # occur until PORTAGE_USE is calculated below.
1412 - pkg_configdict.addLazySingleton(k,
1413 - mydb.__getitem__, k)
1414 - else:
1415 - for k, v in zip(aux_keys, mydb.aux_get(self.mycpv, aux_keys)):
1416 - pkg_configdict[k] = v
1417 - repository = pkg_configdict.pop("repository", None)
1418 - if repository is not None:
1419 - pkg_configdict["PORTAGE_REPO_NAME"] = repository
1420 - slot = pkg_configdict["SLOT"]
1421 - iuse = pkg_configdict["IUSE"]
1422 - if pkg is None:
1423 - cpv_slot = "%s:%s" % (self.mycpv, slot)
1424 - else:
1425 - cpv_slot = pkg
1426 - pkginternaluse = []
1427 - for x in iuse.split():
1428 - if x.startswith("+"):
1429 - pkginternaluse.append(x[1:])
1430 - elif x.startswith("-"):
1431 - pkginternaluse.append(x)
1432 - pkginternaluse = " ".join(pkginternaluse)
1433 - if pkginternaluse != self.configdict["pkginternal"].get("USE", ""):
1434 - self.configdict["pkginternal"]["USE"] = pkginternaluse
1435 - has_changed = True
1436 -
1437 - defaults = []
1438 - pos = 0
1439 - for i, pkgprofileuse_dict in enumerate(self.pkgprofileuse):
1440 - cpdict = pkgprofileuse_dict.get(cp)
1441 - if cpdict:
1442 - keys = list(cpdict)
1443 - while keys:
1444 - bestmatch = best_match_to_list(cpv_slot, keys)
1445 - if bestmatch:
1446 - keys.remove(bestmatch)
1447 - defaults.insert(pos, cpdict[bestmatch])
1448 - else:
1449 - break
1450 - del keys
1451 - if self.make_defaults_use[i]:
1452 - defaults.insert(pos, self.make_defaults_use[i])
1453 - pos = len(defaults)
1454 - defaults = " ".join(defaults)
1455 - if defaults != self.configdict["defaults"].get("USE",""):
1456 - self.configdict["defaults"]["USE"] = defaults
1457 - has_changed = True
1458 -
1459 - useforce = self._getUseForce(cpv_slot)
1460 - if useforce != self.useforce:
1461 - self.useforce = useforce
1462 - has_changed = True
1463 -
1464 - usemask = self._getUseMask(cpv_slot)
1465 - if usemask != self.usemask:
1466 - self.usemask = usemask
1467 - has_changed = True
1468 - oldpuse = self.puse
1469 - self.puse = ""
1470 - cpdict = self.pusedict.get(cp)
1471 - if cpdict:
1472 - keys = list(cpdict)
1473 - while keys:
1474 - self.pusekey = best_match_to_list(cpv_slot, keys)
1475 - if self.pusekey:
1476 - keys.remove(self.pusekey)
1477 - self.puse = (" ".join(cpdict[self.pusekey])) + " " + self.puse
1478 - else:
1479 - break
1480 - del keys
1481 - if oldpuse != self.puse:
1482 - has_changed = True
1483 - self.configdict["pkg"]["PKGUSE"] = self.puse[:] # For saving to PUSE file
1484 - self.configdict["pkg"]["USE"] = self.puse[:] # this gets appended to USE
1485 -
1486 - if has_changed:
1487 - self.reset(keeping_pkg=1,use_cache=use_cache)
1488 -
1489 - # Ensure that "pkg" values are always preferred over "env" values.
1490 - # This must occur _after_ the above reset() call, since reset()
1491 - # copies values from self.backupenv.
1492 - env_configdict = self.configdict['env']
1493 - for k in pkg_configdict:
1494 - if k != 'USE':
1495 - env_configdict.pop(k, None)
1496 -
1497 - lazy_vars = self._lazy_vars(built_use, self)
1498 - env_configdict.addLazySingleton('ACCEPT_LICENSE',
1499 - lazy_vars.__getitem__, 'ACCEPT_LICENSE')
1500 - env_configdict.addLazySingleton('PORTAGE_RESTRICT',
1501 - lazy_vars.__getitem__, 'PORTAGE_RESTRICT')
1502 -
1503 - # If reset() has not been called, it's safe to return
1504 - # early if IUSE has not changed.
1505 - if not has_changed and previous_iuse == iuse:
1506 - return
1507 -
1508 - # Filter out USE flags that aren't part of IUSE. This has to
1509 - # be done for every setcpv() call since practically every
1510 - # package has different IUSE.
1511 - use = set(self["USE"].split())
1512 - iuse_implicit = self._get_implicit_iuse()
1513 - iuse_implicit.update(x.lstrip("+-") for x in iuse.split())
1514 -
1515 - # PORTAGE_IUSE is not always needed so it's lazily evaluated.
1516 - self.configdict["pkg"].addLazySingleton(
1517 - "PORTAGE_IUSE", _lazy_iuse_regex, iuse_implicit)
1518 -
1519 - ebuild_force_test = self.get("EBUILD_FORCE_TEST") == "1"
1520 - if ebuild_force_test and \
1521 - not hasattr(self, "_ebuild_force_test_msg_shown"):
1522 - self._ebuild_force_test_msg_shown = True
1523 - writemsg(_("Forcing test.\n"), noiselevel=-1)
1524 - if "test" in self.features:
1525 - if "test" in self.usemask and not ebuild_force_test:
1526 - # "test" is in IUSE and USE=test is masked, so execution
1527 - # of src_test() probably is not reliable. Therefore,
1528 - # temporarily disable FEATURES=test just for this package.
1529 - self["FEATURES"] = " ".join(x for x in self.features \
1530 - if x != "test")
1531 - use.discard("test")
1532 - else:
1533 - use.add("test")
1534 - if ebuild_force_test:
1535 - self.usemask.discard("test")
1536 -
1537 - # Allow _* flags from USE_EXPAND wildcards to pass through here.
1538 - use.difference_update([x for x in use \
1539 - if x not in iuse_implicit and x[-2:] != '_*'])
1540 -
1541 - # Use the calculated USE flags to regenerate the USE_EXPAND flags so
1542 - # that they are consistent. For optimal performance, use slice
1543 - # comparison instead of startswith().
1544 - use_expand_split = set(x.lower() for \
1545 - x in self.get('USE_EXPAND', '').split())
1546 - lazy_use_expand = self._lazy_use_expand(use, self.usemask,
1547 - iuse_implicit, use_expand_split, self._use_expand_dict)
1548 -
1549 - use_expand_iuses = {}
1550 - for x in iuse_implicit:
1551 - x_split = x.split('_')
1552 - if len(x_split) == 1:
1553 - continue
1554 - for i in range(len(x_split) - 1):
1555 - k = '_'.join(x_split[:i+1])
1556 - if k in use_expand_split:
1557 - v = use_expand_iuses.get(k)
1558 - if v is None:
1559 - v = set()
1560 - use_expand_iuses[k] = v
1561 - v.add(x)
1562 - break
1563 -
1564 - # If it's not in IUSE, variable content is allowed
1565 - # to pass through if it is defined somewhere. This
1566 - # allows packages that support LINGUAS but don't
1567 - # declare it in IUSE to use the variable outside of the
1568 - # USE_EXPAND context.
1569 - for k, use_expand_iuse in use_expand_iuses.items():
1570 - if k + '_*' in use:
1571 - use.update( x for x in use_expand_iuse if x not in usemask )
1572 - k = k.upper()
1573 - self.configdict['env'].addLazySingleton(k,
1574 - lazy_use_expand.__getitem__, k)
1575 -
1576 - # Filtered for the ebuild environment. Store this in a separate
1577 - # attribute since we still want to be able to see global USE
1578 - # settings for things like emerge --info.
1579 -
1580 - self.configdict["pkg"]["PORTAGE_USE"] = \
1581 - " ".join(sorted(x for x in use if x[-2:] != '_*'))
1582 -
1583 - def _get_implicit_iuse(self):
1584 - """
1585 - Some flags are considered to
1586 - be implicit members of IUSE:
1587 - * Flags derived from ARCH
1588 - * Flags derived from USE_EXPAND_HIDDEN variables
1589 - * Masked flags, such as those from {,package}use.mask
1590 - * Forced flags, such as those from {,package}use.force
1591 - * build and bootstrap flags used by bootstrap.sh
1592 - """
1593 - iuse_implicit = set()
1594 - # Flags derived from ARCH.
1595 - arch = self.configdict["defaults"].get("ARCH")
1596 - if arch:
1597 - iuse_implicit.add(arch)
1598 - iuse_implicit.update(self.get("PORTAGE_ARCHLIST", "").split())
1599 -
1600 - # Flags derived from USE_EXPAND_HIDDEN variables
1601 - # such as ELIBC, KERNEL, and USERLAND.
1602 - use_expand_hidden = self.get("USE_EXPAND_HIDDEN", "").split()
1603 - for x in use_expand_hidden:
1604 - iuse_implicit.add(x.lower() + "_.*")
1605 -
1606 - # Flags that have been masked or forced.
1607 - iuse_implicit.update(self.usemask)
1608 - iuse_implicit.update(self.useforce)
1609 -
1610 - # build and bootstrap flags used by bootstrap.sh
1611 - iuse_implicit.add("build")
1612 - iuse_implicit.add("bootstrap")
1613 -
1614 - # Controlled by FEATURES=test. Make this implicit, so handling
1615 - # of FEATURES=test is consistent regardless of explicit IUSE.
1616 - # Users may use use.mask/package.use.mask to control
1617 - # FEATURES=test for all ebuilds, regardless of explicit IUSE.
1618 - iuse_implicit.add("test")
1619 -
1620 - return iuse_implicit
1621 -
1622 - def _getUseMask(self, pkg):
1623 - cp = getattr(pkg, "cp", None)
1624 - if cp is None:
1625 - cp = cpv_getkey(dep.remove_slot(pkg))
1626 - usemask = []
1627 - pos = 0
1628 - for i, pusemask_dict in enumerate(self.pusemask_list):
1629 - cpdict = pusemask_dict.get(cp)
1630 - if cpdict:
1631 - keys = list(cpdict)
1632 - while keys:
1633 - best_match = best_match_to_list(pkg, keys)
1634 - if best_match:
1635 - keys.remove(best_match)
1636 - usemask.insert(pos, cpdict[best_match])
1637 - else:
1638 - break
1639 - del keys
1640 - if self.usemask_list[i]:
1641 - usemask.insert(pos, self.usemask_list[i])
1642 - pos = len(usemask)
1643 - return set(stack_lists(usemask, incremental=True))
1644 -
1645 - def _getUseForce(self, pkg):
1646 - cp = getattr(pkg, "cp", None)
1647 - if cp is None:
1648 - cp = cpv_getkey(dep.remove_slot(pkg))
1649 - useforce = []
1650 - pos = 0
1651 - for i, puseforce_dict in enumerate(self.puseforce_list):
1652 - cpdict = puseforce_dict.get(cp)
1653 - if cpdict:
1654 - keys = list(cpdict)
1655 - while keys:
1656 - best_match = best_match_to_list(pkg, keys)
1657 - if best_match:
1658 - keys.remove(best_match)
1659 - useforce.insert(pos, cpdict[best_match])
1660 - else:
1661 - break
1662 - del keys
1663 - if self.useforce_list[i]:
1664 - useforce.insert(pos, self.useforce_list[i])
1665 - pos = len(useforce)
1666 - return set(stack_lists(useforce, incremental=True))
1667 -
1668 - def _getMaskAtom(self, cpv, metadata):
1669 - """
1670 - Take a package and return a matching package.mask atom, or None if no
1671 - such atom exists or it has been cancelled by package.unmask. PROVIDE
1672 - is not checked, so atoms will not be found for old-style virtuals.
1673 -
1674 - @param cpv: The package name
1675 - @type cpv: String
1676 - @param metadata: A dictionary of raw package metadata
1677 - @type metadata: dict
1678 - @rtype: String
1679 - @return: An matching atom string or None if one is not found.
1680 - """
1681 -
1682 - cp = cpv_getkey(cpv)
1683 - mask_atoms = self.pmaskdict.get(cp)
1684 - if mask_atoms:
1685 - pkg_list = ["%s:%s" % (cpv, metadata["SLOT"])]
1686 - unmask_atoms = self.punmaskdict.get(cp)
1687 - for x in mask_atoms:
1688 - if not match_from_list(x, pkg_list):
1689 - continue
1690 - if unmask_atoms:
1691 - for y in unmask_atoms:
1692 - if match_from_list(y, pkg_list):
1693 - return None
1694 - return x
1695 - return None
1696 -
1697 - def _getProfileMaskAtom(self, cpv, metadata):
1698 - """
1699 - Take a package and return a matching profile atom, or None if no
1700 - such atom exists. Note that a profile atom may or may not have a "*"
1701 - prefix. PROVIDE is not checked, so atoms will not be found for
1702 - old-style virtuals.
1703 -
1704 - @param cpv: The package name
1705 - @type cpv: String
1706 - @param metadata: A dictionary of raw package metadata
1707 - @type metadata: dict
1708 - @rtype: String
1709 - @return: An matching profile atom string or None if one is not found.
1710 - """
1711 -
1712 - cp = cpv_getkey(cpv)
1713 - profile_atoms = self.prevmaskdict.get(cp)
1714 - if profile_atoms:
1715 - pkg_list = ["%s:%s" % (cpv, metadata["SLOT"])]
1716 - for x in profile_atoms:
1717 - if match_from_list(x, pkg_list):
1718 - continue
1719 - return x
1720 - return None
1721 -
1722 - def _getKeywords(self, cpv, metadata):
1723 - cp = cpv_getkey(cpv)
1724 - pkg = "%s:%s" % (cpv, metadata["SLOT"])
1725 - keywords = [[x for x in metadata["KEYWORDS"].split() if x != "-*"]]
1726 - pos = len(keywords)
1727 - for pkeywords_dict in self._pkeywords_list:
1728 - cpdict = pkeywords_dict.get(cp)
1729 - if cpdict:
1730 - keys = list(cpdict)
1731 - while keys:
1732 - best_match = best_match_to_list(pkg, keys)
1733 - if best_match:
1734 - keys.remove(best_match)
1735 - keywords.insert(pos, cpdict[best_match])
1736 - else:
1737 - break
1738 - pos = len(keywords)
1739 - return stack_lists(keywords, incremental=True)
1740 -
1741 - def _getMissingKeywords(self, cpv, metadata):
1742 - """
1743 - Take a package and return a list of any KEYWORDS that the user may
1744 - may need to accept for the given package. If the KEYWORDS are empty
1745 - and the the ** keyword has not been accepted, the returned list will
1746 - contain ** alone (in order to distiguish from the case of "none
1747 - missing").
1748 -
1749 - @param cpv: The package name (for package.keywords support)
1750 - @type cpv: String
1751 - @param metadata: A dictionary of raw package metadata
1752 - @type metadata: dict
1753 - @rtype: List
1754 - @return: A list of KEYWORDS that have not been accepted.
1755 - """
1756 -
1757 - # Hack: Need to check the env directly here as otherwise stacking
1758 - # doesn't work properly as negative values are lost in the config
1759 - # object (bug #139600)
1760 - egroups = self.configdict["backupenv"].get(
1761 - "ACCEPT_KEYWORDS", "").split()
1762 - mygroups = self._getKeywords(cpv, metadata)
1763 - # Repoman may modify this attribute as necessary.
1764 - pgroups = self["ACCEPT_KEYWORDS"].split()
1765 - match=0
1766 - cp = cpv_getkey(cpv)
1767 - pkgdict = self.pkeywordsdict.get(cp)
1768 - matches = False
1769 - if pkgdict:
1770 - cpv_slot_list = ["%s:%s" % (cpv, metadata["SLOT"])]
1771 - for atom, pkgkeywords in pkgdict.items():
1772 - if match_from_list(atom, cpv_slot_list):
1773 - matches = True
1774 - pgroups.extend(pkgkeywords)
1775 - if matches or egroups:
1776 - pgroups.extend(egroups)
1777 - inc_pgroups = set()
1778 - for x in pgroups:
1779 - if x.startswith("-"):
1780 - if x == "-*":
1781 - inc_pgroups.clear()
1782 - else:
1783 - inc_pgroups.discard(x[1:])
1784 - else:
1785 - inc_pgroups.add(x)
1786 - pgroups = inc_pgroups
1787 - del inc_pgroups
1788 - hasstable = False
1789 - hastesting = False
1790 - for gp in mygroups:
1791 - if gp == "*" or (gp == "-*" and len(mygroups) == 1):
1792 - writemsg(_("--- WARNING: Package '%(cpv)s' uses"
1793 - " '%(keyword)s' keyword.\n") % {"cpv": cpv, "keyword": gp}, noiselevel=-1)
1794 - if gp == "*":
1795 - match = 1
1796 - break
1797 - elif gp in pgroups:
1798 - match=1
1799 - break
1800 - elif gp.startswith("~"):
1801 - hastesting = True
1802 - elif not gp.startswith("-"):
1803 - hasstable = True
1804 - if not match and \
1805 - ((hastesting and "~*" in pgroups) or \
1806 - (hasstable and "*" in pgroups) or "**" in pgroups):
1807 - match=1
1808 - if match:
1809 - missing = []
1810 - else:
1811 - if not mygroups:
1812 - # If KEYWORDS is empty then we still have to return something
1813 - # in order to distiguish from the case of "none missing".
1814 - mygroups.append("**")
1815 - missing = mygroups
1816 - return missing
1817 -
1818 - def _getMissingLicenses(self, cpv, metadata):
1819 - """
1820 - Take a LICENSE string and return a list any licenses that the user may
1821 - may need to accept for the given package. The returned list will not
1822 - contain any licenses that have already been accepted. This method
1823 - can throw an InvalidDependString exception.
1824 -
1825 - @param cpv: The package name (for package.license support)
1826 - @type cpv: String
1827 - @param metadata: A dictionary of raw package metadata
1828 - @type metadata: dict
1829 - @rtype: List
1830 - @return: A list of licenses that have not been accepted.
1831 - """
1832 - accept_license = self._accept_license
1833 - cpdict = self._plicensedict.get(cpv_getkey(cpv), None)
1834 - if cpdict:
1835 - accept_license = list(self._accept_license)
1836 - cpv_slot = "%s:%s" % (cpv, metadata["SLOT"])
1837 - for atom in match_to_list(cpv_slot, list(cpdict)):
1838 - accept_license.extend(cpdict[atom])
1839 -
1840 - licenses = set(flatten(dep.use_reduce(dep.paren_reduce(
1841 - metadata["LICENSE"]), matchall=1)))
1842 - licenses.discard('||')
1843 -
1844 - acceptable_licenses = set()
1845 - for x in accept_license:
1846 - if x == '*':
1847 - acceptable_licenses.update(licenses)
1848 - elif x == '-*':
1849 - acceptable_licenses.clear()
1850 - elif x[:1] == '-':
1851 - acceptable_licenses.discard(x[1:])
1852 - else:
1853 - acceptable_licenses.add(x)
1854 -
1855 - license_str = metadata["LICENSE"]
1856 - if "?" in license_str:
1857 - use = metadata["USE"].split()
1858 - else:
1859 - use = []
1860 -
1861 - license_struct = portage.dep.use_reduce(
1862 - portage.dep.paren_reduce(license_str), uselist=use)
1863 - license_struct = portage.dep.dep_opconvert(license_struct)
1864 - return self._getMaskedLicenses(license_struct, acceptable_licenses)
1865 -
1866 - def _getMaskedLicenses(self, license_struct, acceptable_licenses):
1867 - if not license_struct:
1868 - return []
1869 - if license_struct[0] == "||":
1870 - ret = []
1871 - for element in license_struct[1:]:
1872 - if isinstance(element, list):
1873 - if element:
1874 - ret.append(self._getMaskedLicenses(
1875 - element, acceptable_licenses))
1876 - if not ret[-1]:
1877 - return []
1878 - else:
1879 - if element in acceptable_licenses:
1880 - return []
1881 - ret.append(element)
1882 - # Return all masked licenses, since we don't know which combination
1883 - # (if any) the user will decide to unmask.
1884 - return flatten(ret)
1885 -
1886 - ret = []
1887 - for element in license_struct:
1888 - if isinstance(element, list):
1889 - if element:
1890 - ret.extend(self._getMaskedLicenses(element,
1891 - acceptable_licenses))
1892 - else:
1893 - if element not in acceptable_licenses:
1894 - ret.append(element)
1895 - return ret
1896 -
1897 - def _getMissingProperties(self, cpv, metadata):
1898 - """
1899 - Take a PROPERTIES string and return a list of any properties the user may
1900 - may need to accept for the given package. The returned list will not
1901 - contain any properties that have already been accepted. This method
1902 - can throw an InvalidDependString exception.
1903 -
1904 - @param cpv: The package name (for package.properties support)
1905 - @type cpv: String
1906 - @param metadata: A dictionary of raw package metadata
1907 - @type metadata: dict
1908 - @rtype: List
1909 - @return: A list of properties that have not been accepted.
1910 - """
1911 - accept_properties = self._accept_properties
1912 - cpdict = self._ppropertiesdict.get(cpv_getkey(cpv), None)
1913 - if cpdict:
1914 - accept_properties = list(self._accept_properties)
1915 - cpv_slot = "%s:%s" % (cpv, metadata["SLOT"])
1916 - for atom in match_to_list(cpv_slot, list(cpdict)):
1917 - accept_properties.extend(cpdict[atom])
1918 -
1919 - properties = set(flatten(dep.use_reduce(dep.paren_reduce(
1920 - metadata["PROPERTIES"]), matchall=1)))
1921 - properties.discard('||')
1922 -
1923 - acceptable_properties = set()
1924 - for x in accept_properties:
1925 - if x == '*':
1926 - acceptable_properties.update(properties)
1927 - elif x == '-*':
1928 - acceptable_properties.clear()
1929 - elif x[:1] == '-':
1930 - acceptable_properties.discard(x[1:])
1931 - else:
1932 - acceptable_properties.add(x)
1933 -
1934 - properties_str = metadata["PROPERTIES"]
1935 - if "?" in properties_str:
1936 - use = metadata["USE"].split()
1937 - else:
1938 - use = []
1939 -
1940 - properties_struct = portage.dep.use_reduce(
1941 - portage.dep.paren_reduce(properties_str), uselist=use)
1942 - properties_struct = portage.dep.dep_opconvert(properties_struct)
1943 - return self._getMaskedProperties(properties_struct, acceptable_properties)
1944 -
1945 - def _getMaskedProperties(self, properties_struct, acceptable_properties):
1946 - if not properties_struct:
1947 - return []
1948 - if properties_struct[0] == "||":
1949 - ret = []
1950 - for element in properties_struct[1:]:
1951 - if isinstance(element, list):
1952 - if element:
1953 - ret.append(self._getMaskedProperties(
1954 - element, acceptable_properties))
1955 - if not ret[-1]:
1956 - return []
1957 - else:
1958 - if element in acceptable_properties:
1959 - return[]
1960 - ret.append(element)
1961 - # Return all masked properties, since we don't know which combination
1962 - # (if any) the user will decide to unmask
1963 - return flatten(ret)
1964 -
1965 - ret = []
1966 - for element in properties_struct:
1967 - if isinstance(element, list):
1968 - if element:
1969 - ret.extend(self._getMaskedProperties(element,
1970 - acceptable_properties))
1971 - else:
1972 - if element not in acceptable_properties:
1973 - ret.append(element)
1974 - return ret
1975 -
1976 - def _accept_chost(self, cpv, metadata):
1977 - """
1978 - @return True if pkg CHOST is accepted, False otherwise.
1979 - """
1980 - if self._accept_chost_re is None:
1981 - accept_chost = self.get("ACCEPT_CHOSTS", "").split()
1982 - if not accept_chost:
1983 - chost = self.get("CHOST")
1984 - if chost:
1985 - accept_chost.append(chost)
1986 - if not accept_chost:
1987 - self._accept_chost_re = re.compile(".*")
1988 - elif len(accept_chost) == 1:
1989 - try:
1990 - self._accept_chost_re = re.compile(r'^%s$' % accept_chost[0])
1991 - except re.error as e:
1992 - writemsg(_("!!! Invalid ACCEPT_CHOSTS value: '%s': %s\n") % \
1993 - (accept_chost[0], e), noiselevel=-1)
1994 - self._accept_chost_re = re.compile("^$")
1995 - else:
1996 - try:
1997 - self._accept_chost_re = re.compile(
1998 - r'^(%s)$' % "|".join(accept_chost))
1999 - except re.error as e:
2000 - writemsg(_("!!! Invalid ACCEPT_CHOSTS value: '%s': %s\n") % \
2001 - (" ".join(accept_chost), e), noiselevel=-1)
2002 - self._accept_chost_re = re.compile("^$")
2003 -
2004 - pkg_chost = metadata.get('CHOST', '')
2005 - return not pkg_chost or \
2006 - self._accept_chost_re.match(pkg_chost) is not None
2007 -
2008 - def setinst(self,mycpv,mydbapi):
2009 - """This updates the preferences for old-style virtuals,
2010 - affecting the behavior of dep_expand() and dep_check()
2011 - calls. It can change dbapi.match() behavior since that
2012 - calls dep_expand(). However, dbapi instances have
2013 - internal match caches that are not invalidated when
2014 - preferences are updated here. This can potentially
2015 - lead to some inconsistency (relevant to bug #1343)."""
2016 - self.modifying()
2017 - if len(self.virtuals) == 0:
2018 - self.getvirtuals()
2019 - # Grab the virtuals this package provides and add them into the tree virtuals.
2020 - if not hasattr(mydbapi, "aux_get"):
2021 - provides = mydbapi["PROVIDE"]
2022 - else:
2023 - provides = mydbapi.aux_get(mycpv, ["PROVIDE"])[0]
2024 - if not provides:
2025 - return
2026 - if isinstance(mydbapi, portdbapi):
2027 - self.setcpv(mycpv, mydb=mydbapi)
2028 - myuse = self["PORTAGE_USE"]
2029 - elif not hasattr(mydbapi, "aux_get"):
2030 - myuse = mydbapi["USE"]
2031 - else:
2032 - myuse = mydbapi.aux_get(mycpv, ["USE"])[0]
2033 - virts = flatten(portage.dep.use_reduce(portage.dep.paren_reduce(provides), uselist=myuse.split()))
2034 -
2035 - modified = False
2036 - cp = dep.Atom(cpv_getkey(mycpv))
2037 - for virt in virts:
2038 - try:
2039 - virt = dep.Atom(virt).cp
2040 - except exception.InvalidAtom:
2041 - continue
2042 - providers = self.virtuals.get(virt)
2043 - if providers and cp in providers:
2044 - continue
2045 - providers = self._depgraphVirtuals.get(virt)
2046 - if providers is None:
2047 - providers = []
2048 - self._depgraphVirtuals[virt] = providers
2049 - if cp not in providers:
2050 - providers.append(cp)
2051 - modified = True
2052 -
2053 - if modified:
2054 - self.virtuals = self.__getvirtuals_compile()
2055 -
2056 - def reload(self):
2057 - """Reload things like /etc/profile.env that can change during runtime."""
2058 - env_d_filename = os.path.join(self["ROOT"], "etc", "profile.env")
2059 - self.configdict["env.d"].clear()
2060 - env_d = getconfig(env_d_filename, expand=False)
2061 - if env_d:
2062 - # env_d will be None if profile.env doesn't exist.
2063 - self.configdict["env.d"].update(env_d)
2064 -
2065 - def _prune_incremental(self, split):
2066 - """
2067 - Prune off any parts of an incremental variable that are
2068 - made irrelevant by the latest occuring * or -*. This
2069 - could be more aggressive but that might be confusing
2070 - and the point is just to reduce noise a bit.
2071 - """
2072 - for i, x in enumerate(reversed(split)):
2073 - if x == '*':
2074 - split = split[-i-1:]
2075 - break
2076 - elif x == '-*':
2077 - if i == 0:
2078 - split = []
2079 - else:
2080 - split = split[-i:]
2081 - break
2082 - return split
2083 -
2084 - def regenerate(self,useonly=0,use_cache=1):
2085 - """
2086 - Regenerate settings
2087 - This involves regenerating valid USE flags, re-expanding USE_EXPAND flags
2088 - re-stacking USE flags (-flag and -*), as well as any other INCREMENTAL
2089 - variables. This also updates the env.d configdict; useful in case an ebuild
2090 - changes the environment.
2091 -
2092 - If FEATURES has already stacked, it is not stacked twice.
2093 -
2094 - @param useonly: Only regenerate USE flags (not any other incrementals)
2095 - @type useonly: Boolean
2096 - @param use_cache: Enable Caching (only for autouse)
2097 - @type use_cache: Boolean
2098 - @rtype: None
2099 - """
2100 -
2101 - self.modifying()
2102 - if self.already_in_regenerate:
2103 - # XXX: THIS REALLY NEEDS TO GET FIXED. autouse() loops.
2104 - writemsg("!!! Looping in regenerate.\n",1)
2105 - return
2106 - else:
2107 - self.already_in_regenerate = 1
2108 -
2109 - if useonly:
2110 - myincrementals=["USE"]
2111 - else:
2112 - myincrementals = self.incrementals
2113 - myincrementals = set(myincrementals)
2114 - # If self.features exists, it has already been stacked and may have
2115 - # been mutated, so don't stack it again or else any mutations will be
2116 - # reverted.
2117 - if "FEATURES" in myincrementals and hasattr(self, "features"):
2118 - myincrementals.remove("FEATURES")
2119 -
2120 - if "USE" in myincrementals:
2121 - # Process USE last because it depends on USE_EXPAND which is also
2122 - # an incremental!
2123 - myincrementals.remove("USE")
2124 -
2125 - mydbs = self.configlist[:-1]
2126 - mydbs.append(self.backupenv)
2127 -
2128 - # ACCEPT_LICENSE is a lazily evaluated incremental, so that * can be
2129 - # used to match all licenses without every having to explicitly expand
2130 - # it to all licenses.
2131 - if self.local_config:
2132 - mysplit = []
2133 - for curdb in mydbs:
2134 - mysplit.extend(curdb.get('ACCEPT_LICENSE', '').split())
2135 - mysplit = self._prune_incremental(mysplit)
2136 - accept_license_str = ' '.join(mysplit)
2137 - self.configlist[-1]['ACCEPT_LICENSE'] = accept_license_str
2138 - if accept_license_str != self._accept_license_str:
2139 - self._accept_license_str = accept_license_str
2140 - self._accept_license = tuple(self.expandLicenseTokens(mysplit))
2141 - else:
2142 - # repoman will accept any license
2143 - self._accept_license = ('*',)
2144 -
2145 - # ACCEPT_PROPERTIES works like ACCEPT_LICENSE, without groups
2146 - if self.local_config:
2147 - mysplit = []
2148 - for curdb in mydbs:
2149 - mysplit.extend(curdb.get('ACCEPT_PROPERTIES', '').split())
2150 - mysplit = self._prune_incremental(mysplit)
2151 - self.configlist[-1]['ACCEPT_PROPERTIES'] = ' '.join(mysplit)
2152 - if tuple(mysplit) != self._accept_properties:
2153 - self._accept_properties = tuple(mysplit)
2154 - else:
2155 - # repoman will accept any property
2156 - self._accept_properties = ('*',)
2157 -
2158 - for mykey in myincrementals:
2159 -
2160 - myflags=[]
2161 - for curdb in mydbs:
2162 - if mykey not in curdb:
2163 - continue
2164 - #variables are already expanded
2165 - mysplit = curdb[mykey].split()
2166 -
2167 - for x in mysplit:
2168 - if x=="-*":
2169 - # "-*" is a special "minus" var that means "unset all settings".
2170 - # so USE="-* gnome" will have *just* gnome enabled.
2171 - myflags = []
2172 - continue
2173 -
2174 - if x[0]=="+":
2175 - # Not legal. People assume too much. Complain.
2176 - writemsg(colorize("BAD",
2177 - _("USE flags should not start with a '+': %s") % x) \
2178 - + "\n", noiselevel=-1)
2179 - x=x[1:]
2180 - if not x:
2181 - continue
2182 -
2183 - if (x[0]=="-"):
2184 - if (x[1:] in myflags):
2185 - # Unset/Remove it.
2186 - del myflags[myflags.index(x[1:])]
2187 - continue
2188 -
2189 - # We got here, so add it now.
2190 - if x not in myflags:
2191 - myflags.append(x)
2192 -
2193 - myflags.sort()
2194 - #store setting in last element of configlist, the original environment:
2195 - if myflags or mykey in self:
2196 - self.configlist[-1][mykey] = " ".join(myflags)
2197 - del myflags
2198 -
2199 - # Do the USE calculation last because it depends on USE_EXPAND.
2200 - if "auto" in self["USE_ORDER"].split(":"):
2201 - self.configdict["auto"]["USE"] = autouse(
2202 - vartree(root=self["ROOT"], categories=self.categories,
2203 - settings=self),
2204 - use_cache=use_cache, mysettings=self)
2205 - else:
2206 - self.configdict["auto"]["USE"] = ""
2207 -
2208 - use_expand = self.get("USE_EXPAND", "").split()
2209 - use_expand_dict = self._use_expand_dict
2210 - use_expand_dict.clear()
2211 - for k in use_expand:
2212 - v = self.get(k)
2213 - if v is not None:
2214 - use_expand_dict[k] = v
2215 -
2216 - if not self.uvlist:
2217 - for x in self["USE_ORDER"].split(":"):
2218 - if x in self.configdict:
2219 - self.uvlist.append(self.configdict[x])
2220 - self.uvlist.reverse()
2221 -
2222 - # For optimal performance, use slice
2223 - # comparison instead of startswith().
2224 - myflags = set()
2225 - for curdb in self.uvlist:
2226 - cur_use_expand = [x for x in use_expand if x in curdb]
2227 - mysplit = curdb.get("USE", "").split()
2228 - if not mysplit and not cur_use_expand:
2229 - continue
2230 - for x in mysplit:
2231 - if x == "-*":
2232 - myflags.clear()
2233 - continue
2234 -
2235 - if x[0] == "+":
2236 - writemsg(colorize("BAD", _("USE flags should not start "
2237 - "with a '+': %s\n") % x), noiselevel=-1)
2238 - x = x[1:]
2239 - if not x:
2240 - continue
2241 -
2242 - if x[0] == "-":
2243 - myflags.discard(x[1:])
2244 - continue
2245 -
2246 - myflags.add(x)
2247 -
2248 - for var in cur_use_expand:
2249 - var_lower = var.lower()
2250 - is_not_incremental = var not in myincrementals
2251 - if is_not_incremental:
2252 - prefix = var_lower + "_"
2253 - prefix_len = len(prefix)
2254 - for x in list(myflags):
2255 - if x[:prefix_len] == prefix:
2256 - myflags.remove(x)
2257 - for x in curdb[var].split():
2258 - if x[0] == "+":
2259 - if is_not_incremental:
2260 - writemsg(colorize("BAD", _("Invalid '+' "
2261 - "operator in non-incremental variable "
2262 - "'%s': '%s'\n") % (var, x)), noiselevel=-1)
2263 - continue
2264 - else:
2265 - writemsg(colorize("BAD", _("Invalid '+' "
2266 - "operator in incremental variable "
2267 - "'%s': '%s'\n") % (var, x)), noiselevel=-1)
2268 - x = x[1:]
2269 - if x[0] == "-":
2270 - if is_not_incremental:
2271 - writemsg(colorize("BAD", _("Invalid '-' "
2272 - "operator in non-incremental variable "
2273 - "'%s': '%s'\n") % (var, x)), noiselevel=-1)
2274 - continue
2275 - myflags.discard(var_lower + "_" + x[1:])
2276 - continue
2277 - myflags.add(var_lower + "_" + x)
2278 -
2279 - if hasattr(self, "features"):
2280 - self.features.clear()
2281 - else:
2282 - self.features = set()
2283 - self.features.update(self.configlist[-1].get('FEATURES', '').split())
2284 - self['FEATURES'] = ' '.join(sorted(self.features))
2285 -
2286 - myflags.update(self.useforce)
2287 - arch = self.configdict["defaults"].get("ARCH")
2288 - if arch:
2289 - myflags.add(arch)
2290 -
2291 - myflags.difference_update(self.usemask)
2292 - self.configlist[-1]["USE"]= " ".join(sorted(myflags))
2293 -
2294 - self.already_in_regenerate = 0
2295 -
2296 - def get_virts_p(self, myroot=None):
2297 -
2298 - if myroot is not None:
2299 - warnings.warn("The 'myroot' parameter for " + \
2300 - "portage.config.get_virts_p() is deprecated",
2301 - DeprecationWarning, stacklevel=2)
2302 -
2303 - if self.virts_p:
2304 - return self.virts_p
2305 - virts = self.getvirtuals()
2306 - if virts:
2307 - for x in virts:
2308 - vkeysplit = x.split("/")
2309 - if vkeysplit[1] not in self.virts_p:
2310 - self.virts_p[vkeysplit[1]] = virts[x]
2311 - return self.virts_p
2312 -
2313 - def getvirtuals(self, myroot=None):
2314 - """myroot is now ignored because, due to caching, it has always been
2315 - broken for all but the first call."""
2316 -
2317 - if myroot is not None:
2318 - warnings.warn("The 'myroot' parameter for " + \
2319 - "portage.config.getvirtuals() is deprecated",
2320 - DeprecationWarning, stacklevel=2)
2321 -
2322 - myroot = self["ROOT"]
2323 - if self.virtuals:
2324 - return self.virtuals
2325 -
2326 - virtuals_list = []
2327 - for x in self.profiles:
2328 - virtuals_file = os.path.join(x, "virtuals")
2329 - virtuals_dict = grabdict(virtuals_file)
2330 - atoms_dict = {}
2331 - for k, v in virtuals_dict.items():
2332 - try:
2333 - virt_atom = portage.dep.Atom(k)
2334 - except portage.exception.InvalidAtom:
2335 - virt_atom = None
2336 - else:
2337 - if virt_atom.blocker or \
2338 - str(virt_atom) != str(virt_atom.cp):
2339 - virt_atom = None
2340 - if virt_atom is None:
2341 - writemsg(_("--- Invalid virtuals atom in %s: %s\n") % \
2342 - (virtuals_file, k), noiselevel=-1)
2343 - continue
2344 - providers = []
2345 - for atom in v:
2346 - atom_orig = atom
2347 - if atom[:1] == '-':
2348 - # allow incrementals
2349 - atom = atom[1:]
2350 - try:
2351 - atom = portage.dep.Atom(atom)
2352 - except portage.exception.InvalidAtom:
2353 - atom = None
2354 - else:
2355 - if atom.blocker:
2356 - atom = None
2357 - if atom is None:
2358 - writemsg(_("--- Invalid atom in %s: %s\n") % \
2359 - (virtuals_file, myatom), noiselevel=-1)
2360 - else:
2361 - if atom_orig == str(atom):
2362 - # normal atom, so return as Atom instance
2363 - providers.append(atom)
2364 - else:
2365 - # atom has special prefix, so return as string
2366 - providers.append(atom_orig)
2367 - if providers:
2368 - atoms_dict[virt_atom] = providers
2369 - if atoms_dict:
2370 - virtuals_list.append(atoms_dict)
2371 -
2372 - self.dirVirtuals = stack_dictlist(virtuals_list, incremental=True)
2373 - del virtuals_list
2374 -
2375 - for virt in self.dirVirtuals:
2376 - # Preference for virtuals decreases from left to right.
2377 - self.dirVirtuals[virt].reverse()
2378 -
2379 - # Repoman does not use user or tree virtuals.
2380 - if self.local_config and not self.treeVirtuals:
2381 - temp_vartree = vartree(myroot, None,
2382 - categories=self.categories, settings=self)
2383 - self._populate_treeVirtuals(temp_vartree)
2384 -
2385 - self.virtuals = self.__getvirtuals_compile()
2386 - return self.virtuals
2387 -
2388 - def _populate_treeVirtuals(self, vartree):
2389 - """Reduce the provides into a list by CP."""
2390 - for provide, cpv_list in vartree.get_all_provides().items():
2391 - try:
2392 - provide = dep.Atom(provide)
2393 - except exception.InvalidAtom:
2394 - continue
2395 - self.treeVirtuals[provide.cp] = \
2396 - [dep.Atom(cpv_getkey(cpv)) for cpv in cpv_list]
2397 -
2398 - def __getvirtuals_compile(self):
2399 - """Stack installed and profile virtuals. Preference for virtuals
2400 - decreases from left to right.
2401 - Order of preference:
2402 - 1. installed and in profile
2403 - 2. installed only
2404 - 3. profile only
2405 - """
2406 -
2407 - # Virtuals by profile+tree preferences.
2408 - ptVirtuals = {}
2409 -
2410 - for virt, installed_list in self.treeVirtuals.items():
2411 - profile_list = self.dirVirtuals.get(virt, None)
2412 - if not profile_list:
2413 - continue
2414 - for cp in installed_list:
2415 - if cp in profile_list:
2416 - ptVirtuals.setdefault(virt, [])
2417 - ptVirtuals[virt].append(cp)
2418 -
2419 - virtuals = stack_dictlist([ptVirtuals, self.treeVirtuals,
2420 - self.dirVirtuals, self._depgraphVirtuals])
2421 - return virtuals
2422 -
2423 - def __delitem__(self,mykey):
2424 - self.modifying()
2425 - for x in self.lookuplist:
2426 - if x != None:
2427 - if mykey in x:
2428 - del x[mykey]
2429 -
2430 - def __getitem__(self,mykey):
2431 - for d in self.lookuplist:
2432 - if mykey in d:
2433 - return d[mykey]
2434 - return '' # for backward compat, don't raise KeyError
2435 -
2436 - def get(self, k, x=None):
2437 - for d in self.lookuplist:
2438 - if k in d:
2439 - return d[k]
2440 - return x
2441 -
2442 - def pop(self, key, *args):
2443 - if len(args) > 1:
2444 - raise TypeError(
2445 - "pop expected at most 2 arguments, got " + \
2446 - repr(1 + len(args)))
2447 - v = self
2448 - for d in reversed(self.lookuplist):
2449 - v = d.pop(key, v)
2450 - if v is self:
2451 - if args:
2452 - return args[0]
2453 - raise KeyError(key)
2454 - return v
2455 -
2456 - def has_key(self,mykey):
2457 - warnings.warn("portage.config.has_key() is deprecated, "
2458 - "use the in operator instead",
2459 - DeprecationWarning, stacklevel=2)
2460 - return mykey in self
2461 -
2462 - def __contains__(self, mykey):
2463 - """Called to implement membership test operators (in and not in)."""
2464 - for d in self.lookuplist:
2465 - if mykey in d:
2466 - return True
2467 - return False
2468 -
2469 - def setdefault(self, k, x=None):
2470 - v = self.get(k)
2471 - if v is not None:
2472 - return v
2473 - else:
2474 - self[k] = x
2475 - return x
2476 -
2477 - def keys(self):
2478 - return list(self)
2479 -
2480 - def __iter__(self):
2481 - keys = set()
2482 - for d in self.lookuplist:
2483 - keys.update(d)
2484 - return iter(keys)
2485 -
2486 - def iterkeys(self):
2487 - return iter(self)
2488 -
2489 - def iteritems(self):
2490 - for k in self:
2491 - yield (k, self[k])
2492 -
2493 - def items(self):
2494 - return list(self.iteritems())
2495 -
2496 - def __setitem__(self,mykey,myvalue):
2497 - "set a value; will be thrown away at reset() time"
2498 - if not isinstance(myvalue, basestring):
2499 - raise ValueError("Invalid type being used as a value: '%s': '%s'" % (str(mykey),str(myvalue)))
2500 -
2501 - # Avoid potential UnicodeDecodeError exceptions later.
2502 - mykey = _unicode_decode(mykey)
2503 - myvalue = _unicode_decode(myvalue)
2504 -
2505 - self.modifying()
2506 - self.modifiedkeys.append(mykey)
2507 - self.configdict["env"][mykey]=myvalue
2508 -
2509 - def environ(self):
2510 - "return our locally-maintained environment"
2511 - mydict={}
2512 - environ_filter = self._environ_filter
2513 -
2514 - eapi = self.get('EAPI')
2515 - phase = self.get('EBUILD_PHASE')
2516 - filter_calling_env = False
2517 - if phase not in ('clean', 'cleanrm', 'depend'):
2518 - temp_dir = self.get('T')
2519 - if temp_dir is not None and \
2520 - os.path.exists(os.path.join(temp_dir, 'environment')):
2521 - filter_calling_env = True
2522 -
2523 - environ_whitelist = self._environ_whitelist
2524 - env_d = self.configdict["env.d"]
2525 - for x in self:
2526 - if x in environ_filter:
2527 - continue
2528 - myvalue = self[x]
2529 - if not isinstance(myvalue, basestring):
2530 - writemsg(_("!!! Non-string value in config: %s=%s\n") % \
2531 - (x, myvalue), noiselevel=-1)
2532 - continue
2533 - if filter_calling_env and \
2534 - x not in environ_whitelist and \
2535 - not self._environ_whitelist_re.match(x):
2536 - # Do not allow anything to leak into the ebuild
2537 - # environment unless it is explicitly whitelisted.
2538 - # This ensures that variables unset by the ebuild
2539 - # remain unset.
2540 - continue
2541 - mydict[x] = myvalue
2542 - if "HOME" not in mydict and "BUILD_PREFIX" in mydict:
2543 - writemsg("*** HOME not set. Setting to "+mydict["BUILD_PREFIX"]+"\n")
2544 - mydict["HOME"]=mydict["BUILD_PREFIX"][:]
2545 -
2546 - if filter_calling_env:
2547 - if phase:
2548 - whitelist = []
2549 - if "rpm" == phase:
2550 - whitelist.append("RPMDIR")
2551 - for k in whitelist:
2552 - v = self.get(k)
2553 - if v is not None:
2554 - mydict[k] = v
2555 -
2556 - # Filtered by IUSE and implicit IUSE.
2557 - mydict["USE"] = self.get("PORTAGE_USE", "")
2558 -
2559 - # Don't export AA to the ebuild environment in EAPIs that forbid it
2560 - if eapi not in ("0", "1", "2", "3", "3_pre2"):
2561 - mydict.pop("AA", None)
2562 -
2563 - # Prefix variables are supported starting with EAPI 3.
2564 - if phase == 'depend' or eapi in (None, "0", "1", "2"):
2565 - mydict.pop("ED", None)
2566 - mydict.pop("EPREFIX", None)
2567 - mydict.pop("EROOT", None)
2568 -
2569 - if phase == 'depend':
2570 - mydict.pop('FILESDIR', None)
2571 -
2572 - return mydict
2573 -
2574 - def thirdpartymirrors(self):
2575 - if getattr(self, "_thirdpartymirrors", None) is None:
2576 - profileroots = [os.path.join(self["PORTDIR"], "profiles")]
2577 - for x in self["PORTDIR_OVERLAY"].split():
2578 - profileroots.insert(0, os.path.join(x, "profiles"))
2579 - thirdparty_lists = [grabdict(os.path.join(x, "thirdpartymirrors")) for x in profileroots]
2580 - self._thirdpartymirrors = stack_dictlist(thirdparty_lists, incremental=True)
2581 - return self._thirdpartymirrors
2582 -
2583 - def archlist(self):
2584 - return flatten([[myarch, "~" + myarch] \
2585 - for myarch in self["PORTAGE_ARCHLIST"].split()])
2586 -
2587 - def selinux_enabled(self):
2588 - if getattr(self, "_selinux_enabled", None) is None:
2589 - self._selinux_enabled = 0
2590 - if "selinux" in self["USE"].split():
2591 - if selinux:
2592 - if selinux.is_selinux_enabled() == 1:
2593 - self._selinux_enabled = 1
2594 - else:
2595 - self._selinux_enabled = 0
2596 - else:
2597 - writemsg(_("!!! SELinux module not found. Please verify that it was installed.\n"),
2598 - noiselevel=-1)
2599 - self._selinux_enabled = 0
2600 -
2601 - return self._selinux_enabled
2602 -
2603 - if sys.hexversion >= 0x3000000:
2604 - keys = __iter__
2605 - items = iteritems
2606 -
2607 def _can_test_pty_eof():
2608 """
2609 The _test_pty_eof() function seems to hang on most
2610
2611 Added: main/trunk/pym/portage/package/__init__.py
2612 ===================================================================
2613 --- main/trunk/pym/portage/package/__init__.py (rev 0)
2614 +++ main/trunk/pym/portage/package/__init__.py 2010-02-22 04:13:28 UTC (rev 15424)
2615 @@ -0,0 +1,3 @@
2616 +# Copyright 2010 Gentoo Foundation
2617 +# Distributed under the terms of the GNU General Public License v2
2618 +# $Id$
2619
2620
2621 Property changes on: main/trunk/pym/portage/package/__init__.py
2622 ___________________________________________________________________
2623 Added: svn:keywords
2624 + Id
2625
2626 Added: main/trunk/pym/portage/package/ebuild/__init__.py
2627 ===================================================================
2628 --- main/trunk/pym/portage/package/ebuild/__init__.py (rev 0)
2629 +++ main/trunk/pym/portage/package/ebuild/__init__.py 2010-02-22 04:13:28 UTC (rev 15424)
2630 @@ -0,0 +1,3 @@
2631 +# Copyright 2010 Gentoo Foundation
2632 +# Distributed under the terms of the GNU General Public License v2
2633 +# $Id$
2634
2635
2636 Property changes on: main/trunk/pym/portage/package/ebuild/__init__.py
2637 ___________________________________________________________________
2638 Added: svn:keywords
2639 + Id
2640
2641 Added: main/trunk/pym/portage/package/ebuild/config.py
2642 ===================================================================
2643 --- main/trunk/pym/portage/package/ebuild/config.py (rev 0)
2644 +++ main/trunk/pym/portage/package/ebuild/config.py 2010-02-22 04:13:28 UTC (rev 15424)
2645 @@ -0,0 +1,2607 @@
2646 +# Copyright 2010 Gentoo Foundation
2647 +# Distributed under the terms of the GNU General Public License v2
2648 +# $Id$
2649 +
2650 +__all__ = [
2651 + 'autouse', 'best_from_dict', 'check_config_instance', 'config',
2652 +]
2653 +
2654 +import codecs
2655 +import copy
2656 +import errno
2657 +import logging
2658 +import re
2659 +import sys
2660 +import warnings
2661 +
2662 +try:
2663 + from configparser import SafeConfigParser, ParsingError
2664 +except ImportError:
2665 + from ConfigParser import SafeConfigParser, ParsingError
2666 +
2667 +import portage
2668 +from portage import bsd_chflags, eapi_is_supported, \
2669 + load_mod, os, selinux, _encodings, _unicode_encode, _unicode_decode
2670 +from portage.const import CACHE_PATH, CUSTOM_PROFILE_PATH, \
2671 + DEPCACHE_PATH, GLOBAL_CONFIG_PATH, INCREMENTALS, MAKE_CONF_FILE, \
2672 + MODULES_FILE_PATH, PORTAGE_BIN_PATH, PORTAGE_PYM_PATH, \
2673 + PRIVATE_PATH, PROFILE_PATH, USER_CONFIG_PATH, USER_VIRTUALS_FILE
2674 +from portage.data import portage_gid
2675 +from portage.dbapi import dbapi
2676 +from portage.dbapi.porttree import portdbapi
2677 +from portage.dbapi.vartree import vartree
2678 +from portage.dep import Atom, best_match_to_list, dep_opconvert, \
2679 + flatten, isvalidatom, match_from_list, match_to_list, \
2680 + paren_reduce, remove_slot, use_reduce
2681 +from portage.env.loaders import KeyValuePairFileLoader
2682 +from portage.exception import DirectoryNotFound, InvalidAtom, \
2683 + InvalidDependString, ParseError, PortageException
2684 +from portage.localization import _
2685 +from portage.output import colorize
2686 +from portage.process import fakeroot_capable, sandbox_capable
2687 +from portage.util import ensure_dirs, getconfig, grabdict, \
2688 + grabdict_package, grabfile, grabfile_package, LazyItemsDict, \
2689 + normalize_path, stack_dictlist, stack_dicts, stack_lists, \
2690 + writemsg, writemsg_level
2691 +from portage.versions import catpkgsplit, catsplit, cpv_getkey
2692 +
2693 +def autouse(myvartree, use_cache=1, mysettings=None):
2694 + """
2695 + autuse returns a list of USE variables auto-enabled to packages being installed
2696 +
2697 + @param myvartree: Instance of the vartree class (from /var/db/pkg...)
2698 + @type myvartree: vartree
2699 + @param use_cache: read values from cache
2700 + @type use_cache: Boolean
2701 + @param mysettings: Instance of config
2702 + @type mysettings: config
2703 + @rtype: string
2704 + @returns: A string containing a list of USE variables that are enabled via use.defaults
2705 + """
2706 + if mysettings is None:
2707 + mysettings = portage.settings
2708 + if mysettings.profile_path is None:
2709 + return ""
2710 + myusevars=""
2711 + usedefaults = mysettings.use_defs
2712 + for myuse in usedefaults:
2713 + dep_met = True
2714 + for mydep in usedefaults[myuse]:
2715 + if not myvartree.dep_match(mydep,use_cache=True):
2716 + dep_met = False
2717 + break
2718 + if dep_met:
2719 + myusevars += " "+myuse
2720 + return myusevars
2721 +
2722 +def check_config_instance(test):
2723 + if not isinstance(test, config):
2724 + raise TypeError("Invalid type for config object: %s (should be %s)" % (test.__class__, config))
2725 +
2726 +def best_from_dict(key, top_dict, key_order, EmptyOnError=1, FullCopy=1, AllowEmpty=1):
2727 + for x in key_order:
2728 + if x in top_dict and key in top_dict[x]:
2729 + if FullCopy:
2730 + return copy.deepcopy(top_dict[x][key])
2731 + else:
2732 + return top_dict[x][key]
2733 + if EmptyOnError:
2734 + return ""
2735 + else:
2736 + raise KeyError("Key not found in list; '%s'" % key)
2737 +
2738 +def _lazy_iuse_regex(iuse_implicit):
2739 + """
2740 + The PORTAGE_IUSE value is lazily evaluated since re.escape() is slow
2741 + and the value is only used when an ebuild phase needs to be executed
2742 + (it's used only to generate QA notices).
2743 + """
2744 + # Escape anything except ".*" which is supposed to pass through from
2745 + # _get_implicit_iuse().
2746 + regex = sorted(re.escape(x) for x in iuse_implicit)
2747 + regex = "^(%s)$" % "|".join(regex)
2748 + regex = regex.replace("\\.\\*", ".*")
2749 + return regex
2750 +
2751 +class _local_repo_config(object):
2752 + __slots__ = ('aliases', 'eclass_overrides', 'masters', 'name',)
2753 + def __init__(self, name, repo_opts):
2754 + self.name = name
2755 +
2756 + aliases = repo_opts.get('aliases')
2757 + if aliases is not None:
2758 + aliases = tuple(aliases.split())
2759 + self.aliases = aliases
2760 +
2761 + eclass_overrides = repo_opts.get('eclass-overrides')
2762 + if eclass_overrides is not None:
2763 + eclass_overrides = tuple(eclass_overrides.split())
2764 + self.eclass_overrides = eclass_overrides
2765 +
2766 + masters = repo_opts.get('masters')
2767 + if masters is not None:
2768 + masters = tuple(masters.split())
2769 + self.masters = masters
2770 +
2771 +class config(object):
2772 + """
2773 + This class encompasses the main portage configuration. Data is pulled from
2774 + ROOT/PORTDIR/profiles/, from ROOT/etc/make.profile incrementally through all
2775 + parent profiles as well as from ROOT/PORTAGE_CONFIGROOT/* for user specified
2776 + overrides.
2777 +
2778 + Generally if you need data like USE flags, FEATURES, environment variables,
2779 + virtuals ...etc you look in here.
2780 + """
2781 +
2782 + _setcpv_aux_keys = ('DEFINED_PHASES', 'DEPEND', 'EAPI',
2783 + 'INHERITED', 'IUSE', 'KEYWORDS', 'LICENSE', 'PDEPEND',
2784 + 'PROPERTIES', 'PROVIDE', 'RDEPEND', 'SLOT',
2785 + 'repository', 'RESTRICT', 'LICENSE',)
2786 +
2787 + _env_blacklist = [
2788 + "A", "AA", "CATEGORY", "DEPEND", "DESCRIPTION", "EAPI",
2789 + "EBUILD_PHASE", "ED", "EMERGE_FROM", "EPREFIX", "EROOT",
2790 + "HOMEPAGE", "INHERITED", "IUSE",
2791 + "KEYWORDS", "LICENSE", "PDEPEND", "PF", "PKGUSE",
2792 + "PORTAGE_CONFIGROOT", "PORTAGE_IUSE",
2793 + "PORTAGE_NONFATAL", "PORTAGE_REPO_NAME",
2794 + "PORTAGE_USE", "PROPERTIES", "PROVIDE", "RDEPEND", "RESTRICT",
2795 + "ROOT", "SLOT", "SRC_URI"
2796 + ]
2797 +
2798 + _environ_whitelist = []
2799 +
2800 + # Whitelisted variables are always allowed to enter the ebuild
2801 + # environment. Generally, this only includes special portage
2802 + # variables. Ebuilds can unset variables that are not whitelisted
2803 + # and rely on them remaining unset for future phases, without them
2804 + # leaking back in from various locations (bug #189417). It's very
2805 + # important to set our special BASH_ENV variable in the ebuild
2806 + # environment in order to prevent sandbox from sourcing /etc/profile
2807 + # in it's bashrc (causing major leakage).
2808 + _environ_whitelist += [
2809 + "ACCEPT_LICENSE", "BASH_ENV", "BUILD_PREFIX", "D",
2810 + "DISTDIR", "DOC_SYMLINKS_DIR", "EAPI", "EBUILD",
2811 + "EBUILD_EXIT_STATUS_FILE", "EBUILD_FORCE_TEST",
2812 + "EBUILD_PHASE", "ECLASSDIR", "ECLASS_DEPTH", "ED",
2813 + "EMERGE_FROM", "EPREFIX", "EROOT",
2814 + "FEATURES", "FILESDIR", "HOME", "NOCOLOR", "PATH",
2815 + "PKGDIR",
2816 + "PKGUSE", "PKG_LOGDIR", "PKG_TMPDIR",
2817 + "PORTAGE_ACTUAL_DISTDIR", "PORTAGE_ARCHLIST",
2818 + "PORTAGE_BASHRC",
2819 + "PORTAGE_BINPKG_FILE", "PORTAGE_BINPKG_TAR_OPTS",
2820 + "PORTAGE_BINPKG_TMPFILE",
2821 + "PORTAGE_BIN_PATH",
2822 + "PORTAGE_BUILDDIR", "PORTAGE_COLORMAP",
2823 + "PORTAGE_CONFIGROOT", "PORTAGE_DEBUG", "PORTAGE_DEPCACHEDIR",
2824 + "PORTAGE_GID", "PORTAGE_INST_GID", "PORTAGE_INST_UID",
2825 + "PORTAGE_IUSE",
2826 + "PORTAGE_LOG_FILE", "PORTAGE_MASTER_PID",
2827 + "PORTAGE_PYM_PATH", "PORTAGE_QUIET",
2828 + "PORTAGE_REPO_NAME", "PORTAGE_RESTRICT",
2829 + "PORTAGE_TMPDIR", "PORTAGE_UPDATE_ENV",
2830 + "PORTAGE_VERBOSE", "PORTAGE_WORKDIR_MODE",
2831 + "PORTDIR", "PORTDIR_OVERLAY", "PREROOTPATH", "PROFILE_PATHS",
2832 + "ROOT", "ROOTPATH", "T", "TMP", "TMPDIR",
2833 + "USE_EXPAND", "USE_ORDER", "WORKDIR",
2834 + "XARGS",
2835 + ]
2836 +
2837 + # user config variables
2838 + _environ_whitelist += [
2839 + "DOC_SYMLINKS_DIR", "INSTALL_MASK", "PKG_INSTALL_MASK"
2840 + ]
2841 +
2842 + _environ_whitelist += [
2843 + "A", "AA", "CATEGORY", "P", "PF", "PN", "PR", "PV", "PVR"
2844 + ]
2845 +
2846 + # misc variables inherited from the calling environment
2847 + _environ_whitelist += [
2848 + "COLORTERM", "DISPLAY", "EDITOR", "LESS",
2849 + "LESSOPEN", "LOGNAME", "LS_COLORS", "PAGER",
2850 + "TERM", "TERMCAP", "USER",
2851 + ]
2852 +
2853 + # tempdir settings
2854 + _environ_whitelist += [
2855 + "TMPDIR", "TEMP", "TMP",
2856 + ]
2857 +
2858 + # localization settings
2859 + _environ_whitelist += [
2860 + "LANG", "LC_COLLATE", "LC_CTYPE", "LC_MESSAGES",
2861 + "LC_MONETARY", "LC_NUMERIC", "LC_TIME", "LC_PAPER",
2862 + "LC_ALL",
2863 + ]
2864 +
2865 + # other variables inherited from the calling environment
2866 + _environ_whitelist += [
2867 + "CVS_RSH", "ECHANGELOG_USER",
2868 + "GPG_AGENT_INFO",
2869 + "SSH_AGENT_PID", "SSH_AUTH_SOCK",
2870 + "STY", "WINDOW", "XAUTHORITY",
2871 + ]
2872 +
2873 + _environ_whitelist = frozenset(_environ_whitelist)
2874 +
2875 + _environ_whitelist_re = re.compile(r'^(CCACHE_|DISTCC_).*')
2876 +
2877 + # Filter selected variables in the config.environ() method so that
2878 + # they don't needlessly propagate down into the ebuild environment.
2879 + _environ_filter = []
2880 +
2881 + # Exclude anything that could be extremely long here (like SRC_URI)
2882 + # since that could cause execve() calls to fail with E2BIG errors. For
2883 + # example, see bug #262647.
2884 + _environ_filter += [
2885 + 'DEPEND', 'RDEPEND', 'PDEPEND', 'SRC_URI',
2886 + ]
2887 +
2888 + # misc variables inherited from the calling environment
2889 + _environ_filter += [
2890 + "INFOPATH", "MANPATH", "USER",
2891 + ]
2892 +
2893 + # variables that break bash
2894 + _environ_filter += [
2895 + "HISTFILE", "POSIXLY_CORRECT",
2896 + ]
2897 +
2898 + # portage config variables and variables set directly by portage
2899 + _environ_filter += [
2900 + "ACCEPT_KEYWORDS", "ACCEPT_PROPERTIES", "AUTOCLEAN",
2901 + "CLEAN_DELAY", "COLLISION_IGNORE", "CONFIG_PROTECT",
2902 + "CONFIG_PROTECT_MASK", "EGENCACHE_DEFAULT_OPTS", "EMERGE_DEFAULT_OPTS",
2903 + "EMERGE_LOG_DIR",
2904 + "EMERGE_WARNING_DELAY", "FETCHCOMMAND", "FETCHCOMMAND_FTP",
2905 + "FETCHCOMMAND_HTTP", "FETCHCOMMAND_SFTP",
2906 + "GENTOO_MIRRORS", "NOCONFMEM", "O",
2907 + "PORTAGE_BACKGROUND",
2908 + "PORTAGE_BINHOST_CHUNKSIZE", "PORTAGE_CALLER",
2909 + "PORTAGE_ELOG_CLASSES",
2910 + "PORTAGE_ELOG_MAILFROM", "PORTAGE_ELOG_MAILSUBJECT",
2911 + "PORTAGE_ELOG_MAILURI", "PORTAGE_ELOG_SYSTEM",
2912 + "PORTAGE_FETCH_CHECKSUM_TRY_MIRRORS", "PORTAGE_FETCH_RESUME_MIN_SIZE",
2913 + "PORTAGE_GPG_DIR",
2914 + "PORTAGE_GPG_KEY", "PORTAGE_IONICE_COMMAND",
2915 + "PORTAGE_PACKAGE_EMPTY_ABORT",
2916 + "PORTAGE_REPO_DUPLICATE_WARN",
2917 + "PORTAGE_RO_DISTDIRS",
2918 + "PORTAGE_RSYNC_EXTRA_OPTS", "PORTAGE_RSYNC_OPTS",
2919 + "PORTAGE_RSYNC_RETRIES", "PORTAGE_USE", "PORT_LOGDIR",
2920 + "QUICKPKG_DEFAULT_OPTS",
2921 + "RESUMECOMMAND", "RESUMECOMMAND_HTTP", "RESUMECOMMAND_HTTP",
2922 + "RESUMECOMMAND_SFTP", "SYNC", "USE_EXPAND_HIDDEN", "USE_ORDER",
2923 + ]
2924 +
2925 + _environ_filter = frozenset(_environ_filter)
2926 +
2927 + _undef_lic_groups = set()
2928 + _default_globals = (
2929 + ('ACCEPT_LICENSE', '* -@EULA'),
2930 + ('ACCEPT_PROPERTIES', '*'),
2931 + )
2932 +
2933 + # To enhance usability, make some vars case insensitive
2934 + # by forcing them to lower case.
2935 + _case_insensitive_vars = ('AUTOCLEAN', 'NOCOLOR',)
2936 +
2937 + def __init__(self, clone=None, mycpv=None, config_profile_path=None,
2938 + config_incrementals=None, config_root=None, target_root=None,
2939 + local_config=True, env=None):
2940 + """
2941 + @param clone: If provided, init will use deepcopy to copy by value the instance.
2942 + @type clone: Instance of config class.
2943 + @param mycpv: CPV to load up (see setcpv), this is the same as calling init with mycpv=None
2944 + and then calling instance.setcpv(mycpv).
2945 + @type mycpv: String
2946 + @param config_profile_path: Configurable path to the profile (usually PROFILE_PATH from portage.const)
2947 + @type config_profile_path: String
2948 + @param config_incrementals: List of incremental variables
2949 + (defaults to portage.const.INCREMENTALS)
2950 + @type config_incrementals: List
2951 + @param config_root: path to read local config from (defaults to "/", see PORTAGE_CONFIGROOT)
2952 + @type config_root: String
2953 + @param target_root: __init__ override of $ROOT env variable.
2954 + @type target_root: String
2955 + @param local_config: Enables loading of local config (/etc/portage); used most by repoman to
2956 + ignore local config (keywording and unmasking)
2957 + @type local_config: Boolean
2958 + @param env: The calling environment which is used to override settings.
2959 + Defaults to os.environ if unspecified.
2960 + @type env: dict
2961 + """
2962 +
2963 + # When initializing the global portage.settings instance, avoid
2964 + # raising exceptions whenever possible since exceptions thrown
2965 + # from 'import portage' or 'import portage.exceptions' statements
2966 + # can practically render the api unusable for api consumers.
2967 + tolerant = hasattr(portage, '_initializing_globals')
2968 +
2969 + self.already_in_regenerate = 0
2970 +
2971 + self.locked = 0
2972 + self.mycpv = None
2973 + self._setcpv_args_hash = None
2974 + self.puse = []
2975 + self.modifiedkeys = []
2976 + self.uvlist = []
2977 + self._accept_chost_re = None
2978 + self._accept_license = None
2979 + self._accept_license_str = None
2980 + self._license_groups = {}
2981 + self._accept_properties = None
2982 +
2983 + self.virtuals = {}
2984 + self.virts_p = {}
2985 + self.dirVirtuals = None
2986 + self.v_count = 0
2987 +
2988 + # Virtuals obtained from the vartree
2989 + self.treeVirtuals = {}
2990 + # Virtuals by user specification. Includes negatives.
2991 + self.userVirtuals = {}
2992 + # Virtual negatives from user specifications.
2993 + self.negVirtuals = {}
2994 + # Virtuals added by the depgraph via self.setinst().
2995 + self._depgraphVirtuals = {}
2996 +
2997 + self.user_profile_dir = None
2998 + self.local_config = local_config
2999 + self._local_repo_configs = None
3000 + self._local_repo_conf_path = None
3001 +
3002 + if clone:
3003 + # For immutable attributes, use shallow copy for
3004 + # speed and memory conservation.
3005 + self.categories = clone.categories
3006 + self.depcachedir = clone.depcachedir
3007 + self.incrementals = clone.incrementals
3008 + self.module_priority = clone.module_priority
3009 + self.profile_path = clone.profile_path
3010 + self.profiles = clone.profiles
3011 + self.packages = clone.packages
3012 + self.useforce_list = clone.useforce_list
3013 + self.usemask_list = clone.usemask_list
3014 +
3015 + self.user_profile_dir = copy.deepcopy(clone.user_profile_dir)
3016 + self.local_config = copy.deepcopy(clone.local_config)
3017 + self._local_repo_configs = \
3018 + copy.deepcopy(clone._local_repo_configs)
3019 + self._local_repo_conf_path = \
3020 + copy.deepcopy(clone._local_repo_conf_path)
3021 + self.modules = copy.deepcopy(clone.modules)
3022 + self.virtuals = copy.deepcopy(clone.virtuals)
3023 + self.dirVirtuals = copy.deepcopy(clone.dirVirtuals)
3024 + self.treeVirtuals = copy.deepcopy(clone.treeVirtuals)
3025 + self.userVirtuals = copy.deepcopy(clone.userVirtuals)
3026 + self.negVirtuals = copy.deepcopy(clone.negVirtuals)
3027 + self._depgraphVirtuals = copy.deepcopy(clone._depgraphVirtuals)
3028 +
3029 + self.use_defs = copy.deepcopy(clone.use_defs)
3030 + self.usemask = copy.deepcopy(clone.usemask)
3031 + self.pusemask_list = copy.deepcopy(clone.pusemask_list)
3032 + self.useforce = copy.deepcopy(clone.useforce)
3033 + self.puseforce_list = copy.deepcopy(clone.puseforce_list)
3034 + self.puse = copy.deepcopy(clone.puse)
3035 + self.make_defaults_use = copy.deepcopy(clone.make_defaults_use)
3036 + self.pkgprofileuse = copy.deepcopy(clone.pkgprofileuse)
3037 + self.mycpv = copy.deepcopy(clone.mycpv)
3038 + self._setcpv_args_hash = copy.deepcopy(clone._setcpv_args_hash)
3039 +
3040 + self.configdict = copy.deepcopy(clone.configdict)
3041 + self.configlist = [
3042 + self.configdict['env.d'],
3043 + self.configdict['pkginternal'],
3044 + self.configdict['globals'],
3045 + self.configdict['defaults'],
3046 + self.configdict['conf'],
3047 + self.configdict['pkg'],
3048 + self.configdict['auto'],
3049 + self.configdict['env'],
3050 + ]
3051 + self.lookuplist = self.configlist[:]
3052 + self.lookuplist.reverse()
3053 + self._use_expand_dict = copy.deepcopy(clone._use_expand_dict)
3054 + self.backupenv = self.configdict["backupenv"]
3055 + self.pusedict = copy.deepcopy(clone.pusedict)
3056 + self.pkeywordsdict = copy.deepcopy(clone.pkeywordsdict)
3057 + self._pkeywords_list = copy.deepcopy(clone._pkeywords_list)
3058 + self.pmaskdict = copy.deepcopy(clone.pmaskdict)
3059 + self.punmaskdict = copy.deepcopy(clone.punmaskdict)
3060 + self.prevmaskdict = copy.deepcopy(clone.prevmaskdict)
3061 + self.pprovideddict = copy.deepcopy(clone.pprovideddict)
3062 + self.features = copy.deepcopy(clone.features)
3063 +
3064 + self._accept_license = copy.deepcopy(clone._accept_license)
3065 + self._plicensedict = copy.deepcopy(clone._plicensedict)
3066 + self._license_groups = copy.deepcopy(clone._license_groups)
3067 + self._accept_properties = copy.deepcopy(clone._accept_properties)
3068 + self._ppropertiesdict = copy.deepcopy(clone._ppropertiesdict)
3069 + else:
3070 +
3071 + def check_var_directory(varname, var):
3072 + if not os.path.isdir(var):
3073 + writemsg(_("!!! Error: %s='%s' is not a directory. "
3074 + "Please correct this.\n") % (varname, var),
3075 + noiselevel=-1)
3076 + raise DirectoryNotFound(var)
3077 +
3078 + if config_root is None:
3079 + config_root = "/"
3080 +
3081 + config_root = normalize_path(os.path.abspath(
3082 + config_root)).rstrip(os.path.sep) + os.path.sep
3083 +
3084 + check_var_directory("PORTAGE_CONFIGROOT", config_root)
3085 +
3086 + self.depcachedir = DEPCACHE_PATH
3087 +
3088 + if not config_profile_path:
3089 + config_profile_path = \
3090 + os.path.join(config_root, PROFILE_PATH)
3091 + if os.path.isdir(config_profile_path):
3092 + self.profile_path = config_profile_path
3093 + else:
3094 + self.profile_path = None
3095 + else:
3096 + self.profile_path = config_profile_path
3097 +
3098 + if config_incrementals is None:
3099 + self.incrementals = INCREMENTALS
3100 + else:
3101 + self.incrementals = config_incrementals
3102 + if not isinstance(self.incrementals, tuple):
3103 + self.incrementals = tuple(self.incrementals)
3104 +
3105 + self.module_priority = ("user", "default")
3106 + self.modules = {}
3107 + modules_loader = KeyValuePairFileLoader(
3108 + os.path.join(config_root, MODULES_FILE_PATH), None, None)
3109 + modules_dict, modules_errors = modules_loader.load()
3110 + self.modules["user"] = modules_dict
3111 + if self.modules["user"] is None:
3112 + self.modules["user"] = {}
3113 + self.modules["default"] = {
3114 + "portdbapi.metadbmodule": "portage.cache.metadata.database",
3115 + "portdbapi.auxdbmodule": "portage.cache.flat_hash.database",
3116 + }
3117 +
3118 + self.usemask=[]
3119 + self.configlist=[]
3120 +
3121 + # back up our incremental variables:
3122 + self.configdict={}
3123 + self._use_expand_dict = {}
3124 + # configlist will contain: [ env.d, globals, defaults, conf, pkg, auto, backupenv, env ]
3125 + self.configlist.append({})
3126 + self.configdict["env.d"] = self.configlist[-1]
3127 +
3128 + self.configlist.append({})
3129 + self.configdict["pkginternal"] = self.configlist[-1]
3130 +
3131 + # The symlink might not exist or might not be a symlink.
3132 + if self.profile_path is None:
3133 + self.profiles = []
3134 + else:
3135 + self.profiles = []
3136 + def addProfile(currentPath):
3137 + parentsFile = os.path.join(currentPath, "parent")
3138 + eapi_file = os.path.join(currentPath, "eapi")
3139 + try:
3140 + eapi = codecs.open(_unicode_encode(eapi_file,
3141 + encoding=_encodings['fs'], errors='strict'),
3142 + mode='r', encoding=_encodings['content'], errors='replace'
3143 + ).readline().strip()
3144 + except IOError:
3145 + pass
3146 + else:
3147 + if not eapi_is_supported(eapi):
3148 + raise ParseError(_(
3149 + "Profile contains unsupported "
3150 + "EAPI '%s': '%s'") % \
3151 + (eapi, os.path.realpath(eapi_file),))
3152 + if os.path.exists(parentsFile):
3153 + parents = grabfile(parentsFile)
3154 + if not parents:
3155 + raise ParseError(
3156 + _("Empty parent file: '%s'") % parentsFile)
3157 + for parentPath in parents:
3158 + parentPath = normalize_path(os.path.join(
3159 + currentPath, parentPath))
3160 + if os.path.exists(parentPath):
3161 + addProfile(parentPath)
3162 + else:
3163 + raise ParseError(
3164 + _("Parent '%s' not found: '%s'") % \
3165 + (parentPath, parentsFile))
3166 + self.profiles.append(currentPath)
3167 + try:
3168 + addProfile(os.path.realpath(self.profile_path))
3169 + except ParseError as e:
3170 + writemsg(_("!!! Unable to parse profile: '%s'\n") % \
3171 + self.profile_path, noiselevel=-1)
3172 + writemsg("!!! ParseError: %s\n" % str(e), noiselevel=-1)
3173 + del e
3174 + self.profiles = []
3175 + if local_config and self.profiles:
3176 + custom_prof = os.path.join(
3177 + config_root, CUSTOM_PROFILE_PATH)
3178 + if os.path.exists(custom_prof):
3179 + self.user_profile_dir = custom_prof
3180 + self.profiles.append(custom_prof)
3181 + del custom_prof
3182 +
3183 + self.profiles = tuple(self.profiles)
3184 + self.packages_list = [grabfile_package(os.path.join(x, "packages")) for x in self.profiles]
3185 + self.packages = tuple(stack_lists(self.packages_list, incremental=1))
3186 + del self.packages_list
3187 + #self.packages = grab_stacked("packages", self.profiles, grabfile, incremental_lines=1)
3188 +
3189 + # revmaskdict
3190 + self.prevmaskdict={}
3191 + for x in self.packages:
3192 + # Negative atoms are filtered by the above stack_lists() call.
3193 + if not isinstance(x, Atom):
3194 + x = Atom(x.lstrip('*'))
3195 + self.prevmaskdict.setdefault(x.cp, []).append(x)
3196 +
3197 + self._pkeywords_list = []
3198 + rawpkeywords = [grabdict_package(
3199 + os.path.join(x, "package.keywords"), recursive=1) \
3200 + for x in self.profiles]
3201 + for pkeyworddict in rawpkeywords:
3202 + cpdict = {}
3203 + for k, v in pkeyworddict.items():
3204 + cpdict.setdefault(k.cp, {})[k] = v
3205 + self._pkeywords_list.append(cpdict)
3206 +
3207 + # get profile-masked use flags -- INCREMENTAL Child over parent
3208 + self.usemask_list = tuple(
3209 + tuple(grabfile(os.path.join(x, "use.mask"), recursive=1))
3210 + for x in self.profiles)
3211 + self.usemask = set(stack_lists(
3212 + self.usemask_list, incremental=True))
3213 + use_defs_lists = [grabdict(os.path.join(x, "use.defaults")) for x in self.profiles]
3214 + self.use_defs = stack_dictlist(use_defs_lists, incremental=True)
3215 + del use_defs_lists
3216 +
3217 + self.pusemask_list = []
3218 + rawpusemask = [grabdict_package(os.path.join(x, "package.use.mask"),
3219 + recursive=1) for x in self.profiles]
3220 + for pusemaskdict in rawpusemask:
3221 + cpdict = {}
3222 + for k, v in pusemaskdict.items():
3223 + cpdict.setdefault(k.cp, {})[k] = v
3224 + self.pusemask_list.append(cpdict)
3225 + del rawpusemask
3226 +
3227 + self.pkgprofileuse = []
3228 + rawprofileuse = [grabdict_package(os.path.join(x, "package.use"),
3229 + juststrings=True, recursive=1) for x in self.profiles]
3230 + for rawpusedict in rawprofileuse:
3231 + cpdict = {}
3232 + for k, v in rawpusedict.items():
3233 + cpdict.setdefault(k.cp, {})[k] = v
3234 + self.pkgprofileuse.append(cpdict)
3235 + del rawprofileuse
3236 +
3237 + self.useforce_list = tuple(
3238 + tuple(grabfile(os.path.join(x, "use.force"), recursive=1))
3239 + for x in self.profiles)
3240 + self.useforce = set(stack_lists(
3241 + self.useforce_list, incremental=True))
3242 +
3243 + self.puseforce_list = []
3244 + rawpuseforce = [grabdict_package(
3245 + os.path.join(x, "package.use.force"), recursive=1) \
3246 + for x in self.profiles]
3247 + for rawpusefdict in rawpuseforce:
3248 + cpdict = {}
3249 + for k, v in rawpusefdict.items():
3250 + cpdict.setdefault(k.cp, {})[k] = v
3251 + self.puseforce_list.append(cpdict)
3252 + del rawpuseforce
3253 +
3254 + make_conf = getconfig(
3255 + os.path.join(config_root, MAKE_CONF_FILE),
3256 + tolerant=tolerant, allow_sourcing=True)
3257 + if make_conf is None:
3258 + make_conf = {}
3259 +
3260 + # Allow ROOT setting to come from make.conf if it's not overridden
3261 + # by the constructor argument (from the calling environment).
3262 + if target_root is None and "ROOT" in make_conf:
3263 + target_root = make_conf["ROOT"]
3264 + if not target_root.strip():
3265 + target_root = None
3266 + if target_root is None:
3267 + target_root = "/"
3268 +
3269 + target_root = normalize_path(os.path.abspath(
3270 + target_root)).rstrip(os.path.sep) + os.path.sep
3271 +
3272 + ensure_dirs(target_root)
3273 + check_var_directory("ROOT", target_root)
3274 +
3275 + # The expand_map is used for variable substitution
3276 + # in getconfig() calls, and the getconfig() calls
3277 + # update expand_map with the value of each variable
3278 + # assignment that occurs. Variable substitution occurs
3279 + # in the following order, which corresponds to the
3280 + # order of appearance in self.lookuplist:
3281 + #
3282 + # * env.d
3283 + # * make.globals
3284 + # * make.defaults
3285 + # * make.conf
3286 + #
3287 + # Notably absent is "env", since we want to avoid any
3288 + # interaction with the calling environment that might
3289 + # lead to unexpected results.
3290 + expand_map = {}
3291 +
3292 + env_d = getconfig(os.path.join(target_root, "etc", "profile.env"),
3293 + expand=expand_map)
3294 + # env_d will be None if profile.env doesn't exist.
3295 + if env_d:
3296 + self.configdict["env.d"].update(env_d)
3297 + expand_map.update(env_d)
3298 +
3299 + # backupenv is used for calculating incremental variables.
3300 + if env is None:
3301 + env = os.environ
3302 +
3303 + # Avoid potential UnicodeDecodeError exceptions later.
3304 + env_unicode = dict((_unicode_decode(k), _unicode_decode(v))
3305 + for k, v in env.items())
3306 +
3307 + self.backupenv = env_unicode
3308 +
3309 + if env_d:
3310 + # Remove duplicate values so they don't override updated
3311 + # profile.env values later (profile.env is reloaded in each
3312 + # call to self.regenerate).
3313 + for k, v in env_d.items():
3314 + try:
3315 + if self.backupenv[k] == v:
3316 + del self.backupenv[k]
3317 + except KeyError:
3318 + pass
3319 + del k, v
3320 +
3321 + self.configdict["env"] = LazyItemsDict(self.backupenv)
3322 +
3323 + # make.globals should not be relative to config_root
3324 + # because it only contains constants.
3325 + for x in (GLOBAL_CONFIG_PATH, "/etc"):
3326 + self.mygcfg = getconfig(os.path.join(x, "make.globals"),
3327 + expand=expand_map)
3328 + if self.mygcfg:
3329 + break
3330 +
3331 + if self.mygcfg is None:
3332 + self.mygcfg = {}
3333 +
3334 + for k, v in self._default_globals:
3335 + self.mygcfg.setdefault(k, v)
3336 +
3337 + self.configlist.append(self.mygcfg)
3338 + self.configdict["globals"]=self.configlist[-1]
3339 +
3340 + self.make_defaults_use = []
3341 + self.mygcfg = {}
3342 + if self.profiles:
3343 + mygcfg_dlists = [getconfig(os.path.join(x, "make.defaults"),
3344 + expand=expand_map) for x in self.profiles]
3345 +
3346 + for cfg in mygcfg_dlists:
3347 + if cfg:
3348 + self.make_defaults_use.append(cfg.get("USE", ""))
3349 + else:
3350 + self.make_defaults_use.append("")
3351 + self.mygcfg = stack_dicts(mygcfg_dlists,
3352 + incrementals=INCREMENTALS)
3353 + if self.mygcfg is None:
3354 + self.mygcfg = {}
3355 + self.configlist.append(self.mygcfg)
3356 + self.configdict["defaults"]=self.configlist[-1]
3357 +
3358 + self.mygcfg = getconfig(
3359 + os.path.join(config_root, MAKE_CONF_FILE),
3360 + tolerant=tolerant, allow_sourcing=True, expand=expand_map)
3361 + if self.mygcfg is None:
3362 + self.mygcfg = {}
3363 +
3364 + # Don't allow the user to override certain variables in make.conf
3365 + profile_only_variables = self.configdict["defaults"].get(
3366 + "PROFILE_ONLY_VARIABLES", "").split()
3367 + for k in profile_only_variables:
3368 + self.mygcfg.pop(k, None)
3369 +
3370 + self.configlist.append(self.mygcfg)
3371 + self.configdict["conf"]=self.configlist[-1]
3372 +
3373 + self.configlist.append(LazyItemsDict())
3374 + self.configdict["pkg"]=self.configlist[-1]
3375 +
3376 + #auto-use:
3377 + self.configlist.append({})
3378 + self.configdict["auto"]=self.configlist[-1]
3379 +
3380 + self.configdict["backupenv"] = self.backupenv
3381 +
3382 + # Don't allow the user to override certain variables in the env
3383 + for k in profile_only_variables:
3384 + self.backupenv.pop(k, None)
3385 +
3386 + self.configlist.append(self.configdict["env"])
3387 +
3388 + # make lookuplist for loading package.*
3389 + self.lookuplist=self.configlist[:]
3390 + self.lookuplist.reverse()
3391 +
3392 + # Blacklist vars that could interfere with portage internals.
3393 + for blacklisted in self._env_blacklist:
3394 + for cfg in self.lookuplist:
3395 + cfg.pop(blacklisted, None)
3396 + self.backupenv.pop(blacklisted, None)
3397 + del blacklisted, cfg
3398 +
3399 + self["PORTAGE_CONFIGROOT"] = config_root
3400 + self.backup_changes("PORTAGE_CONFIGROOT")
3401 + self["ROOT"] = target_root
3402 + self.backup_changes("ROOT")
3403 +
3404 + # Prefix forward compatability, set EPREFIX to the empty string
3405 + self["EPREFIX"] = ''
3406 + self.backup_changes("EPREFIX")
3407 + self["EROOT"] = target_root
3408 + self.backup_changes("EROOT")
3409 +
3410 + self.pusedict = {}
3411 + self.pkeywordsdict = {}
3412 + self._plicensedict = {}
3413 + self._ppropertiesdict = {}
3414 + self.punmaskdict = {}
3415 + abs_user_config = os.path.join(config_root, USER_CONFIG_PATH)
3416 +
3417 + # locations for "categories" and "arch.list" files
3418 + locations = [os.path.join(self["PORTDIR"], "profiles")]
3419 + pmask_locations = [os.path.join(self["PORTDIR"], "profiles")]
3420 + pmask_locations.extend(self.profiles)
3421 +
3422 + """ repoman controls PORTDIR_OVERLAY via the environment, so no
3423 + special cases are needed here."""
3424 + overlay_profiles = []
3425 + for ov in self["PORTDIR_OVERLAY"].split():
3426 + ov = normalize_path(ov)
3427 + profiles_dir = os.path.join(ov, "profiles")
3428 + if os.path.isdir(profiles_dir):
3429 + overlay_profiles.append(profiles_dir)
3430 + locations += overlay_profiles
3431 +
3432 + pmask_locations.extend(overlay_profiles)
3433 +
3434 + if local_config:
3435 + locations.append(abs_user_config)
3436 + pmask_locations.append(abs_user_config)
3437 + pusedict = grabdict_package(
3438 + os.path.join(abs_user_config, "package.use"), recursive=1)
3439 + for k, v in pusedict.items():
3440 + self.pusedict.setdefault(k.cp, {})[k] = v
3441 +
3442 + #package.keywords
3443 + pkgdict = grabdict_package(
3444 + os.path.join(abs_user_config, "package.keywords"),
3445 + recursive=1)
3446 + for k, v in pkgdict.items():
3447 + # default to ~arch if no specific keyword is given
3448 + if not v:
3449 + mykeywordlist = []
3450 + if self.configdict["defaults"] and \
3451 + "ACCEPT_KEYWORDS" in self.configdict["defaults"]:
3452 + groups = self.configdict["defaults"]["ACCEPT_KEYWORDS"].split()
3453 + else:
3454 + groups = []
3455 + for keyword in groups:
3456 + if not keyword[0] in "~-":
3457 + mykeywordlist.append("~"+keyword)
3458 + v = mykeywordlist
3459 + self.pkeywordsdict.setdefault(k.cp, {})[k] = v
3460 +
3461 + #package.license
3462 + licdict = grabdict_package(os.path.join(
3463 + abs_user_config, "package.license"), recursive=1)
3464 + for k, v in licdict.items():
3465 + cp = k.cp
3466 + cp_dict = self._plicensedict.get(cp)
3467 + if not cp_dict:
3468 + cp_dict = {}
3469 + self._plicensedict[cp] = cp_dict
3470 + cp_dict[k] = self.expandLicenseTokens(v)
3471 +
3472 + #package.properties
3473 + propdict = grabdict_package(os.path.join(
3474 + abs_user_config, "package.properties"), recursive=1)
3475 + for k, v in propdict.items():
3476 + cp = k.cp
3477 + cp_dict = self._ppropertiesdict.get(cp)
3478 + if not cp_dict:
3479 + cp_dict = {}
3480 + self._ppropertiesdict[cp] = cp_dict
3481 + cp_dict[k] = v
3482 +
3483 + self._local_repo_configs = {}
3484 + self._local_repo_conf_path = \
3485 + os.path.join(abs_user_config, 'repos.conf')
3486 +
3487 + repo_conf_parser = SafeConfigParser()
3488 + try:
3489 + repo_conf_parser.readfp(
3490 + codecs.open(
3491 + _unicode_encode(self._local_repo_conf_path,
3492 + encoding=_encodings['fs'], errors='strict'),
3493 + mode='r', encoding=_encodings['content'], errors='replace')
3494 + )
3495 + except EnvironmentError as e:
3496 + if e.errno != errno.ENOENT:
3497 + raise
3498 + del e
3499 + except ParsingError as e:
3500 + writemsg_level(
3501 + _("!!! Error parsing '%s': %s\n") % \
3502 + (self._local_repo_conf_path, e),
3503 + level=logging.ERROR, noiselevel=-1)
3504 + del e
3505 + else:
3506 + repo_defaults = repo_conf_parser.defaults()
3507 + if repo_defaults:
3508 + self._local_repo_configs['DEFAULT'] = \
3509 + _local_repo_config('DEFAULT', repo_defaults)
3510 + for repo_name in repo_conf_parser.sections():
3511 + repo_opts = repo_defaults.copy()
3512 + for opt_name in repo_conf_parser.options(repo_name):
3513 + repo_opts[opt_name] = \
3514 + repo_conf_parser.get(repo_name, opt_name)
3515 + self._local_repo_configs[repo_name] = \
3516 + _local_repo_config(repo_name, repo_opts)
3517 +
3518 + #getting categories from an external file now
3519 + categories = [grabfile(os.path.join(x, "categories")) for x in locations]
3520 + category_re = dbapi._category_re
3521 + self.categories = tuple(sorted(
3522 + x for x in stack_lists(categories, incremental=1)
3523 + if category_re.match(x) is not None))
3524 + del categories
3525 +
3526 + archlist = [grabfile(os.path.join(x, "arch.list")) for x in locations]
3527 + archlist = stack_lists(archlist, incremental=1)
3528 + self.configdict["conf"]["PORTAGE_ARCHLIST"] = " ".join(archlist)
3529 +
3530 + # package.mask and package.unmask
3531 + pkgmasklines = []
3532 + pkgunmasklines = []
3533 + for x in pmask_locations:
3534 + pkgmasklines.append(grabfile_package(
3535 + os.path.join(x, "package.mask"), recursive=1))
3536 + pkgunmasklines.append(grabfile_package(
3537 + os.path.join(x, "package.unmask"), recursive=1))
3538 + pkgmasklines = stack_lists(pkgmasklines, incremental=1)
3539 + pkgunmasklines = stack_lists(pkgunmasklines, incremental=1)
3540 +
3541 + self.pmaskdict = {}
3542 + for x in pkgmasklines:
3543 + self.pmaskdict.setdefault(x.cp, []).append(x)
3544 +
3545 + for x in pkgunmasklines:
3546 + self.punmaskdict.setdefault(x.cp, []).append(x)
3547 +
3548 + pkgprovidedlines = [grabfile(os.path.join(x, "package.provided"), recursive=1) for x in self.profiles]
3549 + pkgprovidedlines = stack_lists(pkgprovidedlines, incremental=1)
3550 + has_invalid_data = False
3551 + for x in range(len(pkgprovidedlines)-1, -1, -1):
3552 + myline = pkgprovidedlines[x]
3553 + if not isvalidatom("=" + myline):
3554 + writemsg(_("Invalid package name in package.provided: %s\n") % \
3555 + myline, noiselevel=-1)
3556 + has_invalid_data = True
3557 + del pkgprovidedlines[x]
3558 + continue
3559 + cpvr = catpkgsplit(pkgprovidedlines[x])
3560 + if not cpvr or cpvr[0] == "null":
3561 + writemsg(_("Invalid package name in package.provided: ")+pkgprovidedlines[x]+"\n",
3562 + noiselevel=-1)
3563 + has_invalid_data = True
3564 + del pkgprovidedlines[x]
3565 + continue
3566 + if cpvr[0] == "virtual":
3567 + writemsg(_("Virtual package in package.provided: %s\n") % \
3568 + myline, noiselevel=-1)
3569 + has_invalid_data = True
3570 + del pkgprovidedlines[x]
3571 + continue
3572 + if has_invalid_data:
3573 + writemsg(_("See portage(5) for correct package.provided usage.\n"),
3574 + noiselevel=-1)
3575 + self.pprovideddict = {}
3576 + for x in pkgprovidedlines:
3577 + x_split = catpkgsplit(x)
3578 + if x_split is None:
3579 + continue
3580 + mycatpkg = cpv_getkey(x)
3581 + if mycatpkg in self.pprovideddict:
3582 + self.pprovideddict[mycatpkg].append(x)
3583 + else:
3584 + self.pprovideddict[mycatpkg]=[x]
3585 +
3586 + # parse licensegroups
3587 + license_groups = self._license_groups
3588 + for x in locations:
3589 + for k, v in grabdict(
3590 + os.path.join(x, "license_groups")).items():
3591 + license_groups.setdefault(k, []).extend(v)
3592 +
3593 + # reasonable defaults; this is important as without USE_ORDER,
3594 + # USE will always be "" (nothing set)!
3595 + if "USE_ORDER" not in self:
3596 + self.backupenv["USE_ORDER"] = "env:pkg:conf:defaults:pkginternal:env.d"
3597 +
3598 + self["PORTAGE_GID"] = str(portage_gid)
3599 + self.backup_changes("PORTAGE_GID")
3600 +
3601 + if self.get("PORTAGE_DEPCACHEDIR", None):
3602 + self.depcachedir = self["PORTAGE_DEPCACHEDIR"]
3603 + self["PORTAGE_DEPCACHEDIR"] = self.depcachedir
3604 + self.backup_changes("PORTAGE_DEPCACHEDIR")
3605 +
3606 + overlays = self.get("PORTDIR_OVERLAY","").split()
3607 + if overlays:
3608 + new_ov = []
3609 + for ov in overlays:
3610 + ov = normalize_path(ov)
3611 + if os.path.isdir(ov):
3612 + new_ov.append(ov)
3613 + else:
3614 + writemsg(_("!!! Invalid PORTDIR_OVERLAY"
3615 + " (not a dir): '%s'\n") % ov, noiselevel=-1)
3616 + self["PORTDIR_OVERLAY"] = " ".join(new_ov)
3617 + self.backup_changes("PORTDIR_OVERLAY")
3618 +
3619 + if "CBUILD" not in self and "CHOST" in self:
3620 + self["CBUILD"] = self["CHOST"]
3621 + self.backup_changes("CBUILD")
3622 +
3623 + self["PORTAGE_BIN_PATH"] = PORTAGE_BIN_PATH
3624 + self.backup_changes("PORTAGE_BIN_PATH")
3625 + self["PORTAGE_PYM_PATH"] = PORTAGE_PYM_PATH
3626 + self.backup_changes("PORTAGE_PYM_PATH")
3627 +
3628 + for var in ("PORTAGE_INST_UID", "PORTAGE_INST_GID"):
3629 + try:
3630 + self[var] = str(int(self.get(var, "0")))
3631 + except ValueError:
3632 + writemsg(_("!!! %s='%s' is not a valid integer. "
3633 + "Falling back to '0'.\n") % (var, self[var]),
3634 + noiselevel=-1)
3635 + self[var] = "0"
3636 + self.backup_changes(var)
3637 +
3638 + # initialize self.features
3639 + self.regenerate()
3640 +
3641 + if bsd_chflags:
3642 + self.features.add('chflags')
3643 +
3644 + self["FEATURES"] = " ".join(sorted(self.features))
3645 + self.backup_changes("FEATURES")
3646 + global _glep_55_enabled, _validate_cache_for_unsupported_eapis
3647 + if 'parse-eapi-ebuild-head' in self.features:
3648 + _validate_cache_for_unsupported_eapis = False
3649 + if 'parse-eapi-glep-55' in self.features:
3650 + _validate_cache_for_unsupported_eapis = False
3651 + _glep_55_enabled = True
3652 +
3653 + for k in self._case_insensitive_vars:
3654 + if k in self:
3655 + self[k] = self[k].lower()
3656 + self.backup_changes(k)
3657 +
3658 + if mycpv:
3659 + self.setcpv(mycpv)
3660 +
3661 + def _init_dirs(self):
3662 + """
3663 + Create a few directories that are critical to portage operation
3664 + """
3665 + if not os.access(self["ROOT"], os.W_OK):
3666 + return
3667 +
3668 + # gid, mode, mask, preserve_perms
3669 + dir_mode_map = {
3670 + "tmp" : ( -1, 0o1777, 0, True),
3671 + "var/tmp" : ( -1, 0o1777, 0, True),
3672 + PRIVATE_PATH : (portage_gid, 0o2750, 0o2, False),
3673 + CACHE_PATH : (portage_gid, 0o755, 0o2, False)
3674 + }
3675 +
3676 + for mypath, (gid, mode, modemask, preserve_perms) \
3677 + in dir_mode_map.items():
3678 + mydir = os.path.join(self["ROOT"], mypath)
3679 + if preserve_perms and os.path.isdir(mydir):
3680 + # Only adjust permissions on some directories if
3681 + # they don't exist yet. This gives freedom to the
3682 + # user to adjust permissions to suit their taste.
3683 + continue
3684 + try:
3685 + ensure_dirs(mydir, gid=gid, mode=mode, mask=modemask)
3686 + except PortageException as e:
3687 + writemsg(_("!!! Directory initialization failed: '%s'\n") % mydir,
3688 + noiselevel=-1)
3689 + writemsg("!!! %s\n" % str(e),
3690 + noiselevel=-1)
3691 +
3692 + def expandLicenseTokens(self, tokens):
3693 + """ Take a token from ACCEPT_LICENSE or package.license and expand it
3694 + if it's a group token (indicated by @) or just return it if it's not a
3695 + group. If a group is negated then negate all group elements."""
3696 + expanded_tokens = []
3697 + for x in tokens:
3698 + expanded_tokens.extend(self._expandLicenseToken(x, None))
3699 + return expanded_tokens
3700 +
3701 + def _expandLicenseToken(self, token, traversed_groups):
3702 + negate = False
3703 + rValue = []
3704 + if token.startswith("-"):
3705 + negate = True
3706 + license_name = token[1:]
3707 + else:
3708 + license_name = token
3709 + if not license_name.startswith("@"):
3710 + rValue.append(token)
3711 + return rValue
3712 + group_name = license_name[1:]
3713 + if traversed_groups is None:
3714 + traversed_groups = set()
3715 + license_group = self._license_groups.get(group_name)
3716 + if group_name in traversed_groups:
3717 + writemsg(_("Circular license group reference"
3718 + " detected in '%s'\n") % group_name, noiselevel=-1)
3719 + rValue.append("@"+group_name)
3720 + elif license_group:
3721 + traversed_groups.add(group_name)
3722 + for l in license_group:
3723 + if l.startswith("-"):
3724 + writemsg(_("Skipping invalid element %s"
3725 + " in license group '%s'\n") % (l, group_name),
3726 + noiselevel=-1)
3727 + else:
3728 + rValue.extend(self._expandLicenseToken(l, traversed_groups))
3729 + else:
3730 + if self._license_groups and \
3731 + group_name not in self._undef_lic_groups:
3732 + self._undef_lic_groups.add(group_name)
3733 + writemsg(_("Undefined license group '%s'\n") % group_name,
3734 + noiselevel=-1)
3735 + rValue.append("@"+group_name)
3736 + if negate:
3737 + rValue = ["-" + token for token in rValue]
3738 + return rValue
3739 +
3740 + def validate(self):
3741 + """Validate miscellaneous settings and display warnings if necessary.
3742 + (This code was previously in the global scope of portage.py)"""
3743 +
3744 + groups = self["ACCEPT_KEYWORDS"].split()
3745 + archlist = self.archlist()
3746 + if not archlist:
3747 + writemsg(_("--- 'profiles/arch.list' is empty or "
3748 + "not available. Empty portage tree?\n"), noiselevel=1)
3749 + else:
3750 + for group in groups:
3751 + if group not in archlist and \
3752 + not (group.startswith("-") and group[1:] in archlist) and \
3753 + group not in ("*", "~*", "**"):
3754 + writemsg(_("!!! INVALID ACCEPT_KEYWORDS: %s\n") % str(group),
3755 + noiselevel=-1)
3756 +
3757 + abs_profile_path = os.path.join(self["PORTAGE_CONFIGROOT"],
3758 + PROFILE_PATH)
3759 + if not self.profile_path or (not os.path.islink(abs_profile_path) and \
3760 + not os.path.exists(os.path.join(abs_profile_path, "parent")) and \
3761 + os.path.exists(os.path.join(self["PORTDIR"], "profiles"))):
3762 + writemsg(_("\a\n\n!!! %s is not a symlink and will probably prevent most merges.\n") % abs_profile_path,
3763 + noiselevel=-1)
3764 + writemsg(_("!!! It should point into a profile within %s/profiles/\n") % self["PORTDIR"])
3765 + writemsg(_("!!! (You can safely ignore this message when syncing. It's harmless.)\n\n\n"))
3766 +
3767 + abs_user_virtuals = os.path.join(self["PORTAGE_CONFIGROOT"],
3768 + USER_VIRTUALS_FILE)
3769 + if os.path.exists(abs_user_virtuals):
3770 + writemsg("\n!!! /etc/portage/virtuals is deprecated in favor of\n")
3771 + writemsg("!!! /etc/portage/profile/virtuals. Please move it to\n")
3772 + writemsg("!!! this new location.\n\n")
3773 +
3774 + if not sandbox_capable and \
3775 + ("sandbox" in self.features or "usersandbox" in self.features):
3776 + if self.profile_path is not None and \
3777 + os.path.realpath(self.profile_path) == \
3778 + os.path.realpath(os.path.join(
3779 + self["PORTAGE_CONFIGROOT"], PROFILE_PATH)):
3780 + # Don't show this warning when running repoman and the
3781 + # sandbox feature came from a profile that doesn't belong
3782 + # to the user.
3783 + writemsg(colorize("BAD", _("!!! Problem with sandbox"
3784 + " binary. Disabling...\n\n")), noiselevel=-1)
3785 +
3786 + if "fakeroot" in self.features and \
3787 + not fakeroot_capable:
3788 + writemsg(_("!!! FEATURES=fakeroot is enabled, but the "
3789 + "fakeroot binary is not installed.\n"), noiselevel=-1)
3790 +
3791 + def loadVirtuals(self,root):
3792 + """Not currently used by portage."""
3793 + writemsg("DEPRECATED: portage.config.loadVirtuals\n")
3794 + self.getvirtuals(root)
3795 +
3796 + def load_best_module(self,property_string):
3797 + best_mod = best_from_dict(property_string,self.modules,self.module_priority)
3798 + mod = None
3799 + try:
3800 + mod = load_mod(best_mod)
3801 + except ImportError:
3802 + if best_mod.startswith("cache."):
3803 + best_mod = "portage." + best_mod
3804 + try:
3805 + mod = load_mod(best_mod)
3806 + except ImportError:
3807 + pass
3808 + if mod is None:
3809 + raise
3810 + return mod
3811 +
3812 + def lock(self):
3813 + self.locked = 1
3814 +
3815 + def unlock(self):
3816 + self.locked = 0
3817 +
3818 + def modifying(self):
3819 + if self.locked:
3820 + raise Exception(_("Configuration is locked."))
3821 +
3822 + def backup_changes(self,key=None):
3823 + self.modifying()
3824 + if key and key in self.configdict["env"]:
3825 + self.backupenv[key] = copy.deepcopy(self.configdict["env"][key])
3826 + else:
3827 + raise KeyError(_("No such key defined in environment: %s") % key)
3828 +
3829 + def reset(self,keeping_pkg=0,use_cache=1):
3830 + """
3831 + Restore environment from self.backupenv, call self.regenerate()
3832 + @param keeping_pkg: Should we keep the set_cpv() data or delete it.
3833 + @type keeping_pkg: Boolean
3834 + @param use_cache: Should self.regenerate use the cache or not
3835 + @type use_cache: Boolean
3836 + @rype: None
3837 + """
3838 + self.modifying()
3839 + self.configdict["env"].clear()
3840 + self.configdict["env"].update(self.backupenv)
3841 +
3842 + self.modifiedkeys = []
3843 + if not keeping_pkg:
3844 + self.mycpv = None
3845 + self.puse = ""
3846 + self.configdict["pkg"].clear()
3847 + self.configdict["pkginternal"].clear()
3848 + self.configdict["defaults"]["USE"] = \
3849 + " ".join(self.make_defaults_use)
3850 + self.usemask = set(stack_lists(
3851 + self.usemask_list, incremental=True))
3852 + self.useforce = set(stack_lists(
3853 + self.useforce_list, incremental=True))
3854 + self.regenerate(use_cache=use_cache)
3855 +
3856 + class _lazy_vars(object):
3857 +
3858 + __slots__ = ('built_use', 'settings', 'values')
3859 +
3860 + def __init__(self, built_use, settings):
3861 + self.built_use = built_use
3862 + self.settings = settings
3863 + self.values = None
3864 +
3865 + def __getitem__(self, k):
3866 + if self.values is None:
3867 + self.values = self._init_values()
3868 + return self.values[k]
3869 +
3870 + def _init_values(self):
3871 + values = {}
3872 + settings = self.settings
3873 + use = self.built_use
3874 + if use is None:
3875 + use = frozenset(settings['PORTAGE_USE'].split())
3876 + values['ACCEPT_LICENSE'] = self._accept_license(use, settings)
3877 + values['PORTAGE_RESTRICT'] = self._restrict(use, settings)
3878 + return values
3879 +
3880 + def _accept_license(self, use, settings):
3881 + """
3882 + Generate a pruned version of ACCEPT_LICENSE, by intersection with
3883 + LICENSE. This is required since otherwise ACCEPT_LICENSE might be
3884 + too big (bigger than ARG_MAX), causing execve() calls to fail with
3885 + E2BIG errors as in bug #262647.
3886 + """
3887 + try:
3888 + licenses = set(flatten(
3889 + use_reduce(paren_reduce(
3890 + settings['LICENSE']),
3891 + uselist=use)))
3892 + except InvalidDependString:
3893 + licenses = set()
3894 + licenses.discard('||')
3895 + if settings._accept_license:
3896 + acceptable_licenses = set()
3897 + for x in settings._accept_license:
3898 + if x == '*':
3899 + acceptable_licenses.update(licenses)
3900 + elif x == '-*':
3901 + acceptable_licenses.clear()
3902 + elif x[:1] == '-':
3903 + acceptable_licenses.discard(x[1:])
3904 + elif x in licenses:
3905 + acceptable_licenses.add(x)
3906 +
3907 + licenses = acceptable_licenses
3908 + return ' '.join(sorted(licenses))
3909 +
3910 + def _restrict(self, use, settings):
3911 + try:
3912 + restrict = set(flatten(
3913 + use_reduce(paren_reduce(
3914 + settings['RESTRICT']),
3915 + uselist=use)))
3916 + except InvalidDependString:
3917 + restrict = set()
3918 + return ' '.join(sorted(restrict))
3919 +
3920 + class _lazy_use_expand(object):
3921 + """
3922 + Lazily evaluate USE_EXPAND variables since they are only needed when
3923 + an ebuild shell is spawned. Variables values are made consistent with
3924 + the previously calculated USE settings.
3925 + """
3926 +
3927 + def __init__(self, use, usemask, iuse_implicit,
3928 + use_expand_split, use_expand_dict):
3929 + self._use = use
3930 + self._usemask = usemask
3931 + self._iuse_implicit = iuse_implicit
3932 + self._use_expand_split = use_expand_split
3933 + self._use_expand_dict = use_expand_dict
3934 +
3935 + def __getitem__(self, key):
3936 + prefix = key.lower() + '_'
3937 + prefix_len = len(prefix)
3938 + expand_flags = set( x[prefix_len:] for x in self._use \
3939 + if x[:prefix_len] == prefix )
3940 + var_split = self._use_expand_dict.get(key, '').split()
3941 + # Preserve the order of var_split because it can matter for things
3942 + # like LINGUAS.
3943 + var_split = [ x for x in var_split if x in expand_flags ]
3944 + var_split.extend(expand_flags.difference(var_split))
3945 + has_wildcard = '*' in expand_flags
3946 + if has_wildcard:
3947 + var_split = [ x for x in var_split if x != "*" ]
3948 + has_iuse = set()
3949 + for x in self._iuse_implicit:
3950 + if x[:prefix_len] == prefix:
3951 + has_iuse.add(x[prefix_len:])
3952 + if has_wildcard:
3953 + # * means to enable everything in IUSE that's not masked
3954 + if has_iuse:
3955 + usemask = self._usemask
3956 + for suffix in has_iuse:
3957 + x = prefix + suffix
3958 + if x not in usemask:
3959 + if suffix not in expand_flags:
3960 + var_split.append(suffix)
3961 + else:
3962 + # If there is a wildcard and no matching flags in IUSE then
3963 + # LINGUAS should be unset so that all .mo files are
3964 + # installed.
3965 + var_split = []
3966 + # Make the flags unique and filter them according to IUSE.
3967 + # Also, continue to preserve order for things like LINGUAS
3968 + # and filter any duplicates that variable may contain.
3969 + filtered_var_split = []
3970 + remaining = has_iuse.intersection(var_split)
3971 + for x in var_split:
3972 + if x in remaining:
3973 + remaining.remove(x)
3974 + filtered_var_split.append(x)
3975 + var_split = filtered_var_split
3976 +
3977 + if var_split:
3978 + value = ' '.join(var_split)
3979 + else:
3980 + # Don't export empty USE_EXPAND vars unless the user config
3981 + # exports them as empty. This is required for vars such as
3982 + # LINGUAS, where unset and empty have different meanings.
3983 + if has_wildcard:
3984 + # ebuild.sh will see this and unset the variable so
3985 + # that things like LINGUAS work properly
3986 + value = '*'
3987 + else:
3988 + if has_iuse:
3989 + value = ''
3990 + else:
3991 + # It's not in IUSE, so just allow the variable content
3992 + # to pass through if it is defined somewhere. This
3993 + # allows packages that support LINGUAS but don't
3994 + # declare it in IUSE to use the variable outside of the
3995 + # USE_EXPAND context.
3996 + value = None
3997 +
3998 + return value
3999 +
4000 + def setcpv(self, mycpv, use_cache=1, mydb=None):
4001 + """
4002 + Load a particular CPV into the config, this lets us see the
4003 + Default USE flags for a particular ebuild as well as the USE
4004 + flags from package.use.
4005 +
4006 + @param mycpv: A cpv to load
4007 + @type mycpv: string
4008 + @param use_cache: Enables caching
4009 + @type use_cache: Boolean
4010 + @param mydb: a dbapi instance that supports aux_get with the IUSE key.
4011 + @type mydb: dbapi or derivative.
4012 + @rtype: None
4013 + """
4014 +
4015 + self.modifying()
4016 +
4017 + pkg = None
4018 + built_use = None
4019 + if not isinstance(mycpv, basestring):
4020 + pkg = mycpv
4021 + mycpv = pkg.cpv
4022 + mydb = pkg.metadata
4023 + args_hash = (mycpv, id(pkg))
4024 + if pkg.built:
4025 + built_use = pkg.use.enabled
4026 + else:
4027 + args_hash = (mycpv, id(mydb))
4028 +
4029 + if args_hash == self._setcpv_args_hash:
4030 + return
4031 + self._setcpv_args_hash = args_hash
4032 +
4033 + has_changed = False
4034 + self.mycpv = mycpv
4035 + cat, pf = catsplit(mycpv)
4036 + cp = cpv_getkey(mycpv)
4037 + cpv_slot = self.mycpv
4038 + pkginternaluse = ""
4039 + iuse = ""
4040 + pkg_configdict = self.configdict["pkg"]
4041 + previous_iuse = pkg_configdict.get("IUSE")
4042 +
4043 + aux_keys = self._setcpv_aux_keys
4044 +
4045 + # Discard any existing metadata from the previous package, but
4046 + # preserve things like USE_EXPAND values and PORTAGE_USE which
4047 + # might be reused.
4048 + for k in aux_keys:
4049 + pkg_configdict.pop(k, None)
4050 +
4051 + pkg_configdict["CATEGORY"] = cat
4052 + pkg_configdict["PF"] = pf
4053 + if mydb:
4054 + if not hasattr(mydb, "aux_get"):
4055 + for k in aux_keys:
4056 + if k in mydb:
4057 + # Make these lazy, since __getitem__ triggers
4058 + # evaluation of USE conditionals which can't
4059 + # occur until PORTAGE_USE is calculated below.
4060 + pkg_configdict.addLazySingleton(k,
4061 + mydb.__getitem__, k)
4062 + else:
4063 + for k, v in zip(aux_keys, mydb.aux_get(self.mycpv, aux_keys)):
4064 + pkg_configdict[k] = v
4065 + repository = pkg_configdict.pop("repository", None)
4066 + if repository is not None:
4067 + pkg_configdict["PORTAGE_REPO_NAME"] = repository
4068 + slot = pkg_configdict["SLOT"]
4069 + iuse = pkg_configdict["IUSE"]
4070 + if pkg is None:
4071 + cpv_slot = "%s:%s" % (self.mycpv, slot)
4072 + else:
4073 + cpv_slot = pkg
4074 + pkginternaluse = []
4075 + for x in iuse.split():
4076 + if x.startswith("+"):
4077 + pkginternaluse.append(x[1:])
4078 + elif x.startswith("-"):
4079 + pkginternaluse.append(x)
4080 + pkginternaluse = " ".join(pkginternaluse)
4081 + if pkginternaluse != self.configdict["pkginternal"].get("USE", ""):
4082 + self.configdict["pkginternal"]["USE"] = pkginternaluse
4083 + has_changed = True
4084 +
4085 + defaults = []
4086 + pos = 0
4087 + for i, pkgprofileuse_dict in enumerate(self.pkgprofileuse):
4088 + cpdict = pkgprofileuse_dict.get(cp)
4089 + if cpdict:
4090 + keys = list(cpdict)
4091 + while keys:
4092 + bestmatch = best_match_to_list(cpv_slot, keys)
4093 + if bestmatch:
4094 + keys.remove(bestmatch)
4095 + defaults.insert(pos, cpdict[bestmatch])
4096 + else:
4097 + break
4098 + del keys
4099 + if self.make_defaults_use[i]:
4100 + defaults.insert(pos, self.make_defaults_use[i])
4101 + pos = len(defaults)
4102 + defaults = " ".join(defaults)
4103 + if defaults != self.configdict["defaults"].get("USE",""):
4104 + self.configdict["defaults"]["USE"] = defaults
4105 + has_changed = True
4106 +
4107 + useforce = self._getUseForce(cpv_slot)
4108 + if useforce != self.useforce:
4109 + self.useforce = useforce
4110 + has_changed = True
4111 +
4112 + usemask = self._getUseMask(cpv_slot)
4113 + if usemask != self.usemask:
4114 + self.usemask = usemask
4115 + has_changed = True
4116 + oldpuse = self.puse
4117 + self.puse = ""
4118 + cpdict = self.pusedict.get(cp)
4119 + if cpdict:
4120 + keys = list(cpdict)
4121 + while keys:
4122 + self.pusekey = best_match_to_list(cpv_slot, keys)
4123 + if self.pusekey:
4124 + keys.remove(self.pusekey)
4125 + self.puse = (" ".join(cpdict[self.pusekey])) + " " + self.puse
4126 + else:
4127 + break
4128 + del keys
4129 + if oldpuse != self.puse:
4130 + has_changed = True
4131 + self.configdict["pkg"]["PKGUSE"] = self.puse[:] # For saving to PUSE file
4132 + self.configdict["pkg"]["USE"] = self.puse[:] # this gets appended to USE
4133 +
4134 + if has_changed:
4135 + self.reset(keeping_pkg=1,use_cache=use_cache)
4136 +
4137 + # Ensure that "pkg" values are always preferred over "env" values.
4138 + # This must occur _after_ the above reset() call, since reset()
4139 + # copies values from self.backupenv.
4140 + env_configdict = self.configdict['env']
4141 + for k in pkg_configdict:
4142 + if k != 'USE':
4143 + env_configdict.pop(k, None)
4144 +
4145 + lazy_vars = self._lazy_vars(built_use, self)
4146 + env_configdict.addLazySingleton('ACCEPT_LICENSE',
4147 + lazy_vars.__getitem__, 'ACCEPT_LICENSE')
4148 + env_configdict.addLazySingleton('PORTAGE_RESTRICT',
4149 + lazy_vars.__getitem__, 'PORTAGE_RESTRICT')
4150 +
4151 + # If reset() has not been called, it's safe to return
4152 + # early if IUSE has not changed.
4153 + if not has_changed and previous_iuse == iuse:
4154 + return
4155 +
4156 + # Filter out USE flags that aren't part of IUSE. This has to
4157 + # be done for every setcpv() call since practically every
4158 + # package has different IUSE.
4159 + use = set(self["USE"].split())
4160 + iuse_implicit = self._get_implicit_iuse()
4161 + iuse_implicit.update(x.lstrip("+-") for x in iuse.split())
4162 +
4163 + # PORTAGE_IUSE is not always needed so it's lazily evaluated.
4164 + self.configdict["pkg"].addLazySingleton(
4165 + "PORTAGE_IUSE", _lazy_iuse_regex, iuse_implicit)
4166 +
4167 + ebuild_force_test = self.get("EBUILD_FORCE_TEST") == "1"
4168 + if ebuild_force_test and \
4169 + not hasattr(self, "_ebuild_force_test_msg_shown"):
4170 + self._ebuild_force_test_msg_shown = True
4171 + writemsg(_("Forcing test.\n"), noiselevel=-1)
4172 + if "test" in self.features:
4173 + if "test" in self.usemask and not ebuild_force_test:
4174 + # "test" is in IUSE and USE=test is masked, so execution
4175 + # of src_test() probably is not reliable. Therefore,
4176 + # temporarily disable FEATURES=test just for this package.
4177 + self["FEATURES"] = " ".join(x for x in self.features \
4178 + if x != "test")
4179 + use.discard("test")
4180 + else:
4181 + use.add("test")
4182 + if ebuild_force_test:
4183 + self.usemask.discard("test")
4184 +
4185 + # Allow _* flags from USE_EXPAND wildcards to pass through here.
4186 + use.difference_update([x for x in use \
4187 + if x not in iuse_implicit and x[-2:] != '_*'])
4188 +
4189 + # Use the calculated USE flags to regenerate the USE_EXPAND flags so
4190 + # that they are consistent. For optimal performance, use slice
4191 + # comparison instead of startswith().
4192 + use_expand_split = set(x.lower() for \
4193 + x in self.get('USE_EXPAND', '').split())
4194 + lazy_use_expand = self._lazy_use_expand(use, self.usemask,
4195 + iuse_implicit, use_expand_split, self._use_expand_dict)
4196 +
4197 + use_expand_iuses = {}
4198 + for x in iuse_implicit:
4199 + x_split = x.split('_')
4200 + if len(x_split) == 1:
4201 + continue
4202 + for i in range(len(x_split) - 1):
4203 + k = '_'.join(x_split[:i+1])
4204 + if k in use_expand_split:
4205 + v = use_expand_iuses.get(k)
4206 + if v is None:
4207 + v = set()
4208 + use_expand_iuses[k] = v
4209 + v.add(x)
4210 + break
4211 +
4212 + # If it's not in IUSE, variable content is allowed
4213 + # to pass through if it is defined somewhere. This
4214 + # allows packages that support LINGUAS but don't
4215 + # declare it in IUSE to use the variable outside of the
4216 + # USE_EXPAND context.
4217 + for k, use_expand_iuse in use_expand_iuses.items():
4218 + if k + '_*' in use:
4219 + use.update( x for x in use_expand_iuse if x not in usemask )
4220 + k = k.upper()
4221 + self.configdict['env'].addLazySingleton(k,
4222 + lazy_use_expand.__getitem__, k)
4223 +
4224 + # Filtered for the ebuild environment. Store this in a separate
4225 + # attribute since we still want to be able to see global USE
4226 + # settings for things like emerge --info.
4227 +
4228 + self.configdict["pkg"]["PORTAGE_USE"] = \
4229 + " ".join(sorted(x for x in use if x[-2:] != '_*'))
4230 +
4231 + def _get_implicit_iuse(self):
4232 + """
4233 + Some flags are considered to
4234 + be implicit members of IUSE:
4235 + * Flags derived from ARCH
4236 + * Flags derived from USE_EXPAND_HIDDEN variables
4237 + * Masked flags, such as those from {,package}use.mask
4238 + * Forced flags, such as those from {,package}use.force
4239 + * build and bootstrap flags used by bootstrap.sh
4240 + """
4241 + iuse_implicit = set()
4242 + # Flags derived from ARCH.
4243 + arch = self.configdict["defaults"].get("ARCH")
4244 + if arch:
4245 + iuse_implicit.add(arch)
4246 + iuse_implicit.update(self.get("PORTAGE_ARCHLIST", "").split())
4247 +
4248 + # Flags derived from USE_EXPAND_HIDDEN variables
4249 + # such as ELIBC, KERNEL, and USERLAND.
4250 + use_expand_hidden = self.get("USE_EXPAND_HIDDEN", "").split()
4251 + for x in use_expand_hidden:
4252 + iuse_implicit.add(x.lower() + "_.*")
4253 +
4254 + # Flags that have been masked or forced.
4255 + iuse_implicit.update(self.usemask)
4256 + iuse_implicit.update(self.useforce)
4257 +
4258 + # build and bootstrap flags used by bootstrap.sh
4259 + iuse_implicit.add("build")
4260 + iuse_implicit.add("bootstrap")
4261 +
4262 + # Controlled by FEATURES=test. Make this implicit, so handling
4263 + # of FEATURES=test is consistent regardless of explicit IUSE.
4264 + # Users may use use.mask/package.use.mask to control
4265 + # FEATURES=test for all ebuilds, regardless of explicit IUSE.
4266 + iuse_implicit.add("test")
4267 +
4268 + return iuse_implicit
4269 +
4270 + def _getUseMask(self, pkg):
4271 + cp = getattr(pkg, "cp", None)
4272 + if cp is None:
4273 + cp = cpv_getkey(remove_slot(pkg))
4274 + usemask = []
4275 + pos = 0
4276 + for i, pusemask_dict in enumerate(self.pusemask_list):
4277 + cpdict = pusemask_dict.get(cp)
4278 + if cpdict:
4279 + keys = list(cpdict)
4280 + while keys:
4281 + best_match = best_match_to_list(pkg, keys)
4282 + if best_match:
4283 + keys.remove(best_match)
4284 + usemask.insert(pos, cpdict[best_match])
4285 + else:
4286 + break
4287 + del keys
4288 + if self.usemask_list[i]:
4289 + usemask.insert(pos, self.usemask_list[i])
4290 + pos = len(usemask)
4291 + return set(stack_lists(usemask, incremental=True))
4292 +
4293 + def _getUseForce(self, pkg):
4294 + cp = getattr(pkg, "cp", None)
4295 + if cp is None:
4296 + cp = cpv_getkey(remove_slot(pkg))
4297 + useforce = []
4298 + pos = 0
4299 + for i, puseforce_dict in enumerate(self.puseforce_list):
4300 + cpdict = puseforce_dict.get(cp)
4301 + if cpdict:
4302 + keys = list(cpdict)
4303 + while keys:
4304 + best_match = best_match_to_list(pkg, keys)
4305 + if best_match:
4306 + keys.remove(best_match)
4307 + useforce.insert(pos, cpdict[best_match])
4308 + else:
4309 + break
4310 + del keys
4311 + if self.useforce_list[i]:
4312 + useforce.insert(pos, self.useforce_list[i])
4313 + pos = len(useforce)
4314 + return set(stack_lists(useforce, incremental=True))
4315 +
4316 + def _getMaskAtom(self, cpv, metadata):
4317 + """
4318 + Take a package and return a matching package.mask atom, or None if no
4319 + such atom exists or it has been cancelled by package.unmask. PROVIDE
4320 + is not checked, so atoms will not be found for old-style virtuals.
4321 +
4322 + @param cpv: The package name
4323 + @type cpv: String
4324 + @param metadata: A dictionary of raw package metadata
4325 + @type metadata: dict
4326 + @rtype: String
4327 + @return: An matching atom string or None if one is not found.
4328 + """
4329 +
4330 + cp = cpv_getkey(cpv)
4331 + mask_atoms = self.pmaskdict.get(cp)
4332 + if mask_atoms:
4333 + pkg_list = ["%s:%s" % (cpv, metadata["SLOT"])]
4334 + unmask_atoms = self.punmaskdict.get(cp)
4335 + for x in mask_atoms:
4336 + if not match_from_list(x, pkg_list):
4337 + continue
4338 + if unmask_atoms:
4339 + for y in unmask_atoms:
4340 + if match_from_list(y, pkg_list):
4341 + return None
4342 + return x
4343 + return None
4344 +
4345 + def _getProfileMaskAtom(self, cpv, metadata):
4346 + """
4347 + Take a package and return a matching profile atom, or None if no
4348 + such atom exists. Note that a profile atom may or may not have a "*"
4349 + prefix. PROVIDE is not checked, so atoms will not be found for
4350 + old-style virtuals.
4351 +
4352 + @param cpv: The package name
4353 + @type cpv: String
4354 + @param metadata: A dictionary of raw package metadata
4355 + @type metadata: dict
4356 + @rtype: String
4357 + @return: An matching profile atom string or None if one is not found.
4358 + """
4359 +
4360 + cp = cpv_getkey(cpv)
4361 + profile_atoms = self.prevmaskdict.get(cp)
4362 + if profile_atoms:
4363 + pkg_list = ["%s:%s" % (cpv, metadata["SLOT"])]
4364 + for x in profile_atoms:
4365 + if match_from_list(x, pkg_list):
4366 + continue
4367 + return x
4368 + return None
4369 +
4370 + def _getKeywords(self, cpv, metadata):
4371 + cp = cpv_getkey(cpv)
4372 + pkg = "%s:%s" % (cpv, metadata["SLOT"])
4373 + keywords = [[x for x in metadata["KEYWORDS"].split() if x != "-*"]]
4374 + pos = len(keywords)
4375 + for pkeywords_dict in self._pkeywords_list:
4376 + cpdict = pkeywords_dict.get(cp)
4377 + if cpdict:
4378 + keys = list(cpdict)
4379 + while keys:
4380 + best_match = best_match_to_list(pkg, keys)
4381 + if best_match:
4382 + keys.remove(best_match)
4383 + keywords.insert(pos, cpdict[best_match])
4384 + else:
4385 + break
4386 + pos = len(keywords)
4387 + return stack_lists(keywords, incremental=True)
4388 +
4389 + def _getMissingKeywords(self, cpv, metadata):
4390 + """
4391 + Take a package and return a list of any KEYWORDS that the user may
4392 + may need to accept for the given package. If the KEYWORDS are empty
4393 + and the the ** keyword has not been accepted, the returned list will
4394 + contain ** alone (in order to distiguish from the case of "none
4395 + missing").
4396 +
4397 + @param cpv: The package name (for package.keywords support)
4398 + @type cpv: String
4399 + @param metadata: A dictionary of raw package metadata
4400 + @type metadata: dict
4401 + @rtype: List
4402 + @return: A list of KEYWORDS that have not been accepted.
4403 + """
4404 +
4405 + # Hack: Need to check the env directly here as otherwise stacking
4406 + # doesn't work properly as negative values are lost in the config
4407 + # object (bug #139600)
4408 + egroups = self.configdict["backupenv"].get(
4409 + "ACCEPT_KEYWORDS", "").split()
4410 + mygroups = self._getKeywords(cpv, metadata)
4411 + # Repoman may modify this attribute as necessary.
4412 + pgroups = self["ACCEPT_KEYWORDS"].split()
4413 + match=0
4414 + cp = cpv_getkey(cpv)
4415 + pkgdict = self.pkeywordsdict.get(cp)
4416 + matches = False
4417 + if pkgdict:
4418 + cpv_slot_list = ["%s:%s" % (cpv, metadata["SLOT"])]
4419 + for atom, pkgkeywords in pkgdict.items():
4420 + if match_from_list(atom, cpv_slot_list):
4421 + matches = True
4422 + pgroups.extend(pkgkeywords)
4423 + if matches or egroups:
4424 + pgroups.extend(egroups)
4425 + inc_pgroups = set()
4426 + for x in pgroups:
4427 + if x.startswith("-"):
4428 + if x == "-*":
4429 + inc_pgroups.clear()
4430 + else:
4431 + inc_pgroups.discard(x[1:])
4432 + else:
4433 + inc_pgroups.add(x)
4434 + pgroups = inc_pgroups
4435 + del inc_pgroups
4436 + hasstable = False
4437 + hastesting = False
4438 + for gp in mygroups:
4439 + if gp == "*" or (gp == "-*" and len(mygroups) == 1):
4440 + writemsg(_("--- WARNING: Package '%(cpv)s' uses"
4441 + " '%(keyword)s' keyword.\n") % {"cpv": cpv, "keyword": gp}, noiselevel=-1)
4442 + if gp == "*":
4443 + match = 1
4444 + break
4445 + elif gp in pgroups:
4446 + match=1
4447 + break
4448 + elif gp.startswith("~"):
4449 + hastesting = True
4450 + elif not gp.startswith("-"):
4451 + hasstable = True
4452 + if not match and \
4453 + ((hastesting and "~*" in pgroups) or \
4454 + (hasstable and "*" in pgroups) or "**" in pgroups):
4455 + match=1
4456 + if match:
4457 + missing = []
4458 + else:
4459 + if not mygroups:
4460 + # If KEYWORDS is empty then we still have to return something
4461 + # in order to distiguish from the case of "none missing".
4462 + mygroups.append("**")
4463 + missing = mygroups
4464 + return missing
4465 +
4466 + def _getMissingLicenses(self, cpv, metadata):
4467 + """
4468 + Take a LICENSE string and return a list any licenses that the user may
4469 + may need to accept for the given package. The returned list will not
4470 + contain any licenses that have already been accepted. This method
4471 + can throw an InvalidDependString exception.
4472 +
4473 + @param cpv: The package name (for package.license support)
4474 + @type cpv: String
4475 + @param metadata: A dictionary of raw package metadata
4476 + @type metadata: dict
4477 + @rtype: List
4478 + @return: A list of licenses that have not been accepted.
4479 + """
4480 + accept_license = self._accept_license
4481 + cpdict = self._plicensedict.get(cpv_getkey(cpv), None)
4482 + if cpdict:
4483 + accept_license = list(self._accept_license)
4484 + cpv_slot = "%s:%s" % (cpv, metadata["SLOT"])
4485 + for atom in match_to_list(cpv_slot, list(cpdict)):
4486 + accept_license.extend(cpdict[atom])
4487 +
4488 + licenses = set(flatten(use_reduce(paren_reduce(
4489 + metadata["LICENSE"]), matchall=1)))
4490 + licenses.discard('||')
4491 +
4492 + acceptable_licenses = set()
4493 + for x in accept_license:
4494 + if x == '*':
4495 + acceptable_licenses.update(licenses)
4496 + elif x == '-*':
4497 + acceptable_licenses.clear()
4498 + elif x[:1] == '-':
4499 + acceptable_licenses.discard(x[1:])
4500 + else:
4501 + acceptable_licenses.add(x)
4502 +
4503 + license_str = metadata["LICENSE"]
4504 + if "?" in license_str:
4505 + use = metadata["USE"].split()
4506 + else:
4507 + use = []
4508 +
4509 + license_struct = use_reduce(
4510 + paren_reduce(license_str), uselist=use)
4511 + license_struct = dep_opconvert(license_struct)
4512 + return self._getMaskedLicenses(license_struct, acceptable_licenses)
4513 +
4514 + def _getMaskedLicenses(self, license_struct, acceptable_licenses):
4515 + if not license_struct:
4516 + return []
4517 + if license_struct[0] == "||":
4518 + ret = []
4519 + for element in license_struct[1:]:
4520 + if isinstance(element, list):
4521 + if element:
4522 + ret.append(self._getMaskedLicenses(
4523 + element, acceptable_licenses))
4524 + if not ret[-1]:
4525 + return []
4526 + else:
4527 + if element in acceptable_licenses:
4528 + return []
4529 + ret.append(element)
4530 + # Return all masked licenses, since we don't know which combination
4531 + # (if any) the user will decide to unmask.
4532 + return flatten(ret)
4533 +
4534 + ret = []
4535 + for element in license_struct:
4536 + if isinstance(element, list):
4537 + if element:
4538 + ret.extend(self._getMaskedLicenses(element,
4539 + acceptable_licenses))
4540 + else:
4541 + if element not in acceptable_licenses:
4542 + ret.append(element)
4543 + return ret
4544 +
4545 + def _getMissingProperties(self, cpv, metadata):
4546 + """
4547 + Take a PROPERTIES string and return a list of any properties the user may
4548 + may need to accept for the given package. The returned list will not
4549 + contain any properties that have already been accepted. This method
4550 + can throw an InvalidDependString exception.
4551 +
4552 + @param cpv: The package name (for package.properties support)
4553 + @type cpv: String
4554 + @param metadata: A dictionary of raw package metadata
4555 + @type metadata: dict
4556 + @rtype: List
4557 + @return: A list of properties that have not been accepted.
4558 + """
4559 + accept_properties = self._accept_properties
4560 + cpdict = self._ppropertiesdict.get(cpv_getkey(cpv), None)
4561 + if cpdict:
4562 + accept_properties = list(self._accept_properties)
4563 + cpv_slot = "%s:%s" % (cpv, metadata["SLOT"])
4564 + for atom in match_to_list(cpv_slot, list(cpdict)):
4565 + accept_properties.extend(cpdict[atom])
4566 +
4567 + properties = set(flatten(use_reduce(paren_reduce(
4568 + metadata["PROPERTIES"]), matchall=1)))
4569 + properties.discard('||')
4570 +
4571 + acceptable_properties = set()
4572 + for x in accept_properties:
4573 + if x == '*':
4574 + acceptable_properties.update(properties)
4575 + elif x == '-*':
4576 + acceptable_properties.clear()
4577 + elif x[:1] == '-':
4578 + acceptable_properties.discard(x[1:])
4579 + else:
4580 + acceptable_properties.add(x)
4581 +
4582 + properties_str = metadata["PROPERTIES"]
4583 + if "?" in properties_str:
4584 + use = metadata["USE"].split()
4585 + else:
4586 + use = []
4587 +
4588 + properties_struct = use_reduce(
4589 + paren_reduce(properties_str), uselist=use)
4590 + properties_struct = dep_opconvert(properties_struct)
4591 + return self._getMaskedProperties(properties_struct, acceptable_properties)
4592 +
4593 + def _getMaskedProperties(self, properties_struct, acceptable_properties):
4594 + if not properties_struct:
4595 + return []
4596 + if properties_struct[0] == "||":
4597 + ret = []
4598 + for element in properties_struct[1:]:
4599 + if isinstance(element, list):
4600 + if element:
4601 + ret.append(self._getMaskedProperties(
4602 + element, acceptable_properties))
4603 + if not ret[-1]:
4604 + return []
4605 + else:
4606 + if element in acceptable_properties:
4607 + return[]
4608 + ret.append(element)
4609 + # Return all masked properties, since we don't know which combination
4610 + # (if any) the user will decide to unmask
4611 + return flatten(ret)
4612 +
4613 + ret = []
4614 + for element in properties_struct:
4615 + if isinstance(element, list):
4616 + if element:
4617 + ret.extend(self._getMaskedProperties(element,
4618 + acceptable_properties))
4619 + else:
4620 + if element not in acceptable_properties:
4621 + ret.append(element)
4622 + return ret
4623 +
4624 + def _accept_chost(self, cpv, metadata):
4625 + """
4626 + @return True if pkg CHOST is accepted, False otherwise.
4627 + """
4628 + if self._accept_chost_re is None:
4629 + accept_chost = self.get("ACCEPT_CHOSTS", "").split()
4630 + if not accept_chost:
4631 + chost = self.get("CHOST")
4632 + if chost:
4633 + accept_chost.append(chost)
4634 + if not accept_chost:
4635 + self._accept_chost_re = re.compile(".*")
4636 + elif len(accept_chost) == 1:
4637 + try:
4638 + self._accept_chost_re = re.compile(r'^%s$' % accept_chost[0])
4639 + except re.error as e:
4640 + writemsg(_("!!! Invalid ACCEPT_CHOSTS value: '%s': %s\n") % \
4641 + (accept_chost[0], e), noiselevel=-1)
4642 + self._accept_chost_re = re.compile("^$")
4643 + else:
4644 + try:
4645 + self._accept_chost_re = re.compile(
4646 + r'^(%s)$' % "|".join(accept_chost))
4647 + except re.error as e:
4648 + writemsg(_("!!! Invalid ACCEPT_CHOSTS value: '%s': %s\n") % \
4649 + (" ".join(accept_chost), e), noiselevel=-1)
4650 + self._accept_chost_re = re.compile("^$")
4651 +
4652 + pkg_chost = metadata.get('CHOST', '')
4653 + return not pkg_chost or \
4654 + self._accept_chost_re.match(pkg_chost) is not None
4655 +
4656 + def setinst(self,mycpv,mydbapi):
4657 + """This updates the preferences for old-style virtuals,
4658 + affecting the behavior of dep_expand() and dep_check()
4659 + calls. It can change dbapi.match() behavior since that
4660 + calls dep_expand(). However, dbapi instances have
4661 + internal match caches that are not invalidated when
4662 + preferences are updated here. This can potentially
4663 + lead to some inconsistency (relevant to bug #1343)."""
4664 + self.modifying()
4665 + if len(self.virtuals) == 0:
4666 + self.getvirtuals()
4667 + # Grab the virtuals this package provides and add them into the tree virtuals.
4668 + if not hasattr(mydbapi, "aux_get"):
4669 + provides = mydbapi["PROVIDE"]
4670 + else:
4671 + provides = mydbapi.aux_get(mycpv, ["PROVIDE"])[0]
4672 + if not provides:
4673 + return
4674 + if isinstance(mydbapi, portdbapi):
4675 + self.setcpv(mycpv, mydb=mydbapi)
4676 + myuse = self["PORTAGE_USE"]
4677 + elif not hasattr(mydbapi, "aux_get"):
4678 + myuse = mydbapi["USE"]
4679 + else:
4680 + myuse = mydbapi.aux_get(mycpv, ["USE"])[0]
4681 + virts = flatten(use_reduce(paren_reduce(provides), uselist=myuse.split()))
4682 +
4683 + modified = False
4684 + cp = Atom(cpv_getkey(mycpv))
4685 + for virt in virts:
4686 + try:
4687 + virt = Atom(virt).cp
4688 + except InvalidAtom:
4689 + continue
4690 + providers = self.virtuals.get(virt)
4691 + if providers and cp in providers:
4692 + continue
4693 + providers = self._depgraphVirtuals.get(virt)
4694 + if providers is None:
4695 + providers = []
4696 + self._depgraphVirtuals[virt] = providers
4697 + if cp not in providers:
4698 + providers.append(cp)
4699 + modified = True
4700 +
4701 + if modified:
4702 + self.virtuals = self.__getvirtuals_compile()
4703 +
4704 + def reload(self):
4705 + """Reload things like /etc/profile.env that can change during runtime."""
4706 + env_d_filename = os.path.join(self["ROOT"], "etc", "profile.env")
4707 + self.configdict["env.d"].clear()
4708 + env_d = getconfig(env_d_filename, expand=False)
4709 + if env_d:
4710 + # env_d will be None if profile.env doesn't exist.
4711 + self.configdict["env.d"].update(env_d)
4712 +
4713 + def _prune_incremental(self, split):
4714 + """
4715 + Prune off any parts of an incremental variable that are
4716 + made irrelevant by the latest occuring * or -*. This
4717 + could be more aggressive but that might be confusing
4718 + and the point is just to reduce noise a bit.
4719 + """
4720 + for i, x in enumerate(reversed(split)):
4721 + if x == '*':
4722 + split = split[-i-1:]
4723 + break
4724 + elif x == '-*':
4725 + if i == 0:
4726 + split = []
4727 + else:
4728 + split = split[-i:]
4729 + break
4730 + return split
4731 +
4732 + def regenerate(self,useonly=0,use_cache=1):
4733 + """
4734 + Regenerate settings
4735 + This involves regenerating valid USE flags, re-expanding USE_EXPAND flags
4736 + re-stacking USE flags (-flag and -*), as well as any other INCREMENTAL
4737 + variables. This also updates the env.d configdict; useful in case an ebuild
4738 + changes the environment.
4739 +
4740 + If FEATURES has already stacked, it is not stacked twice.
4741 +
4742 + @param useonly: Only regenerate USE flags (not any other incrementals)
4743 + @type useonly: Boolean
4744 + @param use_cache: Enable Caching (only for autouse)
4745 + @type use_cache: Boolean
4746 + @rtype: None
4747 + """
4748 +
4749 + self.modifying()
4750 + if self.already_in_regenerate:
4751 + # XXX: THIS REALLY NEEDS TO GET FIXED. autouse() loops.
4752 + writemsg("!!! Looping in regenerate.\n",1)
4753 + return
4754 + else:
4755 + self.already_in_regenerate = 1
4756 +
4757 + if useonly:
4758 + myincrementals=["USE"]
4759 + else:
4760 + myincrementals = self.incrementals
4761 + myincrementals = set(myincrementals)
4762 + # If self.features exists, it has already been stacked and may have
4763 + # been mutated, so don't stack it again or else any mutations will be
4764 + # reverted.
4765 + if "FEATURES" in myincrementals and hasattr(self, "features"):
4766 + myincrementals.remove("FEATURES")
4767 +
4768 + if "USE" in myincrementals:
4769 + # Process USE last because it depends on USE_EXPAND which is also
4770 + # an incremental!
4771 + myincrementals.remove("USE")
4772 +
4773 + mydbs = self.configlist[:-1]
4774 + mydbs.append(self.backupenv)
4775 +
4776 + # ACCEPT_LICENSE is a lazily evaluated incremental, so that * can be
4777 + # used to match all licenses without every having to explicitly expand
4778 + # it to all licenses.
4779 + if self.local_config:
4780 + mysplit = []
4781 + for curdb in mydbs:
4782 + mysplit.extend(curdb.get('ACCEPT_LICENSE', '').split())
4783 + mysplit = self._prune_incremental(mysplit)
4784 + accept_license_str = ' '.join(mysplit)
4785 + self.configlist[-1]['ACCEPT_LICENSE'] = accept_license_str
4786 + if accept_license_str != self._accept_license_str:
4787 + self._accept_license_str = accept_license_str
4788 + self._accept_license = tuple(self.expandLicenseTokens(mysplit))
4789 + else:
4790 + # repoman will accept any license
4791 + self._accept_license = ('*',)
4792 +
4793 + # ACCEPT_PROPERTIES works like ACCEPT_LICENSE, without groups
4794 + if self.local_config:
4795 + mysplit = []
4796 + for curdb in mydbs:
4797 + mysplit.extend(curdb.get('ACCEPT_PROPERTIES', '').split())
4798 + mysplit = self._prune_incremental(mysplit)
4799 + self.configlist[-1]['ACCEPT_PROPERTIES'] = ' '.join(mysplit)
4800 + if tuple(mysplit) != self._accept_properties:
4801 + self._accept_properties = tuple(mysplit)
4802 + else:
4803 + # repoman will accept any property
4804 + self._accept_properties = ('*',)
4805 +
4806 + for mykey in myincrementals:
4807 +
4808 + myflags=[]
4809 + for curdb in mydbs:
4810 + if mykey not in curdb:
4811 + continue
4812 + #variables are already expanded
4813 + mysplit = curdb[mykey].split()
4814 +
4815 + for x in mysplit:
4816 + if x=="-*":
4817 + # "-*" is a special "minus" var that means "unset all settings".
4818 + # so USE="-* gnome" will have *just* gnome enabled.
4819 + myflags = []
4820 + continue
4821 +
4822 + if x[0]=="+":
4823 + # Not legal. People assume too much. Complain.
4824 + writemsg(colorize("BAD",
4825 + _("USE flags should not start with a '+': %s") % x) \
4826 + + "\n", noiselevel=-1)
4827 + x=x[1:]
4828 + if not x:
4829 + continue
4830 +
4831 + if (x[0]=="-"):
4832 + if (x[1:] in myflags):
4833 + # Unset/Remove it.
4834 + del myflags[myflags.index(x[1:])]
4835 + continue
4836 +
4837 + # We got here, so add it now.
4838 + if x not in myflags:
4839 + myflags.append(x)
4840 +
4841 + myflags.sort()
4842 + #store setting in last element of configlist, the original environment:
4843 + if myflags or mykey in self:
4844 + self.configlist[-1][mykey] = " ".join(myflags)
4845 + del myflags
4846 +
4847 + # Do the USE calculation last because it depends on USE_EXPAND.
4848 + if "auto" in self["USE_ORDER"].split(":"):
4849 + self.configdict["auto"]["USE"] = autouse(
4850 + vartree(root=self["ROOT"], categories=self.categories,
4851 + settings=self),
4852 + use_cache=use_cache, mysettings=self)
4853 + else:
4854 + self.configdict["auto"]["USE"] = ""
4855 +
4856 + use_expand = self.get("USE_EXPAND", "").split()
4857 + use_expand_dict = self._use_expand_dict
4858 + use_expand_dict.clear()
4859 + for k in use_expand:
4860 + v = self.get(k)
4861 + if v is not None:
4862 + use_expand_dict[k] = v
4863 +
4864 + if not self.uvlist:
4865 + for x in self["USE_ORDER"].split(":"):
4866 + if x in self.configdict:
4867 + self.uvlist.append(self.configdict[x])
4868 + self.uvlist.reverse()
4869 +
4870 + # For optimal performance, use slice
4871 + # comparison instead of startswith().
4872 + myflags = set()
4873 + for curdb in self.uvlist:
4874 + cur_use_expand = [x for x in use_expand if x in curdb]
4875 + mysplit = curdb.get("USE", "").split()
4876 + if not mysplit and not cur_use_expand:
4877 + continue
4878 + for x in mysplit:
4879 + if x == "-*":
4880 + myflags.clear()
4881 + continue
4882 +
4883 + if x[0] == "+":
4884 + writemsg(colorize("BAD", _("USE flags should not start "
4885 + "with a '+': %s\n") % x), noiselevel=-1)
4886 + x = x[1:]
4887 + if not x:
4888 + continue
4889 +
4890 + if x[0] == "-":
4891 + myflags.discard(x[1:])
4892 + continue
4893 +
4894 + myflags.add(x)
4895 +
4896 + for var in cur_use_expand:
4897 + var_lower = var.lower()
4898 + is_not_incremental = var not in myincrementals
4899 + if is_not_incremental:
4900 + prefix = var_lower + "_"
4901 + prefix_len = len(prefix)
4902 + for x in list(myflags):
4903 + if x[:prefix_len] == prefix:
4904 + myflags.remove(x)
4905 + for x in curdb[var].split():
4906 + if x[0] == "+":
4907 + if is_not_incremental:
4908 + writemsg(colorize("BAD", _("Invalid '+' "
4909 + "operator in non-incremental variable "
4910 + "'%s': '%s'\n") % (var, x)), noiselevel=-1)
4911 + continue
4912 + else:
4913 + writemsg(colorize("BAD", _("Invalid '+' "
4914 + "operator in incremental variable "
4915 + "'%s': '%s'\n") % (var, x)), noiselevel=-1)
4916 + x = x[1:]
4917 + if x[0] == "-":
4918 + if is_not_incremental:
4919 + writemsg(colorize("BAD", _("Invalid '-' "
4920 + "operator in non-incremental variable "
4921 + "'%s': '%s'\n") % (var, x)), noiselevel=-1)
4922 + continue
4923 + myflags.discard(var_lower + "_" + x[1:])
4924 + continue
4925 + myflags.add(var_lower + "_" + x)
4926 +
4927 + if hasattr(self, "features"):
4928 + self.features.clear()
4929 + else:
4930 + self.features = set()
4931 + self.features.update(self.configlist[-1].get('FEATURES', '').split())
4932 + self['FEATURES'] = ' '.join(sorted(self.features))
4933 +
4934 + myflags.update(self.useforce)
4935 + arch = self.configdict["defaults"].get("ARCH")
4936 + if arch:
4937 + myflags.add(arch)
4938 +
4939 + myflags.difference_update(self.usemask)
4940 + self.configlist[-1]["USE"]= " ".join(sorted(myflags))
4941 +
4942 + self.already_in_regenerate = 0
4943 +
4944 + def get_virts_p(self, myroot=None):
4945 +
4946 + if myroot is not None:
4947 + warnings.warn("The 'myroot' parameter for " + \
4948 + "portage.config.get_virts_p() is deprecated",
4949 + DeprecationWarning, stacklevel=2)
4950 +
4951 + if self.virts_p:
4952 + return self.virts_p
4953 + virts = self.getvirtuals()
4954 + if virts:
4955 + for x in virts:
4956 + vkeysplit = x.split("/")
4957 + if vkeysplit[1] not in self.virts_p:
4958 + self.virts_p[vkeysplit[1]] = virts[x]
4959 + return self.virts_p
4960 +
4961 + def getvirtuals(self, myroot=None):
4962 + """myroot is now ignored because, due to caching, it has always been
4963 + broken for all but the first call."""
4964 +
4965 + if myroot is not None:
4966 + warnings.warn("The 'myroot' parameter for " + \
4967 + "portage.config.getvirtuals() is deprecated",
4968 + DeprecationWarning, stacklevel=2)
4969 +
4970 + myroot = self["ROOT"]
4971 + if self.virtuals:
4972 + return self.virtuals
4973 +
4974 + virtuals_list = []
4975 + for x in self.profiles:
4976 + virtuals_file = os.path.join(x, "virtuals")
4977 + virtuals_dict = grabdict(virtuals_file)
4978 + atoms_dict = {}
4979 + for k, v in virtuals_dict.items():
4980 + try:
4981 + virt_atom = Atom(k)
4982 + except InvalidAtom:
4983 + virt_atom = None
4984 + else:
4985 + if virt_atom.blocker or \
4986 + str(virt_atom) != str(virt_atom.cp):
4987 + virt_atom = None
4988 + if virt_atom is None:
4989 + writemsg(_("--- Invalid virtuals atom in %s: %s\n") % \
4990 + (virtuals_file, k), noiselevel=-1)
4991 + continue
4992 + providers = []
4993 + for atom in v:
4994 + atom_orig = atom
4995 + if atom[:1] == '-':
4996 + # allow incrementals
4997 + atom = atom[1:]
4998 + try:
4999 + atom = Atom(atom)
5000 + except InvalidAtom:
5001 + atom = None
5002 + else:
5003 + if atom.blocker:
5004 + atom = None
5005 + if atom is None:
5006 + writemsg(_("--- Invalid atom in %s: %s\n") % \
5007 + (virtuals_file, atom_orig), noiselevel=-1)
5008 + else:
5009 + if atom_orig == str(atom):
5010 + # normal atom, so return as Atom instance
5011 + providers.append(atom)
5012 + else:
5013 + # atom has special prefix, so return as string
5014 + providers.append(atom_orig)
5015 + if providers:
5016 + atoms_dict[virt_atom] = providers
5017 + if atoms_dict:
5018 + virtuals_list.append(atoms_dict)
5019 +
5020 + self.dirVirtuals = stack_dictlist(virtuals_list, incremental=True)
5021 + del virtuals_list
5022 +
5023 + for virt in self.dirVirtuals:
5024 + # Preference for virtuals decreases from left to right.
5025 + self.dirVirtuals[virt].reverse()
5026 +
5027 + # Repoman does not use user or tree virtuals.
5028 + if self.local_config and not self.treeVirtuals:
5029 + temp_vartree = vartree(myroot, None,
5030 + categories=self.categories, settings=self)
5031 + self._populate_treeVirtuals(temp_vartree)
5032 +
5033 + self.virtuals = self.__getvirtuals_compile()
5034 + return self.virtuals
5035 +
5036 + def _populate_treeVirtuals(self, vartree):
5037 + """Reduce the provides into a list by CP."""
5038 + for provide, cpv_list in vartree.get_all_provides().items():
5039 + try:
5040 + provide = Atom(provide)
5041 + except InvalidAtom:
5042 + continue
5043 + self.treeVirtuals[provide.cp] = \
5044 + [Atom(cpv_getkey(cpv)) for cpv in cpv_list]
5045 +
5046 + def __getvirtuals_compile(self):
5047 + """Stack installed and profile virtuals. Preference for virtuals
5048 + decreases from left to right.
5049 + Order of preference:
5050 + 1. installed and in profile
5051 + 2. installed only
5052 + 3. profile only
5053 + """
5054 +
5055 + # Virtuals by profile+tree preferences.
5056 + ptVirtuals = {}
5057 +
5058 + for virt, installed_list in self.treeVirtuals.items():
5059 + profile_list = self.dirVirtuals.get(virt, None)
5060 + if not profile_list:
5061 + continue
5062 + for cp in installed_list:
5063 + if cp in profile_list:
5064 + ptVirtuals.setdefault(virt, [])
5065 + ptVirtuals[virt].append(cp)
5066 +
5067 + virtuals = stack_dictlist([ptVirtuals, self.treeVirtuals,
5068 + self.dirVirtuals, self._depgraphVirtuals])
5069 + return virtuals
5070 +
5071 + def __delitem__(self,mykey):
5072 + self.modifying()
5073 + for x in self.lookuplist:
5074 + if x != None:
5075 + if mykey in x:
5076 + del x[mykey]
5077 +
5078 + def __getitem__(self,mykey):
5079 + for d in self.lookuplist:
5080 + if mykey in d:
5081 + return d[mykey]
5082 + return '' # for backward compat, don't raise KeyError
5083 +
5084 + def get(self, k, x=None):
5085 + for d in self.lookuplist:
5086 + if k in d:
5087 + return d[k]
5088 + return x
5089 +
5090 + def pop(self, key, *args):
5091 + if len(args) > 1:
5092 + raise TypeError(
5093 + "pop expected at most 2 arguments, got " + \
5094 + repr(1 + len(args)))
5095 + v = self
5096 + for d in reversed(self.lookuplist):
5097 + v = d.pop(key, v)
5098 + if v is self:
5099 + if args:
5100 + return args[0]
5101 + raise KeyError(key)
5102 + return v
5103 +
5104 + def has_key(self,mykey):
5105 + warnings.warn("portage.config.has_key() is deprecated, "
5106 + "use the in operator instead",
5107 + DeprecationWarning, stacklevel=2)
5108 + return mykey in self
5109 +
5110 + def __contains__(self, mykey):
5111 + """Called to implement membership test operators (in and not in)."""
5112 + for d in self.lookuplist:
5113 + if mykey in d:
5114 + return True
5115 + return False
5116 +
5117 + def setdefault(self, k, x=None):
5118 + v = self.get(k)
5119 + if v is not None:
5120 + return v
5121 + else:
5122 + self[k] = x
5123 + return x
5124 +
5125 + def keys(self):
5126 + return list(self)
5127 +
5128 + def __iter__(self):
5129 + keys = set()
5130 + for d in self.lookuplist:
5131 + keys.update(d)
5132 + return iter(keys)
5133 +
5134 + def iterkeys(self):
5135 + return iter(self)
5136 +
5137 + def iteritems(self):
5138 + for k in self:
5139 + yield (k, self[k])
5140 +
5141 + def items(self):
5142 + return list(self.iteritems())
5143 +
5144 + def __setitem__(self,mykey,myvalue):
5145 + "set a value; will be thrown away at reset() time"
5146 + if not isinstance(myvalue, basestring):
5147 + raise ValueError("Invalid type being used as a value: '%s': '%s'" % (str(mykey),str(myvalue)))
5148 +
5149 + # Avoid potential UnicodeDecodeError exceptions later.
5150 + mykey = _unicode_decode(mykey)
5151 + myvalue = _unicode_decode(myvalue)
5152 +
5153 + self.modifying()
5154 + self.modifiedkeys.append(mykey)
5155 + self.configdict["env"][mykey]=myvalue
5156 +
5157 + def environ(self):
5158 + "return our locally-maintained environment"
5159 + mydict={}
5160 + environ_filter = self._environ_filter
5161 +
5162 + eapi = self.get('EAPI')
5163 + phase = self.get('EBUILD_PHASE')
5164 + filter_calling_env = False
5165 + if phase not in ('clean', 'cleanrm', 'depend'):
5166 + temp_dir = self.get('T')
5167 + if temp_dir is not None and \
5168 + os.path.exists(os.path.join(temp_dir, 'environment')):
5169 + filter_calling_env = True
5170 +
5171 + environ_whitelist = self._environ_whitelist
5172 + for x in self:
5173 + if x in environ_filter:
5174 + continue
5175 + myvalue = self[x]
5176 + if not isinstance(myvalue, basestring):
5177 + writemsg(_("!!! Non-string value in config: %s=%s\n") % \
5178 + (x, myvalue), noiselevel=-1)
5179 + continue
5180 + if filter_calling_env and \
5181 + x not in environ_whitelist and \
5182 + not self._environ_whitelist_re.match(x):
5183 + # Do not allow anything to leak into the ebuild
5184 + # environment unless it is explicitly whitelisted.
5185 + # This ensures that variables unset by the ebuild
5186 + # remain unset.
5187 + continue
5188 + mydict[x] = myvalue
5189 + if "HOME" not in mydict and "BUILD_PREFIX" in mydict:
5190 + writemsg("*** HOME not set. Setting to "+mydict["BUILD_PREFIX"]+"\n")
5191 + mydict["HOME"]=mydict["BUILD_PREFIX"][:]
5192 +
5193 + if filter_calling_env:
5194 + if phase:
5195 + whitelist = []
5196 + if "rpm" == phase:
5197 + whitelist.append("RPMDIR")
5198 + for k in whitelist:
5199 + v = self.get(k)
5200 + if v is not None:
5201 + mydict[k] = v
5202 +
5203 + # Filtered by IUSE and implicit IUSE.
5204 + mydict["USE"] = self.get("PORTAGE_USE", "")
5205 +
5206 + # Don't export AA to the ebuild environment in EAPIs that forbid it
5207 + if eapi not in ("0", "1", "2", "3", "3_pre2"):
5208 + mydict.pop("AA", None)
5209 +
5210 + # Prefix variables are supported starting with EAPI 3.
5211 + if phase == 'depend' or eapi in (None, "0", "1", "2"):
5212 + mydict.pop("ED", None)
5213 + mydict.pop("EPREFIX", None)
5214 + mydict.pop("EROOT", None)
5215 +
5216 + if phase == 'depend':
5217 + mydict.pop('FILESDIR', None)
5218 +
5219 + return mydict
5220 +
5221 + def thirdpartymirrors(self):
5222 + if getattr(self, "_thirdpartymirrors", None) is None:
5223 + profileroots = [os.path.join(self["PORTDIR"], "profiles")]
5224 + for x in self["PORTDIR_OVERLAY"].split():
5225 + profileroots.insert(0, os.path.join(x, "profiles"))
5226 + thirdparty_lists = [grabdict(os.path.join(x, "thirdpartymirrors")) for x in profileroots]
5227 + self._thirdpartymirrors = stack_dictlist(thirdparty_lists, incremental=True)
5228 + return self._thirdpartymirrors
5229 +
5230 + def archlist(self):
5231 + return flatten([[myarch, "~" + myarch] \
5232 + for myarch in self["PORTAGE_ARCHLIST"].split()])
5233 +
5234 + def selinux_enabled(self):
5235 + if getattr(self, "_selinux_enabled", None) is None:
5236 + self._selinux_enabled = 0
5237 + if "selinux" in self["USE"].split():
5238 + if selinux:
5239 + if selinux.is_selinux_enabled() == 1:
5240 + self._selinux_enabled = 1
5241 + else:
5242 + self._selinux_enabled = 0
5243 + else:
5244 + writemsg(_("!!! SELinux module not found. Please verify that it was installed.\n"),
5245 + noiselevel=-1)
5246 + self._selinux_enabled = 0
5247 +
5248 + return self._selinux_enabled
5249 +
5250 + if sys.hexversion >= 0x3000000:
5251 + keys = __iter__
5252 + items = iteritems
5253
5254
5255 Property changes on: main/trunk/pym/portage/package/ebuild/config.py
5256 ___________________________________________________________________
5257 Added: svn:keywords
5258 + Id