Package portage
[hide private]

Source Code for Package portage

  1  # portage.py -- core Portage functionality 
  2  # Copyright 1998-2013 Gentoo Foundation 
  3  # Distributed under the terms of the GNU General Public License v2 
  4   
  5  from __future__ import unicode_literals 
  6   
  7  VERSION="2.2.7" 
  8   
  9  # =========================================================================== 
 10  # START OF IMPORTS -- START OF IMPORTS -- START OF IMPORTS -- START OF IMPORT 
 11  # =========================================================================== 
 12   
 13  try: 
 14          import sys 
 15          import errno 
 16          if not hasattr(errno, 'ESTALE'): 
 17                  # ESTALE may not be defined on some systems, such as interix. 
 18                  errno.ESTALE = -1 
 19          import re 
 20          import types 
 21          import platform 
 22   
 23          # Temporarily delete these imports, to ensure that only the 
 24          # wrapped versions are imported by portage internals. 
 25          import os 
 26          del os 
 27          import shutil 
 28          del shutil 
 29   
 30  except ImportError as e: 
 31          sys.stderr.write("\n\n") 
 32          sys.stderr.write("!!! Failed to complete python imports. These are internal modules for\n") 
 33          sys.stderr.write("!!! python and failure here indicates that you have a problem with python\n") 
 34          sys.stderr.write("!!! itself and thus portage is not able to continue processing.\n\n") 
 35   
 36          sys.stderr.write("!!! You might consider starting python with verbose flags to see what has\n") 
 37          sys.stderr.write("!!! gone wrong. Here is the information we got for this exception:\n") 
 38          sys.stderr.write("    "+str(e)+"\n\n"); 
 39          raise 
 40   
 41  try: 
 42   
 43          import portage.proxy.lazyimport 
 44          import portage.proxy as proxy 
 45          proxy.lazyimport.lazyimport(globals(), 
 46                  'portage.cache.cache_errors:CacheError', 
 47                  'portage.checksum', 
 48                  'portage.checksum:perform_checksum,perform_md5,prelink_capable', 
 49                  'portage.cvstree', 
 50                  'portage.data', 
 51                  'portage.data:lchown,ostype,portage_gid,portage_uid,secpass,' + \ 
 52                          'uid,userland,userpriv_groups,wheelgid', 
 53                  'portage.dbapi', 
 54                  'portage.dbapi.bintree:bindbapi,binarytree', 
 55                  'portage.dbapi.cpv_expand:cpv_expand', 
 56                  'portage.dbapi.dep_expand:dep_expand', 
 57                  'portage.dbapi.porttree:close_portdbapi_caches,FetchlistDict,' + \ 
 58                          'portagetree,portdbapi', 
 59                  'portage.dbapi.vartree:dblink,merge,unmerge,vardbapi,vartree', 
 60                  'portage.dbapi.virtual:fakedbapi', 
 61                  'portage.dep', 
 62                  'portage.dep:best_match_to_list,dep_getcpv,dep_getkey,' + \ 
 63                          'flatten,get_operator,isjustname,isspecific,isvalidatom,' + \ 
 64                          'match_from_list,match_to_list', 
 65                  'portage.dep.dep_check:dep_check,dep_eval,dep_wordreduce,dep_zapdeps', 
 66                  'portage.eclass_cache', 
 67                  'portage.elog', 
 68                  'portage.exception', 
 69                  'portage.getbinpkg', 
 70                  'portage.locks', 
 71                  'portage.locks:lockdir,lockfile,unlockdir,unlockfile', 
 72                  'portage.mail', 
 73                  'portage.manifest:Manifest', 
 74                  'portage.output', 
 75                  'portage.output:bold,colorize', 
 76                  'portage.package.ebuild.doebuild:doebuild,' + \ 
 77                          'doebuild_environment,spawn,spawnebuild', 
 78                  'portage.package.ebuild.config:autouse,best_from_dict,' + \ 
 79                          'check_config_instance,config', 
 80                  'portage.package.ebuild.deprecated_profile_check:' + \ 
 81                          'deprecated_profile_check', 
 82                  'portage.package.ebuild.digestcheck:digestcheck', 
 83                  'portage.package.ebuild.digestgen:digestgen', 
 84                  'portage.package.ebuild.fetch:fetch', 
 85                  'portage.package.ebuild.getmaskingreason:getmaskingreason', 
 86                  'portage.package.ebuild.getmaskingstatus:getmaskingstatus', 
 87                  'portage.package.ebuild.prepare_build_dirs:prepare_build_dirs', 
 88                  'portage.process', 
 89                  'portage.process:atexit_register,run_exitfuncs', 
 90                  'portage.update:dep_transform,fixdbentries,grab_updates,' + \ 
 91                          'parse_updates,update_config_files,update_dbentries,' + \ 
 92                          'update_dbentry', 
 93                  'portage.util', 
 94                  'portage.util:atomic_ofstream,apply_secpass_permissions,' + \ 
 95                          'apply_recursive_permissions,dump_traceback,getconfig,' + \ 
 96                          'grabdict,grabdict_package,grabfile,grabfile_package,' + \ 
 97                          'map_dictlist_vals,new_protect_filename,normalize_path,' + \ 
 98                          'pickle_read,pickle_write,stack_dictlist,stack_dicts,' + \ 
 99                          'stack_lists,unique_array,varexpand,writedict,writemsg,' + \ 
100                          'writemsg_stdout,write_atomic', 
101                  'portage.util.digraph:digraph', 
102                  'portage.util.env_update:env_update', 
103                  'portage.util.ExtractKernelVersion:ExtractKernelVersion', 
104                  'portage.util.listdir:cacheddir,listdir', 
105                  'portage.util.movefile:movefile', 
106                  'portage.util.mtimedb:MtimeDB', 
107                  'portage.versions', 
108                  'portage.versions:best,catpkgsplit,catsplit,cpv_getkey,' + \ 
109                          'cpv_getkey@getCPFromCPV,endversion_keys,' + \ 
110                          'suffix_value@endversion,pkgcmp,pkgsplit,vercmp,ververify', 
111                  'portage.xpak', 
112                  'subprocess', 
113                  'time', 
114          ) 
115   
116          try: 
117                  from collections import OrderedDict 
118          except ImportError: 
119                  proxy.lazyimport.lazyimport(globals(), 
120                          'portage.cache.mappings:OrderedDict') 
121   
122          import portage.const 
123          from portage.const import VDB_PATH, PRIVATE_PATH, CACHE_PATH, DEPCACHE_PATH, \ 
124                  USER_CONFIG_PATH, MODULES_FILE_PATH, CUSTOM_PROFILE_PATH, PORTAGE_BASE_PATH, \ 
125                  PORTAGE_BIN_PATH, PORTAGE_PYM_PATH, PROFILE_PATH, LOCALE_DATA_PATH, \ 
126                  EBUILD_SH_BINARY, SANDBOX_BINARY, BASH_BINARY, \ 
127                  MOVE_BINARY, PRELINK_BINARY, WORLD_FILE, MAKE_CONF_FILE, MAKE_DEFAULTS_FILE, \ 
128                  DEPRECATED_PROFILE_FILE, USER_VIRTUALS_FILE, EBUILD_SH_ENV_FILE, \ 
129                  INVALID_ENV_FILE, CUSTOM_MIRRORS_FILE, CONFIG_MEMORY_FILE,\ 
130                  INCREMENTALS, EAPI, MISC_SH_BINARY, REPO_NAME_LOC, REPO_NAME_FILE 
131   
132  except ImportError as e: 
133          sys.stderr.write("\n\n") 
134          sys.stderr.write("!!! Failed to complete portage imports. There are internal modules for\n") 
135          sys.stderr.write("!!! portage and failure here indicates that you have a problem with your\n") 
136          sys.stderr.write("!!! installation of portage. Please try a rescue portage located in the\n") 
137          sys.stderr.write("!!! portage tree under '/usr/portage/sys-apps/portage/files/' (default).\n") 
138          sys.stderr.write("!!! There is a README.RESCUE file that details the steps required to perform\n") 
139          sys.stderr.write("!!! a recovery of portage.\n") 
140          sys.stderr.write("    "+str(e)+"\n\n") 
141          raise 
142   
143  if sys.hexversion >= 0x3000000: 
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 import os as _os 324 _os_overrides = { 325 id(_os.fdopen) : _os.fdopen, 326 id(_os.popen) : _os.popen, 327 id(_os.read) : _os.read, 328 id(_os.system) : _os.system, 329 } 330 331 332 try: 333 _os_overrides[id(_os.mkfifo)] = _os.mkfifo 334 except AttributeError: 335 pass # Jython 336 337 if hasattr(_os, 'statvfs'): 338 _os_overrides[id(_os.statvfs)] = _os.statvfs 339 340 os = _unicode_module_wrapper(_os, overrides=_os_overrides, 341 encoding=_encodings['fs']) 342 _os_merge = _unicode_module_wrapper(_os, 343 encoding=_encodings['merge'], overrides=_os_overrides) 344 345 import shutil as _shutil 346 shutil = _unicode_module_wrapper(_shutil, encoding=_encodings['fs']) 347 348 # Imports below this point rely on the above unicode wrapper definitions. 349 try: 350 __import__('selinux') 351 import portage._selinux 352 selinux = _unicode_module_wrapper(_selinux, 353 encoding=_encodings['fs']) 354 _selinux_merge = _unicode_module_wrapper(_selinux, 355 encoding=_encodings['merge']) 356 except (ImportError, OSError) as e: 357 if isinstance(e, OSError): 358 sys.stderr.write("!!! SELinux not loaded: %s\n" % str(e)) 359 del e 360 _selinux = None 361 selinux = None 362 _selinux_merge = None 363 364 # =========================================================================== 365 # END OF IMPORTS -- END OF IMPORTS -- END OF IMPORTS -- END OF IMPORTS -- END 366 # =========================================================================== 367 368 _python_interpreter = os.path.realpath(sys.executable) 369 _bin_path = PORTAGE_BIN_PATH 370 _pym_path = PORTAGE_PYM_PATH 371 _working_copy = VERSION == "HEAD" 372 373 # Api consumers included in portage should set this to True. 374 _internal_caller = False 375 376 _sync_disabled_warnings = False
377 378 -def _get_stdin():
379 """ 380 Buggy code in python's multiprocessing/process.py closes sys.stdin 381 and reassigns it to open(os.devnull), but fails to update the 382 corresponding __stdin__ reference. So, detect that case and handle 383 it appropriately. 384 """ 385 if not sys.__stdin__.closed: 386 return sys.__stdin__ 387 return sys.stdin
388 389 _shell_quote_re = re.compile(r"[\s><=*\\\"'$`]")
390 391 -def _shell_quote(s):
392 """ 393 Quote a string in double-quotes and use backslashes to 394 escape any backslashes, double-quotes, dollar signs, or 395 backquotes in the string. 396 """ 397 if _shell_quote_re.search(s) is None: 398 return s 399 for letter in "\\\"$`": 400 if letter in s: 401 s = s.replace(letter, "\\" + letter) 402 return "\"%s\"" % s
403 404 bsd_chflags = None 405 406 if platform.system() in ('FreeBSD',):
407 408 - class bsd_chflags(object):
409 410 @classmethod
411 - def chflags(cls, path, flags, opts=""):
412 cmd = ['chflags'] 413 if opts: 414 cmd.append(opts) 415 cmd.append('%o' % (flags,)) 416 cmd.append(path) 417 418 if sys.hexversion < 0x3020000 and sys.hexversion >= 0x3000000: 419 # Python 3.1 _execvp throws TypeError for non-absolute executable 420 # path passed as bytes (see http://bugs.python.org/issue8513). 421 fullname = process.find_binary(cmd[0]) 422 if fullname is None: 423 raise exception.CommandNotFound(cmd[0]) 424 cmd[0] = fullname 425 426 encoding = _encodings['fs'] 427 cmd = [_unicode_encode(x, encoding=encoding, errors='strict') 428 for x in cmd] 429 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, 430 stderr=subprocess.STDOUT) 431 output = proc.communicate()[0] 432 status = proc.wait() 433 if os.WIFEXITED(status) and os.WEXITSTATUS(status) == os.EX_OK: 434 return 435 # Try to generate an ENOENT error if appropriate. 436 if 'h' in opts: 437 _os_merge.lstat(path) 438 else: 439 _os_merge.stat(path) 440 # Make sure the binary exists. 441 if not portage.process.find_binary('chflags'): 442 raise portage.exception.CommandNotFound('chflags') 443 # Now we're not sure exactly why it failed or what 444 # the real errno was, so just report EPERM. 445 output = _unicode_decode(output, encoding=encoding) 446 e = OSError(errno.EPERM, output) 447 e.errno = errno.EPERM 448 e.filename = path 449 e.message = output 450 raise e
451 452 @classmethod
453 - def lchflags(cls, path, flags):
454 return cls.chflags(path, flags, opts='-h')
455
456 -def load_mod(name):
457 modname = ".".join(name.split(".")[:-1]) 458 mod = __import__(modname) 459 components = name.split('.') 460 for comp in components[1:]: 461 mod = getattr(mod, comp) 462 return mod
463
464 -def getcwd():
465 "this fixes situations where the current directory doesn't exist" 466 try: 467 return os.getcwd() 468 except OSError: #dir doesn't exist 469 os.chdir("/") 470 return "/"
471 getcwd() 491 492 _doebuild_manifest_exempt_depend = 0 493 494 _testing_eapis = frozenset(["4-python", "4-slot-abi", "5-progress", "5-hdepend"]) 495 _deprecated_eapis = frozenset(["4_pre1", "3_pre2", "3_pre1", "5_pre1", "5_pre2"]) 496 _supported_eapis = frozenset([str(x) for x in range(portage.const.EAPI)] + list(_testing_eapis) + list(_deprecated_eapis))
497 498 -def _eapi_is_deprecated(eapi):
499 return eapi in _deprecated_eapis
500
501 -def eapi_is_supported(eapi):
502 if not isinstance(eapi, basestring): 503 # Only call str() when necessary since with python2 it 504 # can trigger UnicodeEncodeError if EAPI is corrupt. 505 eapi = str(eapi) 506 eapi = eapi.strip() 507 508 if _eapi_is_deprecated(eapi): 509 return True 510 511 if eapi in _testing_eapis: 512 return True 513 514 try: 515 eapi = int(eapi) 516 except ValueError: 517 eapi = -1 518 if eapi < 0: 519 return False 520 return eapi <= portage.const.EAPI
521 522 # This pattern is specified by PMS section 7.3.1. 523 _pms_eapi_re = re.compile(r"^[ \t]*EAPI=(['\"]?)([A-Za-z0-9+_.-]*)\1[ \t]*([ \t]#.*)?$") 524 _comment_or_blank_line = re.compile(r"^\s*(#.*)?$")
525 526 -def _parse_eapi_ebuild_head(f):
527 eapi = None 528 eapi_lineno = None 529 lineno = 0 530 for line in f: 531 lineno += 1 532 m = _comment_or_blank_line.match(line) 533 if m is None: 534 eapi_lineno = lineno 535 m = _pms_eapi_re.match(line) 536 if m is not None: 537 eapi = m.group(2) 538 break 539 540 return (eapi, eapi_lineno)
541
542 -def _movefile(src, dest, **kwargs):
543 """Calls movefile and raises a PortageException if an error occurs.""" 544 if movefile(src, dest, **kwargs) is None: 545 raise portage.exception.PortageException( 546 "mv '%s' '%s'" % (src, dest))
547 548 auxdbkeys = ( 549 'DEPEND', 'RDEPEND', 'SLOT', 'SRC_URI', 550 'RESTRICT', 'HOMEPAGE', 'LICENSE', 'DESCRIPTION', 551 'KEYWORDS', 'INHERITED', 'IUSE', 'REQUIRED_USE', 552 'PDEPEND', 'PROVIDE', 'EAPI', 553 'PROPERTIES', 'DEFINED_PHASES', 'HDEPEND', 'UNUSED_04', 554 'UNUSED_03', 'UNUSED_02', 'UNUSED_01', 555 ) 556 auxdbkeylen=len(auxdbkeys)
557 558 -def portageexit():
559 pass
560
561 -class _trees_dict(dict):
562 __slots__ = ('_running_eroot', '_target_eroot',)
563 - def __init__(self, *pargs, **kargs):
564 dict.__init__(self, *pargs, **kargs) 565 self._running_eroot = None 566 self._target_eroot = None
567
568 -def create_trees(config_root=None, target_root=None, trees=None, env=None, 569 eprefix=None):
570 571 if trees is None: 572 trees = _trees_dict() 573 elif not isinstance(trees, _trees_dict): 574 # caller passed a normal dict or something, 575 # but we need a _trees_dict instance 576 trees = _trees_dict(trees) 577 578 if env is None: 579 env = os.environ 580 581 settings = config(config_root=config_root, target_root=target_root, 582 env=env, eprefix=eprefix) 583 settings.lock() 584 585 trees._target_eroot = settings['EROOT'] 586 myroots = [(settings['EROOT'], settings)] 587 if settings["ROOT"] == "/" and settings["EPREFIX"] == const.EPREFIX: 588 trees._running_eroot = trees._target_eroot 589 else: 590 591 # When ROOT != "/" we only want overrides from the calling 592 # environment to apply to the config that's associated 593 # with ROOT != "/", so pass a nearly empty dict for the env parameter. 594 clean_env = {} 595 for k in ('PATH', 'PORTAGE_GRPNAME', 'PORTAGE_REPOSITORIES', 'PORTAGE_USERNAME', 596 'PYTHONPATH', 'SSH_AGENT_PID', 'SSH_AUTH_SOCK', 'TERM', 597 'ftp_proxy', 'http_proxy', 'no_proxy', 598 '__PORTAGE_TEST_HARDLINK_LOCKS'): 599 v = settings.get(k) 600 if v is not None: 601 clean_env[k] = v 602 settings = config(config_root=None, target_root="/", 603 env=clean_env, eprefix=None) 604 settings.lock() 605 trees._running_eroot = settings['EROOT'] 606 myroots.append((settings['EROOT'], settings)) 607 608 for myroot, mysettings in myroots: 609 trees[myroot] = portage.util.LazyItemsDict(trees.get(myroot, {})) 610 trees[myroot].addLazySingleton("virtuals", mysettings.getvirtuals) 611 trees[myroot].addLazySingleton( 612 "vartree", vartree, categories=mysettings.categories, 613 settings=mysettings) 614 trees[myroot].addLazySingleton("porttree", 615 portagetree, settings=mysettings) 616 trees[myroot].addLazySingleton("bintree", 617 binarytree, pkgdir=mysettings["PKGDIR"], settings=mysettings) 618 return trees
619 620 if VERSION == 'HEAD':
621 - class _LazyVersion(proxy.objectproxy.ObjectProxy):
622 - def _get_target(self):
623 global VERSION 624 if VERSION is not self: 625 return VERSION 626 if os.path.isdir(os.path.join(PORTAGE_BASE_PATH, '.git')): 627 encoding = _encodings['fs'] 628 cmd = [BASH_BINARY, "-c", ("cd %s ; git describe --tags || exit $? ; " + \ 629 "if [ -n \"`git diff-index --name-only --diff-filter=M HEAD`\" ] ; " + \ 630 "then echo modified ; git rev-list --format=%%ct -n 1 HEAD ; fi ; " + \ 631 "exit 0") % _shell_quote(PORTAGE_BASE_PATH)] 632 cmd = [_unicode_encode(x, encoding=encoding, errors='strict') 633 for x in cmd] 634 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, 635 stderr=subprocess.STDOUT) 636 output = _unicode_decode(proc.communicate()[0], encoding=encoding) 637 status = proc.wait() 638 if os.WIFEXITED(status) and os.WEXITSTATUS(status) == os.EX_OK: 639 output_lines = output.splitlines() 640 if output_lines: 641 version_split = output_lines[0].split('-') 642 if version_split: 643 VERSION = version_split[0].lstrip('v') 644 patchlevel = False 645 if len(version_split) > 1: 646 patchlevel = True 647 VERSION = "%s_p%s" %(VERSION, version_split[1]) 648 if len(output_lines) > 1 and output_lines[1] == 'modified': 649 head_timestamp = None 650 if len(output_lines) > 3: 651 try: 652 head_timestamp = long(output_lines[3]) 653 except ValueError: 654 pass 655 timestamp = long(time.time()) 656 if head_timestamp is not None and timestamp > head_timestamp: 657 timestamp = timestamp - head_timestamp 658 if not patchlevel: 659 VERSION = "%s_p0" % (VERSION,) 660 VERSION = "%s_p%d" % (VERSION, timestamp) 661 return VERSION 662 VERSION = 'HEAD' 663 return VERSION
664 VERSION = _LazyVersion() 665 666 _legacy_global_var_names = ("archlist", "db", "features", 667 "groups", "mtimedb", "mtimedbfile", "pkglines", 668 "portdb", "profiledir", "root", "selinux_enabled", 669 "settings", "thirdpartymirrors")
670 671 -def _reset_legacy_globals():
672 673 global _legacy_globals_constructed 674 _legacy_globals_constructed = set() 675 for k in _legacy_global_var_names: 676 globals()[k] = _LegacyGlobalProxy(k)
677
678 -class _LegacyGlobalProxy(proxy.objectproxy.ObjectProxy):
679 680 __slots__ = ('_name',) 681
682 - def __init__(self, name):
683 proxy.objectproxy.ObjectProxy.__init__(self) 684 object.__setattr__(self, '_name', name)
685
686 - def _get_target(self):
687 name = object.__getattribute__(self, '_name') 688 from portage._legacy_globals import _get_legacy_global 689 return _get_legacy_global(name)
690 691 _reset_legacy_globals()
692 693 -def _disable_legacy_globals():
694 """ 695 This deletes the ObjectProxy instances that are used 696 for lazy initialization of legacy global variables. 697 The purpose of deleting them is to prevent new code 698 from referencing these deprecated variables. 699 """ 700 global _legacy_global_var_names 701 for k in _legacy_global_var_names: 702 globals().pop(k, None)
703