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 -class _unicode_func_wrapper(object):
215 """ 216 Wraps a function, converts arguments from unicode to bytes, 217 and return values to unicode from bytes. Function calls 218 will raise UnicodeEncodeError if an argument fails to be 219 encoded with the required encoding. Return values that 220 are single strings are decoded with errors='replace'. Return 221 values that are lists of strings are decoded with errors='strict' 222 and elements that fail to be decoded are omitted from the returned 223 list. 224 """ 225 __slots__ = ('_func', '_encoding') 226
227 - def __init__(self, func, encoding=_encodings['fs']):
228 self._func = func 229 self._encoding = encoding
230
231 - def _process_args(self, args, kwargs):
232 233 encoding = self._encoding 234 wrapped_args = [_unicode_encode(x, encoding=encoding, errors='strict') 235 for x in args] 236 if kwargs: 237 wrapped_kwargs = dict( 238 (k, _unicode_encode(v, encoding=encoding, errors='strict')) 239 for k, v in kwargs.items()) 240 else: 241 wrapped_kwargs = {} 242 243 return (wrapped_args, wrapped_kwargs)
244
245 - def __call__(self, *args, **kwargs):
246 247 encoding = self._encoding 248 wrapped_args, wrapped_kwargs = self._process_args(args, kwargs) 249 250 rval = self._func(*wrapped_args, **wrapped_kwargs) 251 252 # Don't use isinstance() since we don't want to convert subclasses 253 # of tuple such as posix.stat_result in Python >=3.2. 254 if rval.__class__ in (list, tuple): 255 decoded_rval = [] 256 for x in rval: 257 try: 258 x = _unicode_decode(x, encoding=encoding, errors='strict') 259 except UnicodeDecodeError: 260 pass 261 else: 262 decoded_rval.append(x) 263 264 if isinstance(rval, tuple): 265 rval = tuple(decoded_rval) 266 else: 267 rval = decoded_rval 268 else: 269 rval = _unicode_decode(rval, encoding=encoding, errors='replace') 270 271 return rval
272
273 -class _unicode_module_wrapper(object):
274 """ 275 Wraps a module and wraps all functions with _unicode_func_wrapper. 276 """ 277 __slots__ = ('_mod', '_encoding', '_overrides', '_cache') 278
279 - def __init__(self, mod, encoding=_encodings['fs'], overrides=None, cache=True):
280 object.__setattr__(self, '_mod', mod) 281 object.__setattr__(self, '_encoding', encoding) 282 object.__setattr__(self, '_overrides', overrides) 283 if cache: 284 cache = {} 285 else: 286 cache = None 287 object.__setattr__(self, '_cache', cache)
288
289 - def __getattribute__(self, attr):
290 cache = object.__getattribute__(self, '_cache') 291 if cache is not None: 292 result = cache.get(attr) 293 if result is not None: 294 return result 295 result = getattr(object.__getattribute__(self, '_mod'), attr) 296 encoding = object.__getattribute__(self, '_encoding') 297 overrides = object.__getattribute__(self, '_overrides') 298 override = None 299 if overrides is not None: 300 override = overrides.get(id(result)) 301 if override is not None: 302 result = override 303 elif isinstance(result, type): 304 pass 305 elif type(result) is types.ModuleType: 306 result = _unicode_module_wrapper(result, 307 encoding=encoding, overrides=overrides) 308 elif hasattr(result, '__call__'): 309 result = _unicode_func_wrapper(result, encoding=encoding) 310 if cache is not None: 311 cache[attr] = result 312 return result
313
314 -class _eintr_func_wrapper(object):
315 """ 316 Wraps a function and handles EINTR by calling the function as 317 many times as necessary (until it returns without raising EINTR). 318 """ 319 320 __slots__ = ('_func',) 321
322 - def __init__(self, func):
323 self._func = func
324
325 - def __call__(self, *args, **kwargs):
326 327 while True: 328 try: 329 rval = self._func(*args, **kwargs) 330 break 331 except EnvironmentError as e: 332 if e.errno != errno.EINTR: 333 raise 334 335 return rval
336 337 import os as _os 338 _os_overrides = { 339 id(_os.fdopen) : _os.fdopen, 340 id(_os.popen) : _os.popen, 341 id(_os.read) : _os.read, 342 id(_os.system) : _os.system, 343 id(_os.waitpid) : _eintr_func_wrapper(_os.waitpid) 344 } 345 346 347 try: 348 _os_overrides[id(_os.mkfifo)] = _os.mkfifo 349 except AttributeError: 350 pass # Jython 351 352 if hasattr(_os, 'statvfs'): 353 _os_overrides[id(_os.statvfs)] = _os.statvfs 354 355 os = _unicode_module_wrapper(_os, overrides=_os_overrides, 356 encoding=_encodings['fs']) 357 _os_merge = _unicode_module_wrapper(_os, 358 encoding=_encodings['merge'], overrides=_os_overrides) 359 360 import shutil as _shutil 361 shutil = _unicode_module_wrapper(_shutil, encoding=_encodings['fs']) 362 363 # Imports below this point rely on the above unicode wrapper definitions. 364 try: 365 __import__('selinux') 366 import portage._selinux 367 selinux = _unicode_module_wrapper(_selinux, 368 encoding=_encodings['fs']) 369 _selinux_merge = _unicode_module_wrapper(_selinux, 370 encoding=_encodings['merge']) 371 except (ImportError, OSError) as e: 372 if isinstance(e, OSError): 373 sys.stderr.write("!!! SELinux not loaded: %s\n" % str(e)) 374 del e 375 _selinux = None 376 selinux = None 377 _selinux_merge = None 378 379 # =========================================================================== 380 # END OF IMPORTS -- END OF IMPORTS -- END OF IMPORTS -- END OF IMPORTS -- END 381 # =========================================================================== 382 383 _python_interpreter = os.path.realpath(sys.executable) 384 _bin_path = PORTAGE_BIN_PATH 385 _pym_path = PORTAGE_PYM_PATH 386 _not_installed = os.path.isfile(os.path.join(PORTAGE_BASE_PATH, ".portage_not_installed")) 387 388 # Api consumers included in portage should set this to True. 389 _internal_caller = False 390 391 _sync_mode = False
392 393 -def _get_stdin():
394 """ 395 Buggy code in python's multiprocessing/process.py closes sys.stdin 396 and reassigns it to open(os.devnull), but fails to update the 397 corresponding __stdin__ reference. So, detect that case and handle 398 it appropriately. 399 """ 400 if not sys.__stdin__.closed: 401 return sys.__stdin__ 402 return sys.stdin
403 404 _shell_quote_re = re.compile(r"[\s><=*\\\"'$`]")
405 406 -def _shell_quote(s):
407 """ 408 Quote a string in double-quotes and use backslashes to 409 escape any backslashes, double-quotes, dollar signs, or 410 backquotes in the string. 411 """ 412 if _shell_quote_re.search(s) is None: 413 return s 414 for letter in "\\\"$`": 415 if letter in s: 416 s = s.replace(letter, "\\" + letter) 417 return "\"%s\"" % s
418 419 bsd_chflags = None 420 421 if platform.system() in ('FreeBSD',):
422 423 - class bsd_chflags(object):
424 425 @classmethod
426 - def chflags(cls, path, flags, opts=""):
427 cmd = ['chflags'] 428 if opts: 429 cmd.append(opts) 430 cmd.append('%o' % (flags,)) 431 cmd.append(path) 432 433 if sys.hexversion < 0x3020000 and sys.hexversion >= 0x3000000: 434 # Python 3.1 _execvp throws TypeError for non-absolute executable 435 # path passed as bytes (see https://bugs.python.org/issue8513). 436 fullname = process.find_binary(cmd[0]) 437 if fullname is None: 438 raise exception.CommandNotFound(cmd[0]) 439 cmd[0] = fullname 440 441 encoding = _encodings['fs'] 442 cmd = [_unicode_encode(x, encoding=encoding, errors='strict') 443 for x in cmd] 444 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, 445 stderr=subprocess.STDOUT) 446 output = proc.communicate()[0] 447 status = proc.wait() 448 if os.WIFEXITED(status) and os.WEXITSTATUS(status) == os.EX_OK: 449 return 450 # Try to generate an ENOENT error if appropriate. 451 if 'h' in opts: 452 _os_merge.lstat(path) 453 else: 454 _os_merge.stat(path) 455 # Make sure the binary exists. 456 if not portage.process.find_binary('chflags'): 457 raise portage.exception.CommandNotFound('chflags') 458 # Now we're not sure exactly why it failed or what 459 # the real errno was, so just report EPERM. 460 output = _unicode_decode(output, encoding=encoding) 461 e = OSError(errno.EPERM, output) 462 e.errno = errno.EPERM 463 e.filename = path 464 e.message = output 465 raise e
466 467 @classmethod
468 - def lchflags(cls, path, flags):
469 return cls.chflags(path, flags, opts='-h')
470
471 -def load_mod(name):
472 modname = ".".join(name.split(".")[:-1]) 473 mod = __import__(modname) 474 components = name.split('.') 475 for comp in components[1:]: 476 mod = getattr(mod, comp) 477 return mod
478
479 -def getcwd():
480 "this fixes situations where the current directory doesn't exist" 481 try: 482 return os.getcwd() 483 except OSError: #dir doesn't exist 484 os.chdir("/") 485 return "/"
486 getcwd() 506 507 _doebuild_manifest_exempt_depend = 0 508 509 _testing_eapis = frozenset(["4-python", "4-slot-abi", "5-progress", "5-hdepend", "6_pre1"]) 510 _deprecated_eapis = frozenset(["4_pre1", "3_pre2", "3_pre1", "5_pre1", "5_pre2"]) 511 _supported_eapis = frozenset([str(x) for x in range(portage.const.EAPI + 1)] + list(_testing_eapis) + list(_deprecated_eapis))
512 513 -def _eapi_is_deprecated(eapi):
514 return eapi in _deprecated_eapis
515
516 -def eapi_is_supported(eapi):
517 if not isinstance(eapi, basestring): 518 # Only call str() when necessary since with python2 it 519 # can trigger UnicodeEncodeError if EAPI is corrupt. 520 eapi = str(eapi) 521 eapi = eapi.strip() 522 523 return eapi in _supported_eapis
524 525 # This pattern is specified by PMS section 7.3.1. 526 _pms_eapi_re = re.compile(r"^[ \t]*EAPI=(['\"]?)([A-Za-z0-9+_.-]*)\1[ \t]*([ \t]#.*)?$") 527 _comment_or_blank_line = re.compile(r"^\s*(#.*)?$")
528 529 -def _parse_eapi_ebuild_head(f):
530 eapi = None 531 eapi_lineno = None 532 lineno = 0 533 for line in f: 534 lineno += 1 535 m = _comment_or_blank_line.match(line) 536 if m is None: 537 eapi_lineno = lineno 538 m = _pms_eapi_re.match(line) 539 if m is not None: 540 eapi = m.group(2) 541 break 542 543 return (eapi, eapi_lineno)
544
545 -def _movefile(src, dest, **kwargs):
546 """Calls movefile and raises a PortageException if an error occurs.""" 547 if movefile(src, dest, **kwargs) is None: 548 raise portage.exception.PortageException( 549 "mv '%s' '%s'" % (src, dest))
550 551 auxdbkeys = ( 552 'DEPEND', 'RDEPEND', 'SLOT', 'SRC_URI', 553 'RESTRICT', 'HOMEPAGE', 'LICENSE', 'DESCRIPTION', 554 'KEYWORDS', 'INHERITED', 'IUSE', 'REQUIRED_USE', 555 'PDEPEND', 'PROVIDE', 'EAPI', 556 'PROPERTIES', 'DEFINED_PHASES', 'HDEPEND', 'UNUSED_04', 557 'UNUSED_03', 'UNUSED_02', 'UNUSED_01', 558 ) 559 auxdbkeylen = len(auxdbkeys)
560 561 -def portageexit():
562 pass
563
564 -class _trees_dict(dict):
565 __slots__ = ('_running_eroot', '_target_eroot',)
566 - def __init__(self, *pargs, **kargs):
567 dict.__init__(self, *pargs, **kargs) 568 self._running_eroot = None 569 self._target_eroot = None
570
571 -def create_trees(config_root=None, target_root=None, trees=None, env=None, 572 eprefix=None):
573 574 if trees is None: 575 trees = _trees_dict() 576 elif not isinstance(trees, _trees_dict): 577 # caller passed a normal dict or something, 578 # but we need a _trees_dict instance 579 trees = _trees_dict(trees) 580 581 if env is None: 582 env = os.environ 583 584 settings = config(config_root=config_root, target_root=target_root, 585 env=env, eprefix=eprefix) 586 settings.lock() 587 588 depcachedir = settings.get('PORTAGE_DEPCACHEDIR') 589 trees._target_eroot = settings['EROOT'] 590 myroots = [(settings['EROOT'], settings)] 591 if settings["ROOT"] == "/" and settings["EPREFIX"] == const.EPREFIX: 592 trees._running_eroot = trees._target_eroot 593 else: 594 595 # When ROOT != "/" we only want overrides from the calling 596 # environment to apply to the config that's associated 597 # with ROOT != "/", so pass a nearly empty dict for the env parameter. 598 clean_env = {} 599 for k in ('PATH', 'PORTAGE_GRPNAME', 'PORTAGE_REPOSITORIES', 'PORTAGE_USERNAME', 600 'PYTHONPATH', 'SSH_AGENT_PID', 'SSH_AUTH_SOCK', 'TERM', 601 'ftp_proxy', 'http_proxy', 'no_proxy', 602 '__PORTAGE_TEST_HARDLINK_LOCKS'): 603 v = settings.get(k) 604 if v is not None: 605 clean_env[k] = v 606 if depcachedir is not None: 607 clean_env['PORTAGE_DEPCACHEDIR'] = depcachedir 608 settings = config(config_root=None, target_root="/", 609 env=clean_env, eprefix=None) 610 settings.lock() 611 trees._running_eroot = settings['EROOT'] 612 myroots.append((settings['EROOT'], settings)) 613 614 for myroot, mysettings in myroots: 615 trees[myroot] = portage.util.LazyItemsDict(trees.get(myroot, {})) 616 trees[myroot].addLazySingleton("virtuals", mysettings.getvirtuals) 617 trees[myroot].addLazySingleton( 618 "vartree", vartree, categories=mysettings.categories, 619 settings=mysettings) 620 trees[myroot].addLazySingleton("porttree", 621 portagetree, settings=mysettings) 622 trees[myroot].addLazySingleton("bintree", 623 binarytree, pkgdir=mysettings["PKGDIR"], settings=mysettings) 624 return trees
625 626 if VERSION == 'HEAD':
627 - class _LazyVersion(proxy.objectproxy.ObjectProxy):
628 - def _get_target(self):
629 global VERSION 630 if VERSION is not self: 631 return VERSION 632 if os.path.isdir(os.path.join(PORTAGE_BASE_PATH, '.git')): 633 encoding = _encodings['fs'] 634 cmd = [BASH_BINARY, "-c", ("cd %s ; git describe --tags || exit $? ; " + \ 635 "if [ -n \"`git diff-index --name-only --diff-filter=M HEAD`\" ] ; " + \ 636 "then echo modified ; git rev-list --format=%%ct -n 1 HEAD ; fi ; " + \ 637 "exit 0") % _shell_quote(PORTAGE_BASE_PATH)] 638 cmd = [_unicode_encode(x, encoding=encoding, errors='strict') 639 for x in cmd] 640 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, 641 stderr=subprocess.STDOUT) 642 output = _unicode_decode(proc.communicate()[0], encoding=encoding) 643 status = proc.wait() 644 if os.WIFEXITED(status) and os.WEXITSTATUS(status) == os.EX_OK: 645 output_lines = output.splitlines() 646 if output_lines: 647 version_split = output_lines[0].split('-') 648 if len(version_split) > 1: 649 VERSION = version_split[1] 650 patchlevel = False 651 if len(version_split) > 2: 652 patchlevel = True 653 VERSION = "%s_p%s" % (VERSION, version_split[2]) 654 if len(output_lines) > 1 and output_lines[1] == 'modified': 655 head_timestamp = None 656 if len(output_lines) > 3: 657 try: 658 head_timestamp = long(output_lines[3]) 659 except ValueError: 660 pass 661 timestamp = long(time.time()) 662 if head_timestamp is not None and timestamp > head_timestamp: 663 timestamp = timestamp - head_timestamp 664 if not patchlevel: 665 VERSION = "%s_p0" % (VERSION,) 666 VERSION = "%s_p%d" % (VERSION, timestamp) 667 return VERSION 668 VERSION = 'HEAD' 669 return VERSION
670 VERSION = _LazyVersion() 671 672 _legacy_global_var_names = ("archlist", "db", "features", 673 "groups", "mtimedb", "mtimedbfile", "pkglines", 674 "portdb", "profiledir", "root", "selinux_enabled", 675 "settings", "thirdpartymirrors")
676 677 -def _reset_legacy_globals():
678 679 global _legacy_globals_constructed 680 _legacy_globals_constructed = set() 681 for k in _legacy_global_var_names: 682 globals()[k] = _LegacyGlobalProxy(k)
683
684 -class _LegacyGlobalProxy(proxy.objectproxy.ObjectProxy):
685 686 __slots__ = ('_name',) 687
688 - def __init__(self, name):
689 proxy.objectproxy.ObjectProxy.__init__(self) 690 object.__setattr__(self, '_name', name)
691
692 - def _get_target(self):
693 name = object.__getattribute__(self, '_name') 694 from portage._legacy_globals import _get_legacy_global 695 return _get_legacy_global(name)
696 697 _reset_legacy_globals()
698 699 -def _disable_legacy_globals():
700 """ 701 This deletes the ObjectProxy instances that are used 702 for lazy initialization of legacy global variables. 703 The purpose of deleting them is to prevent new code 704 from referencing these deprecated variables. 705 """ 706 global _legacy_global_var_names 707 for k in _legacy_global_var_names: 708 globals().pop(k, None)
709