From: Fabian Groffen Date: Sun, 13 Apr 2008 09:42:21 +0000 (-0000) Subject: Merged from trunk 9831:9860 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=6048003498ae8ebc46f7282189300c52a6634b34;p=portage.git Merged from trunk 9831:9860 | 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 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 --- diff --git a/RELEASE-NOTES b/RELEASE-NOTES index c107bbce3..4b57835f1 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -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 ================================== diff --git a/bin/ebuild.sh b/bin/ebuild.sh index 54e1904d6..064f5313d 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -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 diff --git a/man/emerge.1 b/man/emerge.1 index 6df5af075..90786156c 100644 --- a/man/emerge.1 +++ b/man/emerge.1 @@ -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 diff --git a/man/make.conf.5 b/man/make.conf.5 index 90e419afc..4976ebe4d 100644 --- a/man/make.conf.5 +++ b/man/make.conf.5 @@ -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). diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index 7045c2448..b228ce28d 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -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. diff --git a/pym/_emerge/help.py b/pym/_emerge/help.py index 4c7505da1..b6bc541cd 100644 --- a/pym/_emerge/help.py +++ b/pym/_emerge/help.py @@ -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," diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 07d9f1210..ff4281261 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -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 diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py index ebe49a798..f795d9866 100644 --- a/pym/portage/dbapi/bintree.py +++ b/pym/portage/dbapi/bintree.py @@ -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 diff --git a/pym/portage/getbinpkg.py b/pym/portage/getbinpkg.py index 635fcdfa8..b54a36e2a 100644 --- a/pym/portage/getbinpkg.py +++ b/pym/portage/getbinpkg.py @@ -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