Package portage
[hide private]

Source Code for Package portage

  1  # Copyright 1998-2014 Gentoo Foundation 
  2  # Distributed under the terms of the GNU General Public License v2 
  3   
  4  from __future__ import unicode_literals 
  5   
  6  VERSION = "HEAD" 
  7   
  8  # =========================================================================== 
  9  # START OF IMPORTS -- START OF IMPORTS -- START OF IMPORTS -- START OF IMPORT 
 10  # =========================================================================== 
 11   
 12  try: 
 13          import sys 
 14          import errno 
 15          if not hasattr(errno, 'ESTALE'): 
 16                  # ESTALE may not be defined on some systems, such as interix. 
 17                  errno.ESTALE = -1 
 18          import re 
 19          import types 
 20          import platform 
 21   
 22          # Temporarily delete these imports, to ensure that only the 
 23          # wrapped versions are imported by portage internals. 
 24          import os 
 25          del os 
 26          import shutil 
 27          del shutil 
 28   
 29  except ImportError as e: 
 30          sys.stderr.write("\n\n") 
 31          sys.stderr.write("!!! Failed to complete python imports. These are internal modules for\n") 
 32          sys.stderr.write("!!! python and failure here indicates that you have a problem with python\n") 
 33          sys.stderr.write("!!! itself and thus portage is not able to continue processing.\n\n") 
 34   
 35          sys.stderr.write("!!! You might consider starting python with verbose flags to see what has\n") 
 36          sys.stderr.write("!!! gone wrong. Here is the information we got for this exception:\n") 
 37          sys.stderr.write("    "+str(e)+"\n\n") 
 38          raise 
 39   
 40  try: 
 41   
 42          import portage.proxy.lazyimport 
 43          import portage.proxy as proxy 
 44          proxy.lazyimport.lazyimport(globals(), 
 45                  'portage.cache.cache_errors:CacheError', 
 46                  'portage.checksum', 
 47                  'portage.checksum:perform_checksum,perform_md5,prelink_capable', 
 48                  'portage.cvstree', 
 49                  'portage.data', 
 50                  'portage.data:lchown,ostype,portage_gid,portage_uid,secpass,' + \ 
 51                          'uid,userland,userpriv_groups,wheelgid', 
 52                  'portage.dbapi', 
 53                  'portage.dbapi.bintree:bindbapi,binarytree', 
 54                  'portage.dbapi.cpv_expand:cpv_expand', 
 55                  'portage.dbapi.dep_expand:dep_expand', 
 56                  'portage.dbapi.porttree:close_portdbapi_caches,FetchlistDict,' + \ 
 57                          'portagetree,portdbapi', 
 58                  'portage.dbapi.vartree:dblink,merge,unmerge,vardbapi,vartree', 
 59                  'portage.dbapi.virtual:fakedbapi', 
 60                  'portage.dep', 
 61                  'portage.dep:best_match_to_list,dep_getcpv,dep_getkey,' + \ 
 62                          'flatten,get_operator,isjustname,isspecific,isvalidatom,' + \ 
 63                          'match_from_list,match_to_list', 
 64                  'portage.dep.dep_check:dep_check,dep_eval,dep_wordreduce,dep_zapdeps', 
 65                  'portage.eclass_cache', 
 66                  'portage.elog', 
 67                  'portage.exception', 
 68                  'portage.getbinpkg', 
 69                  'portage.locks', 
 70                  'portage.locks:lockdir,lockfile,unlockdir,unlockfile', 
 71                  'portage.mail', 
 72                  'portage.manifest:Manifest', 
 73                  'portage.output', 
 74                  'portage.output:bold,colorize', 
 75                  'portage.package.ebuild.doebuild:doebuild,' + \ 
 76                          'doebuild_environment,spawn,spawnebuild', 
 77                  'portage.package.ebuild.config:autouse,best_from_dict,' + \ 
 78                          'check_config_instance,config', 
 79                  'portage.package.ebuild.deprecated_profile_check:' + \ 
 80                          'deprecated_profile_check', 
 81                  'portage.package.ebuild.digestcheck:digestcheck', 
 82                  'portage.package.ebuild.digestgen:digestgen', 
 83                  'portage.package.ebuild.fetch:fetch', 
 84                  'portage.package.ebuild.getmaskingreason:getmaskingreason', 
 85                  'portage.package.ebuild.getmaskingstatus:getmaskingstatus', 
 86                  'portage.package.ebuild.prepare_build_dirs:prepare_build_dirs', 
 87                  'portage.process', 
 88                  'portage.process:atexit_register,run_exitfuncs', 
 89                  'portage.update:dep_transform,fixdbentries,grab_updates,' + \ 
 90                          'parse_updates,update_config_files,update_dbentries,' + \ 
 91                          'update_dbentry', 
 92                  'portage.util', 
 93                  'portage.util:atomic_ofstream,apply_secpass_permissions,' + \ 
 94                          'apply_recursive_permissions,dump_traceback,getconfig,' + \ 
 95                          'grabdict,grabdict_package,grabfile,grabfile_package,' + \ 
 96                          'map_dictlist_vals,new_protect_filename,normalize_path,' + \ 
 97                          'pickle_read,pickle_write,stack_dictlist,stack_dicts,' + \ 
 98                          'stack_lists,unique_array,varexpand,writedict,writemsg,' + \ 
 99                          'writemsg_stdout,write_atomic', 
100                  'portage.util.digraph:digraph', 
101                  'portage.util.env_update:env_update', 
102                  'portage.util.ExtractKernelVersion:ExtractKernelVersion', 
103                  'portage.util.listdir:cacheddir,listdir', 
104                  'portage.util.movefile:movefile', 
105                  'portage.util.mtimedb:MtimeDB', 
106                  'portage.versions', 
107                  'portage.versions:best,catpkgsplit,catsplit,cpv_getkey,' + \ 
108                          'cpv_getkey@getCPFromCPV,endversion_keys,' + \ 
109                          'suffix_value@endversion,pkgcmp,pkgsplit,vercmp,ververify', 
110                  'portage.xpak', 
111                  'subprocess', 
112                  'time', 
113          ) 
114   
115          try: 
116                  from collections import OrderedDict 
117          except ImportError: 
118                  proxy.lazyimport.lazyimport(globals(), 
119                          'portage.cache.mappings:OrderedDict') 
120   
121          import portage.const 
122          from portage.const import VDB_PATH, PRIVATE_PATH, CACHE_PATH, DEPCACHE_PATH, \ 
123                  USER_CONFIG_PATH, MODULES_FILE_PATH, CUSTOM_PROFILE_PATH, PORTAGE_BASE_PATH, \ 
124                  PORTAGE_BIN_PATH, PORTAGE_PYM_PATH, PROFILE_PATH, LOCALE_DATA_PATH, \ 
125                  EBUILD_SH_BINARY, SANDBOX_BINARY, BASH_BINARY, \ 
126                  MOVE_BINARY, PRELINK_BINARY, WORLD_FILE, MAKE_CONF_FILE, MAKE_DEFAULTS_FILE, \ 
127                  DEPRECATED_PROFILE_FILE, USER_VIRTUALS_FILE, EBUILD_SH_ENV_FILE, \ 
128                  INVALID_ENV_FILE, CUSTOM_MIRRORS_FILE, CONFIG_MEMORY_FILE,\ 
129                  INCREMENTALS, EAPI, MISC_SH_BINARY, REPO_NAME_LOC, REPO_NAME_FILE 
130   
131  except ImportError as e: 
132          sys.stderr.write("\n\n") 
133          sys.stderr.write("!!! Failed to complete portage imports. There are internal modules for\n") 
134          sys.stderr.write("!!! portage and failure here indicates that you have a problem with your\n") 
135          sys.stderr.write("!!! installation of portage. Please try a rescue portage located in the\n") 
136          sys.stderr.write("!!! portage tree under '/usr/portage/sys-apps/portage/files/' (default).\n") 
137          sys.stderr.write("!!! There is a README.RESCUE file that details the steps required to perform\n") 
138          sys.stderr.write("!!! a recovery of portage.\n") 
139          sys.stderr.write("    "+str(e)+"\n\n") 
140          raise 
141   
142  if sys.hexversion >= 0x3000000: 
143          # pylint: disable=W0622 
144          basestring = str 
145          long = int 
146   
147  # We use utf_8 encoding everywhere. Previously, we used 
148  # sys.getfilesystemencoding() for the 'merge' encoding, but that had 
149  # various problems: 
150  # 
151  #   1) If the locale is ever changed then it can cause orphan files due 
152  #      to changed character set translation. 
153  # 
154  #   2) Ebuilds typically install files with utf_8 encoded file names, 
155  #      and then portage would be forced to rename those files to match 
156  #      sys.getfilesystemencoding(), possibly breaking things. 
157  # 
158  #   3) Automatic translation between encodings can lead to nonsensical 
159  #      file names when the source encoding is unknown by portage. 
160  # 
161  #   4) It's inconvenient for ebuilds to convert the encodings of file 
162  #      names to match the current locale, and upstreams typically encode 
163  #      file names with utf_8 encoding. 
164  # 
165  # So, instead of relying on sys.getfilesystemencoding(), we avoid the above 
166  # problems by using a constant utf_8 'merge' encoding for all locales, as 
167  # discussed in bug #382199 and bug #381509. 
168  _encodings = { 
169          'content'                : 'utf_8', 
170          'fs'                     : 'utf_8', 
171          'merge'                  : 'utf_8', 
172          'repo.content'           : 'utf_8', 
173          'stdio'                  : 'utf_8', 
174  } 
175   
176  if sys.hexversion >= 0x3000000: 
177 178 - def _decode_argv(argv):
179 # With Python 3, the surrogateescape encoding error handler makes it 180 # possible to access the original argv bytes, which can be useful 181 # if their actual encoding does no match the filesystem encoding. 182 fs_encoding = sys.getfilesystemencoding() 183 return [_unicode_decode(x.encode(fs_encoding, 'surrogateescape')) 184 for x in argv]
185
186 - def _unicode_encode(s, encoding=_encodings['content'], errors='backslashreplace'):
187 if isinstance(s, str): 188 s = s.encode(encoding, errors) 189 return s
190
191 - def _unicode_decode(s, encoding=_encodings['content'], errors='replace'):
192 if isinstance(s, bytes): 193 s = str(s, encoding=encoding, errors=errors) 194 return s
195 196 _native_string = _unicode_decode 197 else:
198 199 - def _decode_argv(argv):
200 return [_unicode_decode(x) for x in argv]
201
202 - def _unicode_encode(s, encoding=_encodings['content'], errors='backslashreplace'):
203 if isinstance(s, unicode): 204 s = s.encode(encoding, errors) 205 return s
206
207 - def _unicode_decode(s, encoding=_encodings['content'], errors='replace'):
208 if isinstance(s, bytes): 209 s = unicode(s, encoding=encoding, errors=errors) 210 return s
211 212 _native_string = _unicode_encode 213 214 if sys.hexversion >= 0x20605f0:
215 - def _native_kwargs(kwargs):
216 return kwargs
217 else:
218 # Avoid "TypeError: keywords must be strings" issue triggered 219 # by unicode_literals: http://bugs.python.org/issue4978 220 - def _native_kwargs(kwargs):
221 return dict((_native_string(k), v) for k, v in kwargs.iteritems())
222
223 -class _unicode_func_wrapper(object):
224 """ 225 Wraps a function, converts arguments from unicode to bytes, 226 and return values to unicode from bytes. Function calls 227 will raise UnicodeEncodeError if an argument fails to be 228 encoded with the required encoding. Return values that 229 are single strings are decoded with errors='replace'. Return 230 values that are lists of strings are decoded with errors='strict' 231 and elements that fail to be decoded are omitted from the returned 232 list. 233 """ 234 __slots__ = ('_func', '_encoding') 235
236 - def __init__(self, func, encoding=_encodings['fs']):
237 self._func = func 238 self._encoding = encoding
239
240 - def _process_args(self, args, kwargs):
241 242 encoding = self._encoding 243 wrapped_args = [_unicode_encode(x, encoding=encoding, errors='strict') 244 for x in args] 245 if kwargs: 246 wrapped_kwargs = dict( 247 (k, _unicode_encode(v, encoding=encoding, errors='strict')) 248 for k, v in kwargs.items()) 249 else: 250 wrapped_kwargs = {} 251 252 return (wrapped_args, wrapped_kwargs)
253
254 - def __call__(self, *args, **kwargs):
255 256 encoding = self._encoding 257 wrapped_args, wrapped_kwargs = self._process_args(args, kwargs) 258 259 rval = self._func(*wrapped_args, **wrapped_kwargs) 260 261 # Don't use isinstance() since we don't want to convert subclasses 262 # of tuple such as posix.stat_result in Python >=3.2. 263 if rval.__class__ in (list, tuple): 264 decoded_rval = [] 265 for x in rval: 266 try: 267 x = _unicode_decode(x, encoding=encoding, errors='strict') 268 except UnicodeDecodeError: 269 pass 270 else: 271 decoded_rval.append(x) 272 273 if isinstance(rval, tuple): 274 rval = tuple(decoded_rval) 275 else: 276 rval = decoded_rval 277 else: 278 rval = _unicode_decode(rval, encoding=encoding, errors='replace') 279 280 return rval
281
282 -class _unicode_module_wrapper(object):
283 """ 284 Wraps a module and wraps all functions with _unicode_func_wrapper. 285 """ 286 __slots__ = ('_mod', '_encoding', '_overrides', '_cache') 287
288 - def __init__(self, mod, encoding=_encodings['fs'], overrides=None, cache=True):
289 object.__setattr__(self, '_mod', mod) 290 object.__setattr__(self, '_encoding', encoding) 291 object.__setattr__(self, '_overrides', overrides) 292 if cache: 293 cache = {} 294 else: 295 cache = None 296 object.__setattr__(self, '_cache', cache)
297
298 - def __getattribute__(self, attr):
299 cache = object.__getattribute__(self, '_cache') 300 if cache is not None: 301 result = cache.get(attr) 302 if result is not None: 303 return result 304 result = getattr(object.__getattribute__(self, '_mod'), attr) 305 encoding = object.__getattribute__(self, '_encoding') 306 overrides = object.__getattribute__(self, '_overrides') 307 override = None 308 if overrides is not None: 309 override = overrides.get(id(result)) 310 if override is not None: 311 result = override 312 elif isinstance(result, type): 313 pass 314 elif type(result) is types.ModuleType: 315 result = _unicode_module_wrapper(result, 316 encoding=encoding, overrides=overrides) 317 elif hasattr(result, '__call__'): 318 result = _unicode_func_wrapper(result, encoding=encoding) 319 if cache is not None: 320 cache[attr] = result 321 return result
322
323 -class _eintr_func_wrapper(object):
324 """ 325 Wraps a function and handles EINTR by calling the function as 326 many times as necessary (until it returns without raising EINTR). 327 """ 328 329 __slots__ = ('_func',) 330
331 - def __init__(self, func):
332 self._func = func
333
334 - def __call__(self, *args, **kwargs):
335 336 while True: 337 try: 338 rval = self._func(*args, **kwargs) 339 break 340 except OSError as e: 341 if e.errno != errno.EINTR: 342 raise 343 344 return rval
345 346 import os as _os 347 _os_overrides = { 348 id(_os.fdopen) : _os.fdopen, 349 id(_os.popen) : _os.popen, 350 id(_os.read) : _os.read, 351 id(_os.system) : _os.system, 352 id(_os.waitpid) : _eintr_func_wrapper(_os.waitpid) 353 } 354 355 356 try: 357 _os_overrides[id(_os.mkfifo)] = _os.mkfifo 358 except AttributeError: 359 pass # Jython 360 361 if hasattr(_os, 'statvfs'): 362 _os_overrides[id(_os.statvfs)] = _os.statvfs 363 364 os = _unicode_module_wrapper(_os, overrides=_os_overrides, 365 encoding=_encodings['fs']) 366 _os_merge = _unicode_module_wrapper(_os, 367 encoding=_encodings['merge'], overrides=_os_overrides) 368 369 import shutil as _shutil 370 shutil = _unicode_module_wrapper(_shutil, encoding=_encodings['fs']) 371 372 # Imports below this point rely on the above unicode wrapper definitions. 373 try: 374 __import__('selinux') 375 import portage._selinux 376 selinux = _unicode_module_wrapper(_selinux, 377 encoding=_encodings['fs']) 378 _selinux_merge = _unicode_module_wrapper(_selinux, 379 encoding=_encodings['merge']) 380 except (ImportError, OSError) as e: 381 if isinstance(e, OSError): 382 sys.stderr.write("!!! SELinux not loaded: %s\n" % str(e)) 383 del e 384 _selinux = None 385 selinux = None 386 _selinux_merge = None 387 388 # =========================================================================== 389 # END OF IMPORTS -- END OF IMPORTS -- END OF IMPORTS -- END OF IMPORTS -- END 390 # =========================================================================== 391 392 _python_interpreter = os.path.realpath(sys.executable) 393 _bin_path = PORTAGE_BIN_PATH 394 _pym_path = PORTAGE_PYM_PATH 395 _not_installed = os.path.isfile(os.path.join(PORTAGE_BASE_PATH, ".portage_not_installed")) 396 397 # Api consumers included in portage should set this to True. 398 _internal_caller = False 399 400 _sync_mode = False
401 402 -def _get_stdin():
403 """ 404 Buggy code in python's multiprocessing/process.py closes sys.stdin 405 and reassigns it to open(os.devnull), but fails to update the 406 corresponding __stdin__ reference. So, detect that case and handle 407 it appropriately. 408 """ 409 if not sys.__stdin__.closed: 410 return sys.__stdin__ 411 return sys.stdin
412 413 _shell_quote_re = re.compile(r"[\s><=*\\\"'$`]")
414 415 -def _shell_quote(s):
416 """ 417 Quote a string in double-quotes and use backslashes to 418 escape any backslashes, double-quotes, dollar signs, or 419 backquotes in the string. 420 """ 421 if _shell_quote_re.search(s) is None: 422 return s 423 for letter in "\\\"$`": 424 if letter in s: 425 s = s.replace(letter, "\\" + letter) 426 return "\"%s\"" % s
427 428 bsd_chflags = None 429 430 if platform.system() in ('FreeBSD',):
431 432 - class bsd_chflags(object):
433 434 @classmethod
435 - def chflags(cls, path, flags, opts=""):
436 cmd = ['chflags'] 437 if opts: 438 cmd.append(opts) 439 cmd.append('%o' % (flags,)) 440 cmd.append(path) 441 442 if sys.hexversion < 0x3020000 and sys.hexversion >= 0x3000000: 443 # Python 3.1 _execvp throws TypeError for non-absolute executable 444 # path passed as bytes (see http://bugs.python.org/issue8513). 445 fullname = process.find_binary(cmd[0]) 446 if fullname is None: 447 raise exception.CommandNotFound(cmd[0]) 448 cmd[0] = fullname 449 450 encoding = _encodings['fs'] 451 cmd = [_unicode_encode(x, encoding=encoding, errors='strict') 452 for x in cmd] 453 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, 454 stderr=subprocess.STDOUT) 455 output = proc.communicate()[0] 456 status = proc.wait() 457 if os.WIFEXITED(status) and os.WEXITSTATUS(status) == os.EX_OK: 458 return 459 # Try to generate an ENOENT error if appropriate. 460 if 'h' in opts: 461 _os_merge.lstat(path) 462 else: 463 _os_merge.stat(path) 464 # Make sure the binary exists. 465 if not portage.process.find_binary('chflags'): 466 raise portage.exception.CommandNotFound('chflags') 467 # Now we're not sure exactly why it failed or what 468 # the real errno was, so just report EPERM. 469 output = _unicode_decode(output, encoding=encoding) 470 e = OSError(errno.EPERM, output) 471 e.errno = errno.EPERM 472 e.filename = path 473 e.message = output 474 raise e
475 476 @classmethod
477 - def lchflags(cls, path, flags):
478 return cls.chflags(path, flags, opts='-h')
479
480 -def load_mod(name):
481 modname = ".".join(name.split(".")[:-1]) 482 mod = __import__(modname) 483 components = name.split('.') 484 for comp in components[1:]: 485 mod = getattr(mod, comp) 486 return mod
487
488 -def getcwd():
489 "this fixes situations where the current directory doesn't exist" 490 try: 491 return os.getcwd() 492 except OSError: #dir doesn't exist 493 os.chdir("/") 494 return "/"
495 getcwd() 515 516 _doebuild_manifest_exempt_depend = 0 517 518 _testing_eapis = frozenset(["4-python", "4-slot-abi", "5-progress", "5-hdepend", "6_pre1"]) 519 _deprecated_eapis = frozenset(["4_pre1", "3_pre2", "3_pre1", "5_pre1", "5_pre2"]) 520 _supported_eapis = frozenset([str(x) for x in range(portage.const.EAPI + 1)] + list(_testing_eapis) + list(_deprecated_eapis))
521 522 -def _eapi_is_deprecated(eapi):
523 return eapi in _deprecated_eapis
524
525 -def eapi_is_supported(eapi):
526 if not isinstance(eapi, basestring): 527 # Only call str() when necessary since with python2 it 528 # can trigger UnicodeEncodeError if EAPI is corrupt. 529 eapi = str(eapi) 530 eapi = eapi.strip() 531 532 return eapi in _supported_eapis
533 534 # This pattern is specified by PMS section 7.3.1. 535 _pms_eapi_re = re.compile(r"^[ \t]*EAPI=(['\"]?)([A-Za-z0-9+_.-]*)\1[ \t]*([ \t]#.*)?$") 536 _comment_or_blank_line = re.compile(r"^\s*(#.*)?$")
537 538 -def _parse_eapi_ebuild_head(f):
539 eapi = None 540 eapi_lineno = None 541 lineno = 0 542 for line in f: 543 lineno += 1 544 m = _comment_or_blank_line.match(line) 545 if m is None: 546 eapi_lineno = lineno 547 m = _pms_eapi_re.match(line) 548 if m is not None: 549 eapi = m.group(2) 550 break 551 552 return (eapi, eapi_lineno)
553
554 -def _movefile(src, dest, **kwargs):
555 """Calls movefile and raises a PortageException if an error occurs.""" 556 if movefile(src, dest, **kwargs) is None: 557 raise portage.exception.PortageException( 558 "mv '%s' '%s'" % (src, dest))
559 560 auxdbkeys = ( 561 'DEPEND', 'RDEPEND', 'SLOT', 'SRC_URI', 562 'RESTRICT', 'HOMEPAGE', 'LICENSE', 'DESCRIPTION', 563 'KEYWORDS', 'INHERITED', 'IUSE', 'REQUIRED_USE', 564 'PDEPEND', 'PROVIDE', 'EAPI', 565 'PROPERTIES', 'DEFINED_PHASES', 'HDEPEND', 'UNUSED_04', 566 'UNUSED_03', 'UNUSED_02', 'UNUSED_01', 567 ) 568 auxdbkeylen = len(auxdbkeys)
569 570 -def portageexit():
571 pass
572
573 -class _trees_dict(dict):
574 __slots__ = ('_running_eroot', '_target_eroot',)
575 - def __init__(self, *pargs, **kargs):
576 dict.__init__(self, *pargs, **kargs) 577 self._running_eroot = None 578 self._target_eroot = None
579
580 -def create_trees(config_root=None, target_root=None, trees=None, env=None, 581 eprefix=None):
582 583 if trees is None: 584 trees = _trees_dict() 585 elif not isinstance(trees, _trees_dict): 586 # caller passed a normal dict or something, 587 # but we need a _trees_dict instance 588 trees = _trees_dict(trees) 589 590 if env is None: 591 env = os.environ 592 593 settings = config(config_root=config_root, target_root=target_root, 594 env=env, eprefix=eprefix) 595 settings.lock() 596 597 depcachedir = settings.get('PORTAGE_DEPCACHEDIR') 598 trees._target_eroot = settings['EROOT'] 599 myroots = [(settings['EROOT'], settings)] 600 if settings["ROOT"] == "/" and settings["EPREFIX"] == const.EPREFIX: 601 trees._running_eroot = trees._target_eroot 602 else: 603 604 # When ROOT != "/" we only want overrides from the calling 605 # environment to apply to the config that's associated 606 # with ROOT != "/", so pass a nearly empty dict for the env parameter. 607 clean_env = {} 608 for k in ('PATH', 'PORTAGE_GRPNAME', 'PORTAGE_REPOSITORIES', 'PORTAGE_USERNAME', 609 'PYTHONPATH', 'SSH_AGENT_PID', 'SSH_AUTH_SOCK', 'TERM', 610 'ftp_proxy', 'http_proxy', 'no_proxy', 611 '__PORTAGE_TEST_HARDLINK_LOCKS'): 612 v = settings.get(k) 613 if v is not None: 614 clean_env[k] = v 615 if depcachedir is not None: 616 clean_env['PORTAGE_DEPCACHEDIR'] = depcachedir 617 settings = config(config_root=None, target_root="/", 618 env=clean_env, eprefix=None) 619 settings.lock() 620 trees._running_eroot = settings['EROOT'] 621 myroots.append((settings['EROOT'], settings)) 622 623 for myroot, mysettings in myroots: 624 trees[myroot] = portage.util.LazyItemsDict(trees.get(myroot, {})) 625 trees[myroot].addLazySingleton("virtuals", mysettings.getvirtuals) 626 trees[myroot].addLazySingleton( 627 "vartree", vartree, categories=mysettings.categories, 628 settings=mysettings) 629 trees[myroot].addLazySingleton("porttree", 630 portagetree, settings=mysettings) 631 trees[myroot].addLazySingleton("bintree", 632 binarytree, pkgdir=mysettings["PKGDIR"], settings=mysettings) 633 return trees
634 635 if VERSION == 'HEAD':
636 - class _LazyVersion(proxy.objectproxy.ObjectProxy):
637 - def _get_target(self):
638 global VERSION 639 if VERSION is not self: 640 return VERSION 641 if os.path.isdir(os.path.join(PORTAGE_BASE_PATH, '.git')): 642 encoding = _encodings['fs'] 643 cmd = [BASH_BINARY, "-c", ("cd %s ; git describe --tags || exit $? ; " + \ 644 "if [ -n \"`git diff-index --name-only --diff-filter=M HEAD`\" ] ; " + \ 645 "then echo modified ; git rev-list --format=%%ct -n 1 HEAD ; fi ; " + \ 646 "exit 0") % _shell_quote(PORTAGE_BASE_PATH)] 647 cmd = [_unicode_encode(x, encoding=encoding, errors='strict') 648 for x in cmd] 649 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, 650 stderr=subprocess.STDOUT) 651 output = _unicode_decode(proc.communicate()[0], encoding=encoding) 652 status = proc.wait() 653 if os.WIFEXITED(status) and os.WEXITSTATUS(status) == os.EX_OK: 654 output_lines = output.splitlines() 655 if output_lines: 656 version_split = output_lines[0].split('-') 657 if version_split: 658 VERSION = version_split[0].lstrip('v') 659 patchlevel = False 660 if len(version_split) > 1: 661 patchlevel = True 662 VERSION = "%s_p%s" % (VERSION, version_split[1]) 663 if len(output_lines) > 1 and output_lines[1] == 'modified': 664 head_timestamp = None 665 if len(output_lines) > 3: 666 try: 667 head_timestamp = long(output_lines[3]) 668 except ValueError: 669 pass 670 timestamp = long(time.time()) 671 if head_timestamp is not None and timestamp > head_timestamp: 672 timestamp = timestamp - head_timestamp 673 if not patchlevel: 674 VERSION = "%s_p0" % (VERSION,) 675 VERSION = "%s_p%d" % (VERSION, timestamp) 676 return VERSION 677 VERSION = 'HEAD' 678 return VERSION
679 VERSION = _LazyVersion() 680 681 _legacy_global_var_names = ("archlist", "db", "features", 682 "groups", "mtimedb", "mtimedbfile", "pkglines", 683 "portdb", "profiledir", "root", "selinux_enabled", 684 "settings", "thirdpartymirrors")
685 686 -def _reset_legacy_globals():
687 688 global _legacy_globals_constructed 689 _legacy_globals_constructed = set() 690 for k in _legacy_global_var_names: 691 globals()[k] = _LegacyGlobalProxy(k)
692
693 -class _LegacyGlobalProxy(proxy.objectproxy.ObjectProxy):
694 695 __slots__ = ('_name',) 696
697 - def __init__(self, name):
698 proxy.objectproxy.ObjectProxy.__init__(self) 699 object.__setattr__(self, '_name', name)
700
701 - def _get_target(self):
702 name = object.__getattribute__(self, '_name') 703 from portage._legacy_globals import _get_legacy_global 704 return _get_legacy_global(name)
705 706 _reset_legacy_globals()
707 708 -def _disable_legacy_globals():
709 """ 710 This deletes the ObjectProxy instances that are used 711 for lazy initialization of legacy global variables. 712 The purpose of deleting them is to prevent new code 713 from referencing these deprecated variables. 714 """ 715 global _legacy_global_var_names 716 for k in _legacy_global_var_names: 717 globals().pop(k, None)
718