Index: parallel_emerge |
diff --git a/parallel_emerge b/parallel_emerge |
index f9576f6e7568fb11159232fa2ce9add9971e5293..192cb8afbf9b5906c848e0d2a11e28569c88a66f 100755 |
--- a/parallel_emerge |
+++ b/parallel_emerge |
@@ -406,6 +406,49 @@ class DepGraphGenerator(object): |
root = settings["ROOT"] |
emerge.root_config = trees[root]["root_config"] |
+ def CheckUseFlags(self, pkgsettings, cur_pkg, new_pkg): |
+ """Are the use flags in cur_pkg up to date? |
+ |
+ Return True if use flags are up to date; return false otherwise.""" |
+ |
+ # cur_use: The set of flags that were enabled when the package was |
+ # first installed. |
+ # cur_iuse: The set of flags that affected the specified package |
+ # when it was first installed. |
+ # |
+ # The intersection of cur_use and cur_iuse provides the set of |
+ # flags that were enabled and affected the specified package. |
+ cur_use = cur_pkg.use.enabled |
+ cur_iuse = cur_pkg.iuse.all |
+ |
+ # Check whether this package is already installed with the right use |
+ # flags. |
+ # |
+ # now_use: The set of flags (special and non-special) that are now |
+ # enabled for the specified package. |
+ # now_iuse: The set of non-special flags that affect the specified |
+ # package. |
+ now_use = new_pkg.use.enabled |
+ now_iuse = new_pkg.iuse.all |
+ |
+ # Tell portage we want to lookup the flags for the specified package |
+ # in package.use.{mask,force} |
+ pkgsettings.setcpv(new_pkg.cpv) |
+ |
+ # Grab the set of flags that are requested for the given package. |
+ # This includes flags that don't affect the package, and includes |
+ # all sources of flags (e.g. USE environment variable, make.conf, |
+ # make.defaults, package.use.{mask,force}, etc.). |
+ # |
+ # This is used by portage in the _reinstall_for_flags function below. |
+ forced_flags = set(pkgsettings.useforce).union(pkgsettings.usemask) |
+ |
+ depgraph = self.emerge.depgraph |
+ |
+ flags = depgraph._reinstall_for_flags(forced_flags, cur_use, |
+ cur_iuse, now_use, now_iuse) |
+ return not flags |
+ |
def GenDependencyTree(self): |
"""Get dependency tree info from emerge. |
@@ -509,7 +552,10 @@ class DepGraphGenerator(object): |
# versions of packages that we're either upgrading or replacing. |
# |
# The "vardb" is the database of installed packages. |
- vardb = emerge.trees[emerge.settings["ROOT"]]["vartree"].dbapi |
+ root = emerge.settings["ROOT"] |
+ frozen_config = depgraph._frozen_config |
+ vardb = frozen_config.trees[root]["vartree"].dbapi |
+ pkgsettings = frozen_config.pkgsettings[root] |
deps_info = {} |
for pkg in depgraph.altlist(): |
if isinstance(pkg, Package): |
@@ -517,8 +563,11 @@ class DepGraphGenerator(object): |
# that is already installed, then this operation is possibly optional. |
# ("--selective" mode is handled later, in RemoveInstalledPackages()) |
optional = False |
- if not emptytree and vardb.cpv_exists(pkg.cpv): |
- optional = True |
+ if not emptytree: |
+ for vardb_pkg in vardb.match_pkgs(pkg.cpv): |
+ if self.CheckUseFlags(pkgsettings, vardb_pkg, pkg): |
+ optional = True |
+ break |
# Add the package to our database. |
self.package_db[str(pkg.cpv)] = pkg |
@@ -531,7 +580,7 @@ class DepGraphGenerator(object): |
# 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. |
- depgraph._frozen_config.myopts.pop("--tree", None) |
+ frozen_config.myopts.pop("--tree", None) |
seconds = time.time() - start |
if "--quiet" not in emerge.opts: |
@@ -575,8 +624,8 @@ class DepGraphGenerator(object): |
final_pkgs = set() |
# These packages take a really long time to build, so, for expediency, we |
- # are blacklisting them from automatic rebuilds. Instead, these packages |
- # will only be rebuilt when they are explicitly rev'd. |
+ # are blacklisting them from automatic rebuilds because one of their |
+ # dependencies needs to be recompiled. |
rebuild_blacklist = set() |
for pkg in ("media-plugins/o3d", "dev-java/icedtea"): |
for match in final_db.match_pkgs(pkg): |
@@ -696,7 +745,10 @@ class DepGraphGenerator(object): |
if "--selective" in emerge.opts: |
selective = emerge.opts["--selective"] != "n" |
else: |
- selective = "--noreplace" in emerge.opts or "--update" in emerge.opts |
+ selective = ("--noreplace" in emerge.opts or |
+ "--update" in emerge.opts or |
+ "--newuse" in emerge.opts or |
+ "--reinstall" in emerge.opts) |
onlydeps = "--onlydeps" in emerge.opts |
if not selective: |
for pkg in emerge.cmdline_packages: |
@@ -811,14 +863,13 @@ class DepGraphGenerator(object): |
"""Merge this package and all packages it provides.""" |
this_pkg = deps_map[pkg] |
- if (this_pkg[merge_type] or pkg not in final_pkgs or |
- pkg in rebuild_blacklist): |
+ if (this_pkg[merge_type] or pkg not in final_pkgs): |
return |
# Mark this package as non-optional |
deps_info[pkg]["optional"] = False |
this_pkg[merge_type] = True |
- for w in this_pkg["provides"]: |
+ for w in this_pkg["provides"].difference(rebuild_blacklist): |
MergeChildren(w, merge_type) |
if this_pkg["action"] == "nomerge": |
@@ -958,7 +1009,7 @@ class DepGraphGenerator(object): |
local_mtime = LastModifiedWithDeps(pkg, local_pkgs, local_mtime_cache) |
local_ready = PrebuiltsReady(pkg, local_pkgs, local_ready_cache) |
if (not local_ready or local_pkgs.get(pkg, 0) < local_mtime and |
- pkg not in cycles): |
+ pkg not in cycles and pkg not in rebuild_blacklist): |
# OK, at least one package is missing from the local cache or is |
# outdated. This means we're going to have to install the package |
# and all dependencies. |
@@ -983,13 +1034,14 @@ class DepGraphGenerator(object): |
bintree = emerge.trees[root]["bintree"] |
bindb = bintree.dbapi |
root_config = emerge.root_config |
+ pkgsettings = emerge.depgraph._frozen_config.pkgsettings[root] |
prebuilt_pkgs = {} |
# Populate the DB with packages |
bintree.populate("--getbinpkg" in emerge.opts, |
"--getbinpkgonly" in emerge.opts) |
- # Update packages that can use prebuilts to do so. |
+ # Build list of prebuilt packages |
for pkg, info in deps_map.iteritems(): |
if info and not info["mandatory_source"] and info["action"] == "merge": |
db_keys = list(bindb._aux_cache_keys) |
@@ -1004,7 +1056,19 @@ class DepGraphGenerator(object): |
metadata=metadata, onlydeps=False, mtime=mtime, |
operation="merge", root_config=root_config, |
type_name="binary") |
- self.package_db[pkg] = db_pkg |
+ prebuilt_pkgs[pkg] = db_pkg |
+ |
+ # Calculate what packages need to be rebuilt due to changes in use flags. |
+ for pkg, db_pkg in prebuilt_pkgs.iteritems(): |
+ db_pkg_src = self.package_db[pkg] |
+ if not self.CheckUseFlags(pkgsettings, db_pkg, db_pkg_src): |
+ MergeChildren(pkg, "mandatory_source") |
+ |
+ # Convert eligible packages to binaries. |
+ for pkg, info in deps_map.iteritems(): |
+ if (info and not info["mandatory_source"] and |
+ info["action"] == "merge" and pkg in prebuilt_pkgs): |
+ self.package_db[pkg] = prebuilt_pkgs[pkg] |
seconds = time.time() - start |
if "--quiet" not in emerge.opts: |