import sys
import tempfile
import time
+import warnings
try:
import cPickle as pickle
_aux_cache_keys_re = re.compile(r'^NEEDED\..*$')
_aux_multi_line_re = re.compile(r'^(CONTENTS|NEEDED\..*)$')
- def __init__(self, root, categories=None, settings=None, vartree=None):
+ def __init__(self, _unused_param=None, categories=None, settings=None, vartree=None):
"""
The categories parameter is unused since the dbapi class
now has a categories property that is generated from the
available packages.
"""
- self.root = _unicode_decode(root,
- encoding=_encodings['content'], errors='strict')
- if self.root[-1] != '/':
- self.root += '/'
# Used by emerge to check whether any packages
# have been added or removed.
self.blockers = None
if settings is None:
- from portage import settings
+ settings = portage.settings
self.settings = settings
+ self.root = settings['ROOT']
+
+ if _unused_param is not None and _unused_param != self.root:
+ warnings.warn("The first parameter of the " + \
+ "portage.dbapi.vartree.vardbapi" + \
+ " constructor is now unused. Use " + \
+ "settings['ROOT'] instead.",
+ DeprecationWarning, stacklevel=2)
+
+ self._eroot = settings['EROOT']
if vartree is None:
- from portage import db
- vartree = db[root]["vartree"]
+ vartree = portage.db[self.root]["vartree"]
self.vartree = vartree
self._aux_cache_keys = set(
["BUILD_TIME", "CHOST", "COUNTER", "DEPEND", "DESCRIPTION",
"repository", "RESTRICT" , "SLOT", "USE", "DEFINED_PHASES",
"REQUIRED_USE"])
self._aux_cache_obj = None
- self._aux_cache_filename = os.path.join(self.root,
+ self._aux_cache_filename = os.path.join(self._eroot,
CACHE_PATH, "vdb_metadata.pickle")
- self._counter_path = os.path.join(root,
+ self._counter_path = os.path.join(self._eroot,
CACHE_PATH, "counter")
try:
- self.plib_registry = PreservedLibsRegistry(self.root,
- os.path.join(self.root, PRIVATE_PATH, "preserved_libs_registry"))
+ self.plib_registry = PreservedLibsRegistry(self._eroot,
+ os.path.join(self._eroot, PRIVATE_PATH, "preserved_libs_registry"))
except PermissionDenied:
# apparently this user isn't allowed to access PRIVATE_PATH
self.plib_registry = None
def getpath(self, mykey, filename=None):
# This is an optimized hotspot, so don't use unicode-wrapped
# os module and don't use os.path.join().
- rValue = self.root + VDB_PATH + _os.sep + mykey
+ rValue = self._eroot + VDB_PATH + _os.sep + mykey
if filename is not None:
# If filename is always relative, we can do just
# rValue += _os.sep + filename
This is called before an after any modifications, so that consumers
can use directory mtimes to validate caches. See bug #290428.
"""
- base = self.root + VDB_PATH
+ base = self._eroot + VDB_PATH
cat = catsplit(cpv)[0]
catdir = base + _os.sep + cat
t = time.time()
involve merge or unmerge of packages).
"""
returnme = []
- basepath = os.path.join(self.root, VDB_PATH) + os.path.sep
+ basepath = os.path.join(self._eroot, VDB_PATH) + os.path.sep
if use_cache:
from portage import listdir
return list(self._iter_match(mydep,
self.cp_list(mydep.cp, use_cache=use_cache)))
try:
- curmtime = os.stat(os.path.join(self.root, VDB_PATH, mycat)).st_mtime
+ curmtime = os.stat(os.path.join(self._eroot, VDB_PATH, mycat)).st_mtime
except (IOError, OSError):
curmtime=0
class vartree(object):
"this tree will scan a var/db/pkg database located at root (passed to init)"
- def __init__(self, root="/", virtual=None, clone=None, categories=None,
+ def __init__(self, root=None, virtual=None, clone=None, categories=None,
settings=None):
- if clone:
- writemsg("vartree.__init__(): deprecated " + \
- "use of clone parameter\n", noiselevel=-1)
- self.root = clone.root[:]
- self.dbapi = copy.deepcopy(clone.dbapi)
- self.populated = 1
- from portage import config
- self.settings = config(clone=clone.settings)
- else:
- self.root = root[:]
- if settings is None:
- from portage import settings
- self.settings = settings
- if categories is None:
- categories = settings.categories
- self.dbapi = vardbapi(self.root, categories=categories,
- settings=settings, vartree=self)
- self.populated = 1
+
+ if settings is None:
+ settings = portage.settings
+ self.root = settings['ROOT']
+
+ if root is not None and root != self.root:
+ warnings.warn("The 'root' parameter of the " + \
+ "portage.dbapi.vartree.vartree" + \
+ " constructor is now unused. Use " + \
+ "settings['ROOT'] instead.",
+ DeprecationWarning, stacklevel=2)
+
+ self.settings = settings
+ self.dbapi = vardbapi(settings=settings, vartree=self)
+ self.populated = 1
def getpath(self, mykey, filename=None):
return self.dbapi.getpath(mykey, filename=filename)
except SystemExit as e:
raise
except Exception as e:
- mydir = os.path.join(self.root, VDB_PATH, mycpv)
+ mydir = os.path.join(self._eroot, VDB_PATH, mycpv)
writemsg(_("\nParse Error reading PROVIDE and USE in '%s'\n") % mydir,
noiselevel=-1)
if mylines:
self._blockers = blockers
self._scheduler = scheduler
- self.dbroot = normalize_path(os.path.join(myroot, VDB_PATH))
+ # WARNING: EROOT support is experimental and may be incomplete
+ # for cases in which EPREFIX is non-empty.
+ self._eroot = mysettings['EROOT']
+ self.dbroot = normalize_path(os.path.join(self._eroot, VDB_PATH))
self.dbcatdir = self.dbroot+"/"+cat
self.dbpkgdir = self.dbcatdir+"/"+pkg
self.dbtmpdir = self.dbcatdir+"/-MERGING-"+pkg
obj_index = contents_re.groupindex['obj']
dir_index = contents_re.groupindex['dir']
sym_index = contents_re.groupindex['sym']
- myroot = self.myroot
+ myroot = self._eroot
if myroot == os.path.sep:
myroot = None
pos = 0
#remove self from vartree database so that our own virtual gets zapped if we're the last node
self.vartree.zap(self.mycpv)
- def isowner(self, filename, destroot):
+ def isowner(self, filename, destroot=None):
"""
Check if a file belongs to this package. This may
result in a stat call for the parent directory of
1. True if this package owns the file.
2. False if this package does not own the file.
"""
- return bool(self._match_contents(filename, destroot))
- def _match_contents(self, filename, destroot):
+ if destroot is not None and destroot != self._eroot:
+ warnings.warn("The second parameter of the " + \
+ "portage.dbapi.vartree.dblink.isowner()" + \
+ " is now unused. Instead " + \
+ "self.settings['EROOT'] will be used.",
+ DeprecationWarning, stacklevel=2)
+
+ return bool(self._match_contents(filename))
+
+ def _match_contents(self, filename, destroot=None):
"""
The matching contents entry is returned, which is useful
since the path may differ from the one given by the caller,
filename = _unicode_decode(filename,
encoding=_encodings['content'], errors='strict')
- destroot = _unicode_decode(destroot,
- encoding=_encodings['content'], errors='strict')
+ if destroot is not None and destroot != self._eroot:
+ warnings.warn("The second parameter of the " + \
+ "portage.dbapi.vartree.dblink._match_contents()" + \
+ " is now unused. Instead " + \
+ "self.settings['EROOT'] will be used.",
+ DeprecationWarning, stacklevel=2)
+
+ destroot = self._eroot
# The given filename argument might have a different encoding than the
# the filenames contained in the contents, so use separate wrapped os
def __init__(self, clone=None, mycpv=None, config_profile_path=None,
config_incrementals=None, config_root=None, target_root=None,
- local_config=True, env=None):
+ _eprefix=None, local_config=True, env=None):
"""
@param clone: If provided, init will use deepcopy to copy by value the instance.
@type clone: Instance of config class.
@type config_root: String
@param target_root: __init__ override of $ROOT env variable.
@type target_root: String
+ @param _eprefix: set the EPREFIX variable (private, used by internal tests)
+ @type _eprefix: String
@param local_config: Enables loading of local config (/etc/portage); used most by repoman to
ignore local config (keywording and unmasking)
@type local_config: Boolean
@type env: dict
"""
+ # rename local _eprefix variable for convenience
+ eprefix = _eprefix
+ del _eprefix
+
# When initializing the global portage.settings instance, avoid
# raising exceptions whenever possible since exceptions thrown
# from 'import portage' or 'import portage.exceptions' statements
noiselevel=-1)
raise DirectoryNotFound(var)
+ if eprefix is None:
+ eprefix = ""
if config_root is None:
- config_root = "/"
+ config_root = eprefix + os.sep
config_root = normalize_path(os.path.abspath(
config_root)).rstrip(os.path.sep) + os.path.sep
ensure_dirs(target_root)
check_var_directory("ROOT", target_root)
+ eroot = target_root.rstrip(os.sep) + eprefix + os.sep
+
# The expand_map is used for variable substitution
# in getconfig() calls, and the getconfig() calls
# update expand_map with the value of each variable
# lead to unexpected results.
expand_map = {}
- env_d = getconfig(os.path.join(target_root, "etc", "profile.env"),
+ env_d = getconfig(os.path.join(eroot, "etc", "profile.env"),
expand=expand_map)
# env_d will be None if profile.env doesn't exist.
if env_d:
self["ROOT"] = target_root
self.backup_changes("ROOT")
- # Prefix forward compatability, set EPREFIX to the empty string
- self["EPREFIX"] = ''
+ self["EPREFIX"] = eprefix
self.backup_changes("EPREFIX")
- self["EROOT"] = target_root
+ self["EROOT"] = eroot
self.backup_changes("EROOT")
self.pusedict = portage.dep.ExtendedAtomDict(dict)
"""
Create a few directories that are critical to portage operation
"""
- if not os.access(self["ROOT"], os.W_OK):
+ if not os.access(self["EROOT"], os.W_OK):
return
# gid, mode, mask, preserve_perms
for mypath, (gid, mode, modemask, preserve_perms) \
in dir_mode_map.items():
- mydir = os.path.join(self["ROOT"], mypath)
+ mydir = os.path.join(self["EROOT"], mypath)
if preserve_perms and os.path.isdir(mydir):
# Only adjust permissions on some directories if
# they don't exist yet. This gives freedom to the
def reload(self):
"""Reload things like /etc/profile.env that can change during runtime."""
- env_d_filename = os.path.join(self["ROOT"], "etc", "profile.env")
+ env_d_filename = os.path.join(self["EROOT"], "etc", "profile.env")
self.configdict["env.d"].clear()
env_d = getconfig(env_d_filename, expand=False)
if env_d:
profile: settings defined by the profile.
"""
self.debug = debug
- self.root = tempfile.mkdtemp() + os.path.sep
- self.portdir = os.path.join(self.root, "usr/portage")
- self.vdbdir = os.path.join(self.root, "var/db/pkg")
+ self.root = "/"
+ self.eprefix = tempfile.mkdtemp()
+ self.eroot = self.root + self.eprefix.lstrip(os.sep) + os.sep
+ self.portdir = os.path.join(self.eroot, "usr/portage")
+ self.vdbdir = os.path.join(self.eroot, "var/db/pkg")
os.makedirs(self.portdir)
os.makedirs(self.vdbdir)
raise NotImplentedError()
#Create profile symlink
- os.makedirs(os.path.join(self.root, "etc"))
- os.symlink(sub_profile_dir, os.path.join(self.root, "etc", "make.profile"))
+ os.makedirs(os.path.join(self.eroot, "etc"))
+ os.symlink(sub_profile_dir, os.path.join(self.eroot, "etc", "make.profile"))
def _create_world(self, world):
#Create /var/lib/portage/world
- var_lib_portage = os.path.join(self.root, "var", "lib", "portage")
+ var_lib_portage = os.path.join(self.eroot, "var", "lib", "portage")
os.makedirs(var_lib_portage)
world_file = os.path.join(var_lib_portage, "world")
env = {
"ACCEPT_KEYWORDS": "x86",
"PORTDIR": self.portdir,
- "ROOT": self.root,
- 'PORTAGE_TMPDIR' : os.path.join(self.root, 'var/tmp'),
+ 'PORTAGE_TMPDIR' : os.path.join(self.eroot, 'var/tmp'),
}
# Pass along PORTAGE_USERNAME and PORTAGE_GRPNAME since they
if 'PORTAGE_GRPNAME' in os.environ:
env['PORTAGE_GRPNAME'] = os.environ['PORTAGE_GRPNAME']
- settings = config(config_root=self.root, target_root=self.root, env=env)
+ settings = config(_eprefix=self.eprefix, env=env)
settings.lock()
trees = {
self.root: {
- "virtuals": settings.getvirtuals(),
- "vartree": vartree(self.root, categories=settings.categories, settings=settings),
+ "vartree": vartree(settings=settings),
"porttree": portagetree(self.root, settings=settings),
- "bintree": binarytree(self.root, os.path.join(self.root, "usr/portage/packages"), settings=settings)
+ "bintree": binarytree(self.root,
+ os.path.join(self.eroot, "usr/portage/packages"),
+ settings=settings)
}
}
options = options.copy()
options["--pretend"] = True
options["--quiet"] = True
- options["--root"] = self.root
- options["--config-root"] = self.root
- options["--root-deps"] = True
if self.debug:
options["--debug"] = True
- # Add a fake _test_ option that can be used for
- # conditional test code.
- options["_test_"] = True
if not self.debug:
portage.util.noiselimit = -2
def cleanup(self):
if self.debug:
- print("\nROOT=%s" % self.root)
+ print("\nEROOT=%s" % self.eroot)
else:
- shutil.rmtree(self.root)
+ shutil.rmtree(self.eroot)
class ResolverPlaygroundTestCase(object):