class _frozen_depgraph_config(object):
- def __init__(self, settings, trees, myopts, spinner, dynamic_config, depgraph):
+ def __init__(self, settings, trees, myopts, spinner):
self.settings = settings
self.target_root = settings["ROOT"]
self.myopts = myopts
self.trees = {}
self._trees_orig = trees
self.roots = {}
- # Contains installed packages and new packages that have been added
- # to the graph.
- self._graph_trees = {}
+ # All Package instances
+ self._pkg_cache = {}
for myroot in trees:
self.trees[myroot] = {}
# Create a RootConfig instance that references
self.trees[myroot][tree] = trees[myroot][tree]
self.trees[myroot]["vartree"] = \
FakeVartree(trees[myroot]["root_config"],
- pkg_cache=dynamic_config._pkg_cache)
+ pkg_cache=self._pkg_cache)
self.pkgsettings[myroot] = portage.config(
clone=self.trees[myroot]["vartree"].settings)
- dynamic_config._slot_pkg_map[myroot] = {}
- vardb = self.trees[myroot]["vartree"].dbapi
- preload_installed_pkgs = "--nodeps" not in self.myopts and \
- "--buildpkgonly" not in self.myopts
- # This fakedbapi instance will model the state that the vdb will
- # have after new packages have been installed.
- fakedb = PackageVirtualDbapi(vardb.settings)
- if preload_installed_pkgs:
- for pkg in vardb:
- self.spinner.update()
- # This triggers metadata updates via FakeVartree.
- vardb.aux_get(pkg.cpv, [])
- fakedb.cpv_inject(pkg)
-
- # Now that the vardb state is cached in our FakeVartree,
- # we won't be needing the real vartree cache for awhile.
- # To make some room on the heap, clear the vardbapi
- # caches.
- trees[myroot]["vartree"].dbapi._clear_cache()
- gc.collect()
-
- dynamic_config.mydbapi[myroot] = fakedb
- def graph_tree():
- pass
- graph_tree.dbapi = fakedb
- self._graph_trees[myroot] = {}
- dynamic_config._filtered_trees[myroot] = {}
- # Substitute the graph tree for the vartree in dep_check() since we
- # want atom selections to be consistent with package selections
- # have already been made.
- self._graph_trees[myroot]["porttree"] = graph_tree
- self._graph_trees[myroot]["vartree"] = graph_tree
- def filtered_tree():
- pass
- filtered_tree.dbapi = _dep_check_composite_db(depgraph, myroot)
- dynamic_config._filtered_trees[myroot]["porttree"] = filtered_tree
-
- # Passing in graph_tree as the vartree here could lead to better
- # atom selections in some cases by causing atoms for packages that
- # have been added to the graph to be preferred over other choices.
- # However, it can trigger atom selections that result in
- # unresolvable direct circular dependencies. For example, this
- # happens with gwydion-dylan which depends on either itself or
- # gwydion-dylan-bin. In case gwydion-dylan is not yet installed,
- # gwydion-dylan-bin needs to be selected in order to avoid a
- # an unresolvable direct circular dependency.
- #
- # To solve the problem described above, pass in "graph_db" so that
- # packages that have been added to the graph are distinguishable
- # from other available packages and installed packages. Also, pass
- # the parent package into self._select_atoms() calls so that
- # unresolvable direct circular dependencies can be detected and
- # avoided when possible.
- dynamic_config._filtered_trees[myroot]["graph_db"] = graph_tree.dbapi
- dynamic_config._filtered_trees[myroot]["vartree"] = self.trees[myroot]["vartree"]
-
- dbs = []
- portdb = self.trees[myroot]["porttree"].dbapi
- bindb = self.trees[myroot]["bintree"].dbapi
- vardb = self.trees[myroot]["vartree"].dbapi
- # (db, pkg_type, built, installed, db_keys)
- if "--usepkgonly" not in self.myopts:
- db_keys = list(portdb._aux_cache_keys)
- dbs.append((portdb, "ebuild", False, False, db_keys))
- if "--usepkg" in self.myopts:
- db_keys = list(bindb._aux_cache_keys)
- dbs.append((bindb, "binary", True, False, db_keys))
- db_keys = list(trees[myroot]["vartree"].dbapi._aux_cache_keys)
- dbs.append((vardb, "installed", True, True, db_keys))
- dynamic_config._filtered_trees[myroot]["dbs"] = dbs
- if "--usepkg" in self.myopts:
- self.trees[myroot]["bintree"].populate(
- "--getbinpkg" in self.myopts,
- "--getbinpkgonly" in self.myopts)
- del trees
self._required_set_names = set(["system", "world"])
class _dynamic_depgraph_config(object):
- def __init__(self, myparams):
+ def __init__(self, depgraph, myparams):
self.myparams = myparams
# Maps slot atom to package for each Package added to the graph.
self._slot_pkg_map = {}
# Contains a filtered view of preferred packages that are selected
# from available repositories.
self._filtered_trees = {}
- # All Package instances
- self._pkg_cache = {}
+ # Contains installed packages and new packages that have been added
+ # to the graph.
+ self._graph_trees = {}
+ # Caches visible packages returned from _select_package, for use in
+ # depgraph._iter_atoms_for_pkg() SLOT logic.
+ self._visible_pkgs = {}
#contains the args created by select_files
self._initial_arg_list = []
self.digraph = portage.digraph()
self._ignored_deps = []
self._highest_pkg_cache = {}
+ for myroot in depgraph._frozen_config.trees:
+ self._slot_pkg_map[myroot] = {}
+ vardb = depgraph._frozen_config.trees[myroot]["vartree"].dbapi
+ preload_installed_pkgs = \
+ "--nodeps" not in depgraph._frozen_config.myopts and \
+ "--buildpkgonly" not in depgraph._frozen_config.myopts
+ # This fakedbapi instance will model the state that the vdb will
+ # have after new packages have been installed.
+ fakedb = PackageVirtualDbapi(vardb.settings)
+ if preload_installed_pkgs:
+ for pkg in vardb:
+ depgraph._frozen_config.spinner.update()
+ # This triggers metadata updates via FakeVartree.
+ vardb.aux_get(pkg.cpv, [])
+ fakedb.cpv_inject(pkg)
+
+ # Now that the vardb state is cached in our FakeVartree,
+ # we won't be needing the real vartree cache for awhile.
+ # To make some room on the heap, clear the vardbapi
+ # caches.
+ depgraph._frozen_config._trees_orig[myroot
+ ]["vartree"].dbapi._clear_cache()
+ gc.collect()
+
+ self.mydbapi[myroot] = fakedb
+ def graph_tree():
+ pass
+ graph_tree.dbapi = fakedb
+ self._graph_trees[myroot] = {}
+ self._filtered_trees[myroot] = {}
+ # Substitute the graph tree for the vartree in dep_check() since we
+ # want atom selections to be consistent with package selections
+ # have already been made.
+ self._graph_trees[myroot]["porttree"] = graph_tree
+ self._graph_trees[myroot]["vartree"] = graph_tree
+ def filtered_tree():
+ pass
+ filtered_tree.dbapi = _dep_check_composite_db(depgraph, myroot)
+ self._filtered_trees[myroot]["porttree"] = filtered_tree
+ self._visible_pkgs[myroot] = PackageVirtualDbapi(vardb.settings)
+
+ # Passing in graph_tree as the vartree here could lead to better
+ # atom selections in some cases by causing atoms for packages that
+ # have been added to the graph to be preferred over other choices.
+ # However, it can trigger atom selections that result in
+ # unresolvable direct circular dependencies. For example, this
+ # happens with gwydion-dylan which depends on either itself or
+ # gwydion-dylan-bin. In case gwydion-dylan is not yet installed,
+ # gwydion-dylan-bin needs to be selected in order to avoid a
+ # an unresolvable direct circular dependency.
+ #
+ # To solve the problem described above, pass in "graph_db" so that
+ # packages that have been added to the graph are distinguishable
+ # from other available packages and installed packages. Also, pass
+ # the parent package into self._select_atoms() calls so that
+ # unresolvable direct circular dependencies can be detected and
+ # avoided when possible.
+ self._filtered_trees[myroot]["graph_db"] = graph_tree.dbapi
+ self._filtered_trees[myroot]["vartree"] = \
+ depgraph._frozen_config.trees[myroot]["vartree"]
+
+ dbs = []
+ portdb = depgraph._frozen_config.trees[myroot]["porttree"].dbapi
+ bindb = depgraph._frozen_config.trees[myroot]["bintree"].dbapi
+ vardb = depgraph._frozen_config.trees[myroot]["vartree"].dbapi
+ # (db, pkg_type, built, installed, db_keys)
+ if "--usepkgonly" not in depgraph._frozen_config.myopts:
+ db_keys = list(portdb._aux_cache_keys)
+ dbs.append((portdb, "ebuild", False, False, db_keys))
+ if "--usepkg" in depgraph._frozen_config.myopts:
+ db_keys = list(bindb._aux_cache_keys)
+ dbs.append((bindb, "binary", True, False, db_keys))
+ db_keys = list(depgraph._frozen_config._trees_orig[myroot
+ ]["vartree"].dbapi._aux_cache_keys)
+ dbs.append((vardb, "installed", True, True, db_keys))
+ self._filtered_trees[myroot]["dbs"] = dbs
+ if "--usepkg" in depgraph._frozen_config.myopts:
+ depgraph._frozen_config._trees_orig[myroot
+ ]["bintree"].populate(
+ "--getbinpkg" in depgraph._frozen_config.myopts,
+ "--getbinpkgonly" in depgraph._frozen_config.myopts)
class depgraph(object):
_dep_keys = ["DEPEND", "RDEPEND", "PDEPEND"]
- def __init__(self, settings, trees, myopts, myparams, spinner):
- self._dynamic_config = _dynamic_depgraph_config(myparams)
- self._frozen_config = _frozen_depgraph_config(settings, trees, \
- myopts, spinner, self._dynamic_config, self)
-
+ def __init__(self, settings, trees, myopts, myparams, spinner,
+ frozen_config=None):
+ if frozen_config is None:
+ frozen_config = _frozen_depgraph_config(settings, trees,
+ myopts, spinner)
+ self._frozen_config = frozen_config
+ self._dynamic_config = _dynamic_depgraph_config(self, myparams)
+
self._select_atoms = self._select_atoms_highest_available
self._select_package = self._select_pkg_highest_available
if atom_cp != pkg.cp and \
self._have_new_virt(pkg.root, atom_cp):
continue
- visible_pkgs = root_config.visible_pkgs.match_pkgs(atom)
+ visible_pkgs = \
+ self._dynamic_config._visible_pkgs[pkg.root].match_pkgs(atom)
visible_pkgs.reverse() # descending order
higher_slot = None
for visible_pkg in visible_pkgs:
os.path.realpath(self._frozen_config.trees[myroot]["bintree"].getname(mykey)):
print colorize("BAD", "\n*** You need to adjust PKGDIR to emerge this package.\n")
return 0, myfavorites
- db_keys = list(bindb._aux_cache_keys)
- metadata = izip(db_keys, bindb.aux_get(mykey, db_keys))
- pkg = Package(type_name="binary", root_config=root_config,
- cpv=mykey, built=True, metadata=metadata,
+
+ pkg = self._pkg(mykey, "binary", root_config,
onlydeps=onlydeps)
- self._dynamic_config._pkg_cache[pkg] = pkg
args.append(PackageArg(arg=x, package=pkg,
root_config=root_config))
elif ext==".ebuild":
else:
raise portage.exception.PackageNotFound(
"%s is not in a valid portage tree hierarchy or does not exist" % x)
- db_keys = list(portdb._aux_cache_keys)
- metadata = izip(db_keys, portdb.aux_get(mykey, db_keys))
- pkg = Package(type_name="ebuild", root_config=root_config,
- cpv=mykey, metadata=metadata, onlydeps=onlydeps)
- self._dynamic_config._pkg_cache[pkg] = pkg
+ pkg = self._pkg(mykey, "ebuild", root_config,
+ onlydeps=onlydeps)
args.append(PackageArg(arg=x, package=pkg,
root_config=root_config))
elif x.startswith(os.path.sep):
portage.writemsg("\n", noiselevel=-1)
# Order needs to be preserved since a feature of --nodeps
# is to allow the user to force a specific merge order.
- args.reverse()
self._dynamic_config._initial_arg_list = args[:]
return self._resolve(myfavorites)
added to the graph or those that are installed and have
not been scheduled for replacement.
"""
- kwargs["trees"] = self._frozen_config._graph_trees
+ kwargs["trees"] = self._dynamic_config._graph_trees
return self._select_atoms_highest_available(*pargs, **kwargs)
def _select_atoms_highest_available(self, root, depstring,
settings = pkg.root_config.settings
if visible(settings, pkg) and not (pkg.installed and \
settings._getMissingKeywords(pkg.cpv, pkg.metadata)):
- pkg.root_config.visible_pkgs.cpv_inject(pkg)
+ self._dynamic_config._visible_pkgs[pkg.root].cpv_inject(pkg)
return ret
def _select_pkg_highest_available_imp(self, root, atom, onlydeps=False):
those that are installed and have not been scheduled for
replacement.
"""
- graph_db = self._frozen_config._graph_trees[root]["porttree"].dbapi
+ graph_db = self._dynamic_config._graph_trees[root]["porttree"].dbapi
matches = graph_db.match_pkgs(atom)
if not matches:
return None, None
operation = "merge"
if installed or onlydeps:
operation = "nomerge"
- pkg = self._dynamic_config._pkg_cache.get(
+ pkg = self._frozen_config._pkg_cache.get(
(type_name, root_config.root, cpv, operation))
if pkg is None and onlydeps and not installed:
# Maybe it already got pulled in as a "merge" node.
pkg = Package(built=(type_name != "ebuild"), cpv=cpv,
installed=installed, metadata=metadata,
root_config=root_config, type_name=type_name)
- self._dynamic_config._pkg_cache[pkg] = pkg
+ self._frozen_config._pkg_cache[pkg] = pkg
return pkg
def _validate_blockers(self):
try:
success, atoms = portage.dep_check(depstr,
final_db, pkgsettings, myuse=pkg.use.enabled,
- trees=self._frozen_config._graph_trees, myroot=myroot)
+ trees=self._dynamic_config._graph_trees, myroot=myroot)
except Exception, e:
if isinstance(e, SystemExit):
raise
operation="uninstall",
root_config=inst_pkg.root_config,
type_name=inst_pkg.type_name)
- self._dynamic_config._pkg_cache[uninst_task] = uninst_task
# Enforce correct merge order with a hard dep.
self._dynamic_config.digraph.addnode(uninst_task, inst_task,
priority=BlockerDepPriority.instance)
continue
root_config = self._frozen_config.roots[task.root]
- inst_pkg = self._dynamic_config._pkg_cache[
- ("installed", task.root, task.cpv, "nomerge")]
+ inst_pkg = self._pkg(task.cpv, "installed", root_config,
+ installed=True)
if self._dynamic_config.digraph.contains(inst_pkg):
continue
# Remove the corresponding "nomerge" node and substitute
# the Uninstall node.
- inst_pkg = self._dynamic_config._pkg_cache[
- ("installed", uninstall.root, uninstall.cpv, "nomerge")]
+ inst_pkg = self._pkg(uninstall.cpv, "installed",
+ uninstall.root_config, installed=True)
+
try:
mygraph.remove(inst_pkg)
except KeyError:
continue
if action != "merge":
continue
- tree_type = self.pkg_tree_map[pkg_type]
- mydb = trees[myroot][tree_type].dbapi
- db_keys = list(self._frozen_config._trees_orig[myroot][
- tree_type].dbapi._aux_cache_keys)
+ root_config = self._frozen_config.roots[myroot]
try:
- metadata = izip(db_keys, mydb.aux_get(pkg_key, db_keys))
- except KeyError:
+ pkg = self._pkg(pkg_key, pkg_type, root_config)
+ except portage.exception.PackageNotFound:
# It does no exist or it is corrupt.
- if action == "uninstall":
- continue
if skip_missing:
# TODO: log these somewhere
continue
- raise portage.exception.PackageNotFound(pkg_key)
- installed = action == "uninstall"
- built = pkg_type != "ebuild"
- root_config = self._frozen_config.roots[myroot]
- pkg = Package(built=built, cpv=pkg_key,
- installed=installed, metadata=metadata,
- operation=action, root_config=root_config,
- type_name=pkg_type)
- self._dynamic_config._pkg_cache[pkg] = pkg
+ raise
- root_config = self._frozen_config.roots[pkg.root]
if "merge" == pkg.operation and \
not visible(root_config.settings, pkg):
if skip_masked:
skip_unsatisfied = True
mergelist = mtimedb["resume"]["mergelist"]
dropped_tasks = set()
+ frozen_config = _frozen_depgraph_config(settings, trees,
+ myopts, spinner)
while True:
mydepgraph = depgraph(settings, trees,
- myopts, myparams, spinner)
+ myopts, myparams, spinner, frozen_config=frozen_config)
try:
success = mydepgraph._loadResumeCommand(mtimedb["resume"],
skip_masked=skip_masked)