| Index: parallel_emerge
|
| diff --git a/parallel_emerge b/parallel_emerge
|
| index 6516c29f5ece1a7080a582825fa30f4e59a6c2fc..930f53dcd6f1982d92000cb2a74421378182ecb8 100755
|
| --- a/parallel_emerge
|
| +++ b/parallel_emerge
|
| @@ -76,7 +76,8 @@ if "PORTAGE_USERNAME" not in os.environ:
|
| from _emerge.actions import adjust_configs
|
| from _emerge.actions import load_emerge_config
|
| from _emerge.create_depgraph_params import create_depgraph_params
|
| -from _emerge.depgraph import backtrack_depgraph
|
| +from _emerge.depgraph import depgraph as emerge_depgraph
|
| +from _emerge.depgraph import _frozen_depgraph_config
|
| from _emerge.main import emerge_main
|
| from _emerge.main import parse_opts
|
| from _emerge.Package import Package
|
| @@ -479,24 +480,9 @@ class DepGraphGenerator(object):
|
| cur_iuse, now_use, now_iuse)
|
| return not flags
|
|
|
| - def GenDependencyTree(self, remote_pkgs):
|
| - """Get dependency tree info from emerge.
|
| -
|
| - TODO(): Update cros_extract_deps to also use this code.
|
| - Returns:
|
| - Dependency tree
|
| - """
|
| - start = time.time()
|
| -
|
| + def CreateDepgraph(self, emerge, packages):
|
| + """Create an emerge depgraph object."""
|
| # Setup emerge options.
|
| - #
|
| - # We treat dependency info a bit differently than emerge itself. Unless
|
| - # you're using --usepkgonly, we disable --getbinpkg and --usepkg here so
|
| - # that emerge will look at the dependencies of the source ebuilds rather
|
| - # than the binary dependencies. This helps ensure that we have the option
|
| - # of merging a package from source, if we want to switch to it with
|
| - # --workon and the dependencies have changed.
|
| - emerge = self.emerge
|
| emerge_opts = emerge.opts.copy()
|
|
|
| # Enable --emptytree so that we get the full tree, which we need for
|
| @@ -507,12 +493,86 @@ class DepGraphGenerator(object):
|
| emerge_opts["--tree"] = True
|
| emerge_opts["--emptytree"] = True
|
|
|
| - # Tell emerge not to worry about use flags yet. We handle those inside
|
| - # parallel_emerge itself. Further, when we use the --force-remote-binary
|
| - # flag, we don't emerge to reject a package just because it has different
|
| - # use flags.
|
| - emerge_opts.pop("--newuse", None)
|
| - emerge_opts.pop("--reinstall", None)
|
| + # Set up parameters.
|
| + params = create_depgraph_params(emerge_opts, emerge.action)
|
| + frozen_config = _frozen_depgraph_config(emerge.settings, emerge.trees,
|
| + emerge_opts, emerge.spinner)
|
| + backtrack_max = emerge_opts.get('--backtrack', 5)
|
| + runtime_pkg_mask = None
|
| + allow_backtracking = backtrack_max > 0
|
| +
|
| + # Try up to backtrack_max times to create a working depgraph. Each time we
|
| + # run into a conflict, mask the offending package and try again.
|
| + # TODO(davidjames): When Portage supports --force-remote-binary directly,
|
| + # switch back to using the backtrack_depgraph function.
|
| + for i in range(backtrack_max + 1):
|
| + if i == backtrack_max:
|
| + # Looks like we hit the backtracking limit. Run the dependency
|
| + # calculation one more time (from scratch) to show the original error
|
| + # message.
|
| + runtime_pkg_mask = None
|
| + allow_backtracking = False
|
| +
|
| + # Create a depgraph object.
|
| + depgraph = emerge_depgraph(emerge.settings, emerge.trees, emerge_opts,
|
| + params, emerge.spinner, frozen_config=frozen_config,
|
| + allow_backtracking=allow_backtracking,
|
| + runtime_pkg_mask=runtime_pkg_mask)
|
| +
|
| + if i == 0:
|
| + for cpv in self.forced_remote_binary_packages:
|
| + # If --force-remote-binary was specified, we want to use this package
|
| + # regardless of its use flags. Unfortunately, Portage doesn't support
|
| + # ignoring use flags for just one package. To convince Portage to
|
| + # install the package, we trick Portage into thinking the package has
|
| + # the right use flags.
|
| + # TODO(davidjames): Update Portage to support --force-remote-binary
|
| + # directly, so that this hack isn't necessary.
|
| + pkg = depgraph._pkg(cpv, "binary", emerge.root_config)
|
| + pkgsettings = frozen_config.pkgsettings[pkg.root]
|
| + pkgsettings.setcpv(pkg)
|
| + pkg.use.enabled = pkgsettings["PORTAGE_USE"].split()
|
| +
|
| + # Select the packages we want.
|
| + success, favorites = depgraph.select_files(packages)
|
| + if success:
|
| + break
|
| + elif depgraph.need_restart():
|
| + # Looks like we found some packages that can't be installed due to
|
| + # conflicts. Try again, masking out the conflicting packages.
|
| + runtime_pkg_mask = depgraph.get_runtime_pkg_mask()
|
| + elif allow_backtracking and i > 0:
|
| + # Looks like we tried all the possible combinations, and we still can't
|
| + # solve the graph. Stop backtracking, so that we can report an error
|
| + # message.
|
| + runtime_pkg_mask = None
|
| + allow_backtracking = False
|
| + else:
|
| + break
|
| +
|
| + # Delete the --tree option, because we don't really want to display a
|
| + # tree. We just wanted to get emerge to leave uninstall instructions on
|
| + # the graph. Later, when we display the graph, we'll want standard-looking
|
| + # output, so removing the --tree option is important.
|
| + frozen_config.myopts.pop("--tree", None)
|
| +
|
| + emerge.depgraph = depgraph
|
| +
|
| + # Is it impossible to honor the user's request? Bail!
|
| + if not success:
|
| + depgraph.display_problems()
|
| + sys.exit(1)
|
| +
|
| + def GenDependencyTree(self, remote_pkgs):
|
| + """Get dependency tree info from emerge.
|
| +
|
| + TODO(): Update cros_extract_deps to also use this code.
|
| + Returns:
|
| + Dependency tree
|
| + """
|
| + start = time.time()
|
| +
|
| + emerge = self.emerge
|
|
|
| # Create a list of packages to merge
|
| packages = set(emerge.cmdline_packages[:])
|
| @@ -527,9 +587,17 @@ class DepGraphGenerator(object):
|
| full_pkgname in self.force_remote_binary):
|
| forced_pkgs.setdefault(full_pkgname, []).append(pkg)
|
|
|
| + # Add forced binary packages to the dependency list. This is necessary
|
| + # to ensure that the install plan contains the right package.
|
| + #
|
| + # Putting the forced binary package at the beginning of the list is an
|
| + # optimization that helps avoid unnecessary backtracking (e.g., if
|
| + # Portage first selects the wrong version, and then backtracks later, it
|
| + # takes a bit longer and uses up an unnecessary backtrack iteration.)
|
| + packages = list(packages)
|
| for pkgs in forced_pkgs.values():
|
| forced_package = portage.versions.best(pkgs)
|
| - packages.add("=%s" % forced_package)
|
| + packages.insert(0, "=%s" % forced_package)
|
| self.forced_remote_binary_packages.add(forced_package)
|
|
|
| # Tell emerge to be quiet. We print plenty of info ourselves so we don't
|
| @@ -544,18 +612,8 @@ class DepGraphGenerator(object):
|
| if "--quiet" not in emerge.opts:
|
| print "Calculating deps..."
|
|
|
| - # Ask portage to build a dependency graph. with the options we specified
|
| - # above.
|
| - params = create_depgraph_params(emerge_opts, emerge.action)
|
| - success, depgraph, _ = backtrack_depgraph(
|
| - emerge.settings, emerge.trees, emerge_opts, params, emerge.action,
|
| - packages, emerge.spinner)
|
| - emerge.depgraph = depgraph
|
| -
|
| - # Is it impossible to honor the user's request? Bail!
|
| - if not success:
|
| - depgraph.display_problems()
|
| - sys.exit(1)
|
| + self.CreateDepgraph(emerge, packages)
|
| + depgraph = emerge.depgraph
|
|
|
| # Build our own tree from the emerge digraph.
|
| deps_tree = {}
|
| @@ -604,11 +662,6 @@ class DepGraphGenerator(object):
|
| vardb = frozen_config.trees[root]["vartree"].dbapi
|
| pkgsettings = frozen_config.pkgsettings[root]
|
|
|
| - # It's time to start worrying about use flags, if necessary.
|
| - for flag in ("--newuse", "--reinstall"):
|
| - if flag in emerge.opts:
|
| - emerge_opts[flag] = emerge.opts[flag]
|
| -
|
| deps_info = {}
|
| for pkg in depgraph.altlist():
|
| if isinstance(pkg, Package):
|
| @@ -636,12 +689,6 @@ class DepGraphGenerator(object):
|
| deps_info[str(pkg.cpv)] = {"idx": len(deps_info),
|
| "optional": optional}
|
|
|
| - # Delete the --tree option, because we don't really want to display a
|
| - # tree. We just wanted to get emerge to leave uninstall instructions on
|
| - # the graph. Later, when we display the graph, we'll want standard-looking
|
| - # output, so removing the --tree option is important.
|
| - frozen_config.myopts.pop("--tree", None)
|
| -
|
| seconds = time.time() - start
|
| if "--quiet" not in emerge.opts:
|
| print "Deps calculated in %dm%.1fs" % (seconds / 60, seconds % 60)
|
|
|