Merged from trunk 9831:9860
authorFabian Groffen <grobian@gentoo.org>
Sun, 13 Apr 2008 09:42:21 +0000 (09:42 -0000)
committerFabian Groffen <grobian@gentoo.org>
Sun, 13 Apr 2008 09:42:21 +0000 (09:42 -0000)
   | 9832    | In config.setcpv() and load_infodir(), always set known good |
   | zmedico | values for CATEGORY and PF, since corruption of these can    |
   |         | cause problems.                                              |

   | 9834    | Remove all calls to config.load_infodir() since it doesn't   |
   | zmedico | seem to server any purpose now that the complete environment |
   |         | is loaded from environment.bz2.                              |

   | 9835    | Remove unused infodir variable.                              |
   | zmedico |                                                              |

   | 9837    | Make doebuild() bail out early with a PermissionDenied error |
   | zmedico | if there is no write access to $PKGDIR.                      |

   | 9839    | When dep_check() expands new-style virtuals, use USE flags   |
   | zmedico | from aux_get calls to evaluate any conditionals that the     |
   |         | depstrings might contain. This works properly for ebuilds    |
   |         | now that aux_get() is backed by Package instances containing |
   |         | the correct USE.                                             |

   | 9840    | Fix the code from the previous commit so that it doesn't try |
   | zmedico | to pull USE from a portdbapi instance (like when called by   |
   |         | repoman) since portdbapi doesn't return USE in aux_get()     |
   |         | calls.                                                       |

   | 9842    | Fix 'undefined name' errors found by pyflakes.               |
   | zmedico |                                                              |

   | 9844    | Make file_get() redirect FETCHCOMMAND output to stdout just  |
   | zmedico | like portage.fetch() does. Thanks to Ramereth for reporting. |

   | 9846    | Rename the undocumented --conistent option to                |
   | zmedico | --complete-graph and add some docs.                          |

   | 9848    | Add some notes for the parallel-fetch feature and the new    |
   | zmedico | --complete-graph option for emerge.                          |

   | 9850    | Make binarytree.prevent_collision() adjust permissions on    |
   | zmedico | directories and raise a PermissionDenied error if the        |
   |         | required directories is not writable.                        |

   | 9852    | Bug #215016 - When transforming of USE flags to USE_EXPAND   |
   | zmedico | variables, filter out flags that aren't considered to be     |
   |         | part of IUSE or implicit IUSE. This patch moves all IUSE     |
   |         | dependent code from config.regenerate() to config.setcpv().  |

   | 9854    | * Optimize config.setcpv() to return early if IUSE has not   |
   | zmedico | changed since the previous setcpv() call. * Add EBUILD_PHASE |
   |         | to the blacklisted variables list.                           |

   | 9856    | Bug #217444 - Send debug-print() output to stderr so that it |
   | zmedico | can't interfere with command substitution. Thanks to Fabio   |
   |         | Rossi <rossi.f@inwind.it> for this patch.                    |

   | 9858    | Fix the filtering for bug #215016: * fix broken comparison   |
   | zmedico | for he iuse filtering * filter out any duplicates that       |
   |         | variable may contain                                         |

   | 9860    | In --buildpkgonly mode, don't discard RDEPEND and PDEPEND if |
   | zmedico | --empty or --deep are enabled. The makes it possible to run  |
   |         | `emerge -eB world` and have every single package rebuilt     |
   |         | (without actually installing anything).                      |

svn path=/main/branches/prefix/; revision=9868

RELEASE-NOTES
bin/ebuild.sh
man/emerge.1
man/make.conf.5
pym/_emerge/__init__.py
pym/_emerge/help.py
pym/portage/__init__.py
pym/portage/dbapi/bintree.py
pym/portage/getbinpkg.py

index c107bbce3dc0da24613b44730a9972360857d461..4b57835f109bcba34abaee746d3b21770e875b62 100644 (file)
@@ -32,6 +32,23 @@ portage-2.2
 * "world" does no longer include "system" unconditionally, but you can add
   "@system" to the worldfile to restore the old state.
 
+portage-2.1.5
+==================================
+
+* The parallel-fetch feature is now enabled by default. It is optimized
+  to avoid doing redundant checksums for previously downloaded files that have
+  the correct size. Run `tail -f /var/log/emerge-fetch.log` in a
+  terminal to view parallel-fetch progress. Add FEATURES="-parallel-fetch"
+  to /etc/make.conf if you want to disable this feature.
+
+* For extra careful dependency handling, emerge has a new --complete-graph
+  option that causes it to consider the deep dependencies of all packages from
+  the system and world sets. With this option enabled, emerge will bail out
+  if it determines that the given operation will break any dependencies of
+  the packages that have been added to the graph. Unlike the --deep option,
+  the --complete-graph option does not cause any more packages to be updated
+  than would have otherwise been updated with the option disabled.
+
 portage-2.1.4.1
 ==================================
 
index 54e1904d6afdcfa2e378fd9b06d202f34c83ed46..064f5313deef2e969c135e0d88a23f3885e92f2a 100755 (executable)
@@ -1124,7 +1124,7 @@ debug-print() {
 
                # extra user-configurable targets
                if [ "$ECLASS_DEBUG_OUTPUT" == "on" ]; then
-                       echo "debug: $1"
+                       echo "debug: $1" >&2
                elif [ -n "$ECLASS_DEBUG_OUTPUT" ]; then
                        echo "debug: $1" >> $ECLASS_DEBUG_OUTPUT
                fi
index 6df5af075e7550476c3d2a7ac63e69cf6e012ccc..90786156cba1158c4ca280c604880546dbbc70d0 100644 (file)
@@ -248,6 +248,17 @@ is not a tty (by default, color is disabled unless stdout is a tty).
 Used alongside \fB\-\-pretend\fR to cause the package name, new version, 
 and old version to be displayed in an aligned format for easy cut\-n\-paste.
 .TP
+.BR "\-\-complete\-graph"
+This causes \fBemerge\fR to consider the deep dependencies of all
+packages from the system and world sets. With this option enabled,
+\fBemerge\fR will bail out if it determines that the given operation will
+break any dependencies of the packages that have been added to the
+graph. Like the \fB\-\-deep\fR option, the \fB\-\-complete\-graph\fR
+option will significantly increase the time taken for dependency
+calculations. Note that, unlike the \fB\-\-deep\fR option, the
+\fB\-\-complete\-graph\fR option does not cause any more packages to
+be updated than would have otherwise been updated with the option disabled.
+.TP
 .BR \-\-config\-root=DIR
 Set the \fBPORTAGE_CONFIGROOT\fR environment variable.
 .TP
index 90e419afc8220ac5aedb2e5124ffe9e064daad95..4976ebe4d2ba97f0799617709a2eb0c2c0ec2035 100644 (file)
@@ -242,7 +242,9 @@ Prevents the stripping of binaries that are merged to the live filesystem.
 Disables xterm titlebar updates (which contains status info).
 .TP
 .B parallel\-fetch
-Fetch in the background while compiling.
+Fetch in the background while compiling. Run
+`tail \-f /var/log/emerge\-fetch.log` in a
+terminal to view parallel-fetch progress.
 .TP
 .B sandbox
 Enable sandbox\-ing when running \fBemerge\fR(1) and \fBebuild\fR(1).
index 7045c2448bf7e731f59a5da75e9ba33b590fd390..b228ce28d37f5275828573c9f038cc3c811462c1 100644 (file)
@@ -203,7 +203,7 @@ options=[
 "--ask",          "--alphabetical",
 "--buildpkg",     "--buildpkgonly",
 "--changelog",    "--columns",
-"--consistent",
+"--complete-graph",
 "--debug",        "--deep",
 "--digest",
 "--emptytree",
@@ -390,7 +390,7 @@ def create_depgraph_params(myopts, myaction):
                myparams.discard("recurse")
        if "--deep" in myopts:
                myparams.add("deep")
-       if "--consistent" in myopts:
+       if "--complete-graph" in myopts:
                myparams.add("consistent")
        return myparams
 
@@ -2026,10 +2026,12 @@ class depgraph(object):
                for k in depkeys:
                        edepend[k] = metadata[k]
 
-               if mytype == "ebuild":
-                       if "--buildpkgonly" in self.myopts:
-                               edepend["RDEPEND"] = ""
-                               edepend["PDEPEND"] = ""
+               if not pkg.built and \
+                       "--buildpkgonly" in self.myopts and \
+                       "deep" not in self.myparams and \
+                       "empty" not in self.myparams:
+                       edepend["RDEPEND"] = ""
+                       edepend["PDEPEND"] = ""
                bdeps_satisfied = False
                if mytype in ("installed", "binary"):
                        if self.myopts.get("--with-bdeps", "n") == "y":
@@ -2867,7 +2869,7 @@ class depgraph(object):
                intially satisfied.
 
                Since this method can consume enough time to disturb users, it is
-               currently only enabled by the --consistent option.
+               currently only enabled by the --complete-graph option.
                """
                if "consistent" not in self.myparams:
                        # Skip this to avoid consuming enough time to disturb users.
index 4c7505da170d5011dca6abc21a68a73534a16ab6..b6bc541cd7b37743ad5c24a9a4e3ff90fdd33c06 100644 (file)
@@ -17,7 +17,7 @@ def shorthelp():
        print bold("Options:")+" "+green("-")+"["+green("abBcCdDefgGhkKlnNoOpqPsStuvV")+"] ["+green("--oneshot")+"] ["+green("--newuse")+"] ["+green("--noconfmem")+"]"
        print      "                                          [ " + green("--color")+" < " + turquoise("y") + " | "+ turquoise("n")+" >  ] [ "+green("--columns")+" ]"
        print      "                                     [ "+green("--reinstall ")+turquoise("changed-use")+" ] ["+green("--nospinner")+"]"
-       print "                                          [ "+green("--deep")+"  ] [" + green("--with-bdeps")+" < " + turquoise("y") + " | "+ turquoise("n")+" > ]"
+       print "                    [ "+green("--complete-graph")+"  ] [ "+green("--deep")+"  ] [" + green("--with-bdeps")+" < " + turquoise("y") + " | "+ turquoise("n")+" > ]"
        print bold("Actions:")+" [ "+green("--clean")+" | "+green("--depclean")+" | "+green("--prune")+" | "+green("--regen")+" | "+green("--search")+" | "+green("--unmerge")+" ]"
 
 def help(myaction,myopts,havecolor=1):
@@ -220,6 +220,19 @@ def help(myaction,myopts,havecolor=1):
                print "              Display the pretend output in a tabular form. Versions are"
                print "              aligned vertically."
                print
+               print "       "+green("--complete-graph")
+               desc = "This causes emerge to consider the deep dependencies of all" + \
+                       " packages from the system and world sets. With this option enabled," + \
+                       " emerge will bail out if it determines that the given operation will" + \
+                       " break any dependencies of the packages that have been added to the" + \
+                       " graph. Like the --deep option, the --complete-graph" + \
+                       " option will significantly increase the time taken for dependency" + \
+                       " calculations. Note that, unlike the --deep option, the" + \
+                       " --complete-graph option does not cause any more packages to" + \
+                       " be updated than would have otherwise been updated with the option disabled."
+               for line in wrap(desc, desc_width):
+                       print desc_indent + line
+               print
                print "       "+green("--debug")+" ("+green("-d")+" short option)"
                print "              Tell emerge to run the ebuild command in --debug mode. In this"
                print "              mode, the bash build environment will run with the -x option,"
index 07d9f1210d5620ff9b6b1b42794884b5b6b7fef5..ff42812611a53cdff160d1c1d302f88f23e51e01 100644 (file)
@@ -1014,7 +1014,6 @@ class config(object):
 
                self.user_profile_dir = None
                self.local_config = local_config
-               self._use_wildcards = False
 
                if clone:
                        self._filter_calling_env = copy.deepcopy(clone._filter_calling_env)
@@ -1075,7 +1074,6 @@ class config(object):
 
                        self._accept_license = copy.deepcopy(clone._accept_license)
                        self._plicensedict = copy.deepcopy(clone._plicensedict)
-                       self._use_wildcards = copy.deepcopy(clone._use_wildcards)
                else:
 
                        def check_var_directory(varname, var):
@@ -1145,7 +1143,7 @@ class config(object):
                                                parents = grabfile(parentsFile)
                                                if not parents:
                                                        raise portage.exception.ParseError(
-                                                               "Empty parent file: '%s'" % parents_file)
+                                                               "Empty parent file: '%s'" % parentsFile)
                                                for parentPath in parents:
                                                        parentPath = normalize_path(os.path.join(
                                                                currentPath, parentPath))
@@ -1304,7 +1302,8 @@ class config(object):
                        self.lookuplist.reverse()
 
                        # Blacklist vars that could interfere with portage internals.
-                       for blacklisted in "CATEGORY", "PKGUSE", "PORTAGE_CONFIGROOT", \
+                       for blacklisted in "CATEGORY", "EBUILD_PHASE", \
+                               "PKGUSE", "PORTAGE_CONFIGROOT", \
                                "PORTAGE_IUSE", "PORTAGE_USE", "ROOT", "EPREFIX", "EROOT":
                                for cfg in self.lookuplist:
                                        cfg.pop(blacklisted, None)
@@ -1380,11 +1379,6 @@ class config(object):
                                        if not self.pusedict.has_key(cp):
                                                self.pusedict[cp] = {}
                                        self.pusedict[cp][key] = pusedict[key]
-                                       if not self._use_wildcards:
-                                               for x in pusedict[key]:
-                                                       if x.endswith("_*"):
-                                                               self._use_wildcards = True
-                                                               break
 
                                #package.keywords
                                pkgdict = grabdict_package(
@@ -1837,6 +1831,13 @@ class config(object):
                                os.path.join(infodir, "CATEGORY"), noiselevel=-1)
                        self.configdict["pkg"].update(backup_pkg_metadata)
                        retval = 0
+
+               # Always set known good values for these variables, since
+               # corruption of these can cause problems:
+               cat, pf = catsplit(self.mycpv)
+               self.configdict["pkg"]["CATEGORY"] = cat
+               self.configdict["pkg"]["PF"] = pf
+
                return retval
 
        def setcpv(self, mycpv, use_cache=1, mydb=None):
@@ -1961,24 +1962,24 @@ class config(object):
                        has_changed = True
                self.configdict["pkg"]["PKGUSE"] = self.puse[:] # For saving to PUSE file
                self.configdict["pkg"]["USE"]    = self.puse[:] # this gets appended to USE
-               if iuse != self.configdict["pkg"].get("IUSE",""):
-                       self.configdict["pkg"]["IUSE"] = iuse
-                       test_use_changed = False
-                       if "test" in self.features:
-                               test_use_changed = \
-                                       bool(re.search(r'(^|\s)[-+]?test(\s|$)', iuse)) != \
-                                       ("test" in self["USE"].split())
-                       if self.get("EBUILD_PHASE") or \
-                               self._use_wildcards or \
-                               test_use_changed:
-                               # Without this conditional, regenerate() would be called
-                               # *every* time.
-                               has_changed = True
-               # CATEGORY is essential for doebuild calls
-               self.configdict["pkg"]["CATEGORY"] = mycpv.split("/")[0]
+               previous_iuse = self.configdict["pkg"].get("IUSE")
+               self.configdict["pkg"]["IUSE"] = iuse
+
+               # Always set known good values for these variables, since
+               # corruption of these can cause problems:
+               cat, pf = catsplit(self.mycpv)
+               self.configdict["pkg"]["CATEGORY"] = cat
+               self.configdict["pkg"]["PF"] = pf
+
                if has_changed:
                        self.reset(keeping_pkg=1,use_cache=use_cache)
 
+               # If this is not an ebuild phase and reset() has not been called,
+               # it's safe to return early here if IUSE has not changed.
+               if not (has_changed or ebuild_phase) and \
+                       previous_iuse == iuse:
+                       return
+
                # Filter out USE flags that aren't part of IUSE. This has to
                # be done for every setcpv() call since practically every
                # package has different IUSE. Some flags are considered to
@@ -1990,7 +1991,7 @@ class config(object):
                #  * Forced flags, such as those from {,package}use.force
                #  * build and bootstrap flags used by bootstrap.sh
 
-               usesplit = self["USE"].split()
+               use = set(self["USE"].split())
                iuse_implicit = set(x.lstrip("+-") for x in iuse.split())
 
                # Flags derived from ARCH.
@@ -2006,7 +2007,7 @@ class config(object):
                if use_expand_hidden:
                        use_expand_hidden = re.compile("^(%s)_.*" % \
                                ("|".join(x.lower() for x in use_expand_hidden)))
-                       for x in usesplit:
+                       for x in use:
                                if use_expand_hidden.match(x):
                                        iuse_implicit.add(x)
 
@@ -2032,11 +2033,95 @@ class config(object):
                                iuse_grep = ""
                        self.configdict["pkg"]["PORTAGE_IUSE"] = iuse_grep
 
+               ebuild_force_test = self.get("EBUILD_FORCE_TEST") == "1"
+               if ebuild_force_test and ebuild_phase and \
+                       not hasattr(self, "_ebuild_force_test_msg_shown"):
+                               self._ebuild_force_test_msg_shown = True
+                               writemsg("Forcing test.\n", noiselevel=-1)
+               if "test" in self.features and "test" in iuse_implicit:
+                       if "test" in self.usemask and not ebuild_force_test:
+                               # "test" is in IUSE and USE=test is masked, so execution
+                               # of src_test() probably is not reliable. Therefore,
+                               # temporarily disable FEATURES=test just for this package.
+                               self["FEATURES"] = " ".join(x for x in self.features \
+                                       if x != "test")
+                               use.discard("test")
+                       else:
+                               use.add("test")
+                               if ebuild_force_test:
+                                       self.usemask.discard("test")
+
+               # Use the calculated USE flags to regenerate the USE_EXPAND flags so
+               # that they are consistent.
+               use_expand = self.get("USE_EXPAND", "").split()
+               for var in use_expand:
+                       prefix = var.lower() + "_"
+                       prefix_len = len(prefix)
+                       expand_flags = set([ x[prefix_len:] for x in use \
+                               if x.startswith(prefix) ])
+                       var_split = self.get(var, "").split()
+                       # Preserve the order of var_split because it can matter for things
+                       # like LINGUAS.
+                       var_split = [ x for x in var_split if x in expand_flags ]
+                       var_split.extend(expand_flags.difference(var_split))
+                       has_wildcard = "*" in var_split
+                       if has_wildcard:
+                               var_split = [ x for x in var_split if x != "*" ]
+                       has_iuse = set()
+                       for x in iuse_implicit:
+                               if x.startswith(prefix):
+                                       has_iuse.add(x[prefix_len:])
+                       if has_wildcard:
+                               # * means to enable everything in IUSE that's not masked
+                               if has_iuse:
+                                       for x in iuse_implicit:
+                                               if x.startswith(prefix) and x not in self.usemask:
+                                                       suffix = x[prefix_len:]
+                                                       var_split.append(suffix)
+                                                       use.add(x)
+                               else:
+                                       # If there is a wildcard and no matching flags in IUSE then
+                                       # LINGUAS should be unset so that all .mo files are
+                                       # installed.
+                                       var_split = []
+                       # Make the flags unique and filter them according to IUSE.
+                       # Also, continue to preserve order for things like LINGUAS
+                       # and filter any duplicates that variable may contain.
+                       filtered_var_split = []
+                       remaining = has_iuse.intersection(var_split)
+                       for x in var_split:
+                               if x in remaining:
+                                       remaining.remove(x)
+                                       filtered_var_split.append(x)
+                       var_split = filtered_var_split
+
+                       if var_split:
+                               self[var] = " ".join(var_split)
+                       else:
+                               # Don't export empty USE_EXPAND vars unless the user config
+                               # exports them as empty.  This is required for vars such as
+                               # LINGUAS, where unset and empty have different meanings.
+                               if has_wildcard:
+                                       # ebuild.sh will see this and unset the variable so
+                                       # that things like LINGUAS work properly
+                                       self[var] = "*"
+                               else:
+                                       if has_iuse:
+                                               self[var] = ""
+                                       else:
+                                               # It's not in IUSE, so just allow the variable content
+                                               # to pass through if it is defined somewhere.  This
+                                               # allows packages that support LINGUAS but don't
+                                               # declare it in IUSE to use the variable outside of the
+                                               # USE_EXPAND context.
+                                               pass
+
                # Filtered for the ebuild environment. Store this in a separate
                # attribute since we still want to be able to see global USE
                # settings for things like emerge --info.
+
                self.configdict["pkg"]["PORTAGE_USE"] = " ".join(sorted(
-                       x for x in usesplit if \
+                       x for x in use if \
                        x in iuse_implicit))
 
        def getMaskAtom(self, cpv, metadata):
@@ -2438,103 +2523,18 @@ class config(object):
                                                continue
                                        myflags.add(var_lower + "_" + x)
 
-               myflags.update(self.useforce)
-
-               iuse = self.configdict["pkg"].get("IUSE","").split()
-               iuse = [ x.lstrip("+-") for x in iuse ]
-               # FEATURES=test should imply USE=test
                if not hasattr(self, "features"):
-                       self.features = list(sorted(set(
-                               self.configlist[-1].get("FEATURES","").split())))
+                       self.features = sorted(set(
+                               self.configlist[-1].get("FEATURES","").split()))
                self["FEATURES"] = " ".join(self.features)
-               ebuild_force_test = self.get("EBUILD_FORCE_TEST") == "1"
-               if ebuild_force_test and \
-                       self.get("EBUILD_PHASE") == "test" and \
-                       not hasattr(self, "_ebuild_force_test_msg_shown"):
-                               self._ebuild_force_test_msg_shown = True
-                               writemsg("Forcing test.\n", noiselevel=-1)
-               if "test" in self.features and "test" in iuse:
-                       if "test" in self.usemask and not ebuild_force_test:
-                               # "test" is in IUSE and USE=test is masked, so execution
-                               # of src_test() probably is not reliable. Therefore,
-                               # temporarily disable FEATURES=test just for this package.
-                               self["FEATURES"] = " ".join(x for x in self.features \
-                                       if x != "test")
-                               myflags.discard("test")
-                       else:
-                               myflags.add("test")
-                               if ebuild_force_test:
-                                       self.usemask.discard("test")
-
-               usesplit = [ x for x in myflags if \
-                       x not in self.usemask]
-
-               # Use the calculated USE flags to regenerate the USE_EXPAND flags so
-               # that they are consistent.
-               for var in use_expand:
-                       prefix = var.lower() + "_"
-                       prefix_len = len(prefix)
-                       expand_flags = set([ x[prefix_len:] for x in usesplit \
-                               if x.startswith(prefix) ])
-                       var_split = self.get(var, "").split()
-                       # Preserve the order of var_split because it can matter for things
-                       # like LINGUAS.
-                       var_split = [ x for x in var_split if x in expand_flags ]
-                       var_split.extend(expand_flags.difference(var_split))
-                       has_wildcard = "*" in var_split
-                       if has_wildcard:
-                               var_split = [ x for x in var_split if x != "*" ]
-                               self._use_wildcards = True
-                       has_iuse = False
-                       for x in iuse:
-                               if x.startswith(prefix):
-                                       has_iuse = True
-                                       break
-                       if has_wildcard:
-                               # * means to enable everything in IUSE that's not masked
-                               if has_iuse:
-                                       for x in iuse:
-                                               if x.startswith(prefix) and x not in self.usemask:
-                                                       suffix = x[prefix_len:]
-                                                       if suffix in var_split:
-                                                               continue
-                                                       var_split.append(suffix)
-                                                       usesplit.append(x)
-                               else:
-                                       # If there is a wildcard and no matching flags in IUSE then
-                                       # LINGUAS should be unset so that all .mo files are
-                                       # installed.
-                                       var_split = []
-                       if var_split:
-                               self[var] = " ".join(var_split)
-                       else:
-                               # Don't export empty USE_EXPAND vars unless the user config
-                               # exports them as empty.  This is required for vars such as
-                               # LINGUAS, where unset and empty have different meanings.
-                               if has_wildcard:
-                                       # ebuild.sh will see this and unset the variable so
-                                       # that things like LINGUAS work properly
-                                       self[var] = "*"
-                               else:
-                                       if has_iuse:
-                                               self[var] = ""
-                                       else:
-                                               # It's not in IUSE, so just allow the variable content
-                                               # to pass through if it is defined somewhere.  This
-                                               # allows packages that support LINGUAS but don't
-                                               # declare it in IUSE to use the variable outside of the
-                                               # USE_EXPAND context.
-                                               pass
 
+               myflags.update(self.useforce)
                arch = self.configdict["defaults"].get("ARCH")
-               if arch and arch not in usesplit:
-                       usesplit.append(arch)
-
-               usesplit = [x for x in usesplit if \
-                       x not in self.usemask]
+               if arch:
+                       myflags.add(arch)
 
-               usesplit.sort()
-               self.configlist[-1]["USE"]= " ".join(usesplit)
+               myflags.difference_update(self.usemask)
+               self.configlist[-1]["USE"]= " ".join(sorted(myflags))
 
                self.already_in_regenerate = 0
 
@@ -4825,12 +4825,6 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                        return spawn(_shell_quote(ebuild_sh_binary) + " " + mydo,
                                mysettings, debug=debug, free=1, logfile=logfile)
                elif mydo == "setup":
-                       infodir = os.path.join(
-                               mysettings["PORTAGE_BUILDDIR"], "build-info")
-                       if os.path.isdir(infodir):
-                               """Load USE flags for setup phase of a binary package.
-                               Ideally, the environment.bz2 would be used instead."""
-                               mysettings.load_infodir(infodir)
                        retval = spawn(
                                _shell_quote(ebuild_sh_binary) + " " + mydo, mysettings,
                                debug=debug, free=1, logfile=logfile)
@@ -4887,7 +4881,6 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                                                noiselevel=-1)
                        return phase_retval
                elif mydo in ("prerm", "postrm", "config", "info"):
-                       mysettings.load_infodir(mysettings["O"])
                        retval =  spawn(
                                _shell_quote(ebuild_sh_binary) + " " + mydo,
                                mysettings, debug=debug, free=1, logfile=logfile)
@@ -5052,6 +5045,16 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                                actionmap[x]["dep"] = ' '.join(actionmap_deps[x])
 
                if mydo in actionmap:
+                       if mydo == "package":
+                               # Make sure the package directory exists before executing
+                               # this phase. This can raise PermissionDenied if
+                               # the current user doesn't have write access to $PKGDIR.
+                               parent_dir = os.path.join(mysettings["PKGDIR"],
+                                       mysettings["CATEGORY"])
+                               portage.util.ensure_dirs(parent_dir)
+                               if not os.access(parent_dir, os.W_OK):
+                                       raise portage.exception.PermissionDenied(
+                                               "access('%s', os.W_OK)" % parent_dir)
                        retval = spawnebuild(mydo,
                                actionmap, mysettings, debug, logfile=logfile)
                elif mydo=="qmerge":
@@ -5400,12 +5403,21 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/",
                else:
                        a = ['||']
                for y in pkgs:
-                       depstring = " ".join(y[2].aux_get(y[0], dep_keys))
+                       cpv, pv_split, db = y
+                       depstring = " ".join(db.aux_get(cpv, dep_keys))
+                       pkg_kwargs = kwargs.copy()
+                       if isinstance(db, portdbapi):
+                               # for repoman
+                               pass
+                       else:
+                               # for emerge
+                               use_split = db.aux_get(cpv, ["USE"])[0].split()
+                               pkg_kwargs["myuse"] = use_split
                        if edebug:
                                print "Virtual Parent:   ", y[0]
                                print "Virtual Depstring:", depstring
                        mycheck = dep_check(depstring, mydbapi, mysettings, myroot=myroot,
-                               trees=trees, **kwargs)
+                               trees=trees, **pkg_kwargs)
                        if not mycheck[0]:
                                raise portage.exception.ParseError(
                                        "%s: %s '%s'" % (y[0], mycheck[1], depstring))
@@ -6092,8 +6104,8 @@ class FetchlistDict(UserDict.DictMixin):
                """Returns the complete fetch list for a given package."""
                return self.portdb.getfetchlist(pkg_key, mysettings=self.settings,
                        all=True, mytree=self.mytree)[1]
-       def __contains__(self):
-               return pkg_key in self.keys()
+       def __contains__(self, cpv):
+               return cpv in self.keys()
        def has_key(self, pkg_key):
                """Returns true if the given package exists within pkgdir."""
                return pkg_key in self
index ebe49a798d8122eb56becdaf16970868808d5d60..f795d9866ac67178ef40bd11529aa1b60ebb4325 100644 (file)
@@ -4,7 +4,8 @@
 
 from portage.dep import isvalidatom, isjustname, dep_getkey, match_from_list
 from portage.dbapi.virtual import fakedbapi
-from portage.exception import InvalidPackageName, InvalidAtom, PortageException
+from portage.exception import InvalidPackageName, InvalidAtom, \
+       PermissionDenied, PortageException
 from portage.output import green
 from portage.util import ensure_dirs, normalize_path, writemsg, writemsg_stdout
 from portage.versions import best, catpkgsplit, catsplit
@@ -291,6 +292,15 @@ class binarytree(object):
                ${PKGDIR}/${CATEGORY}/${PF}.tbz2 so that both can coexist."""
                if not self._all_directory:
                        return
+
+               # Copy group permissions for new directories that
+               # may have been created.
+               for path in ("All", catsplit(cpv)[0]):
+                       path = os.path.join(self.pkgdir, path)
+                       self._ensure_dir(path)
+                       if not os.access(path, os.W_OK):
+                               raise PermissionDenied("access('%s', W_OK)" % path)
+
                full_path = self.getname(cpv)
                if "All" == full_path.split(os.path.sep)[-2]:
                        return
index 635fcdfa8c7d523aed4a0e0b8ae83f505dac6062..b54a36e2a246ee5836f3cdf31f6c499896c780b6 100644 (file)
@@ -399,7 +399,12 @@ def file_get(baseurl,dest,conn=None,fcmd=None):
        lexer = shlex.shlex(StringIO.StringIO(fcmd), posix=True)
        lexer.whitespace_split = True
        myfetch = [varexpand(x, mydict=variables) for x in lexer]
-       retval = spawn(myfetch, env=os.environ.copy())
+       fd_pipes= {
+               0:sys.stdin.fileno(),
+               1:sys.stdout.fileno(),
+               2:sys.stdout.fileno()
+       }
+       retval = spawn(myfetch, env=os.environ.copy(), fd_pipes=fd_pipes)
        if retval != os.EX_OK:
                sys.stderr.write("Fetcher exited with a failure condition.\n")
                return 0