Merged from trunk -r14515:14525
authorFabian Groffen <grobian@gentoo.org>
Sat, 10 Oct 2009 10:23:41 +0000 (10:23 -0000)
committerFabian Groffen <grobian@gentoo.org>
Sat, 10 Oct 2009 10:23:41 +0000 (10:23 -0000)
   | 14516    | Enable pty support on FreeBSD.                              |
   | zmedico  |                                                             |

   | 14517    | Bug #287950 - Add support for FEATURES=fail-clean which is  |
   | zmedico  | useful for cleaning up temp files on tmpfs after build      |
   |          | failures with --keep-going.                                 |

   | 14518    | Bug #287950 - Add a --fail-clean[=n] option, for enabling   |
   | zmedico  | or disabling FEATURES=fail-clean from the command line.     |

   | 14519    | Fix typo in FEATURES=news docs. Thanks to Jonathan Callen   |
   | zmedico  | <en.ABCD@gmail.com> for this patch.                         |

   | 14520    | Bug #267468 - Display the total number of binary packages   |
   | zmedico  | in the merge list. Thanks to Sebastian Mingramm (few) for   |
   |          | this patch.                                                 |

   | 14521    | Bug #270933 - Make the "If you need support ..." message    |
   | zmedico  | ask for emerge --info and the build.log. Thanks to          |
   |          | Sebastian Mingramm (few) for this patch.                    |

   | 14522    | Bug #271551 - Inside depgraph.select_files(), avoid bailing |
   | zmedico  | out due to an ambiguous package name in cases when all but  |
   |          | one of the resolved packages are virtual. Thanks to         |
   |          | Sebastian Mingramm (few) for this patch.                    |

   | 14523    | Bug #272000 - When --keep-going is enabled, don't           |
   | zmedico  | completely bail out at the beginning due to corrupt         |
   |          | manifest(s). Thanks to Sebastian Mingramm (few) for this    |
   |          | patch.                                                      |

   | 14524    | Fix "TabError: inconsistent use of tabs and spaces in       |
   | arfrever | indentation" with Python 3 which was introduced in r14522.  |

   | 14525    | Ask for the output of 'emerge --info =$CATEGORY/$PF'.       |
   | arfrever |                                                             |

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

13 files changed:
bin/ebuild
bin/isolated-functions.sh
man/emerge.1
man/make.conf.5
pym/_emerge/EbuildPhase.py
pym/_emerge/PackageCounters.py
pym/_emerge/Scheduler.py
pym/_emerge/actions.py
pym/_emerge/depgraph.py
pym/_emerge/help.py
pym/_emerge/main.py
pym/portage/__init__.py
pym/portage/dbapi/vartree.py

index bcf513cc340ef851ce07de31f895501487a240ab..5493fba8facf9f8195bc1a863e6cdea3c191092b 100755 (executable)
@@ -201,6 +201,11 @@ if "test" in pargs:
                tmpsettings["FEATURES"] = " ".join(sorted(tmpsettings.features))
                tmpsettings.backup_changes("FEATURES")
 
+if 'fail-clean' in tmpsettings.features:
+       tmpsettings.features.remove('fail-clean')
+       tmpsettings["FEATURES"] = " ".join(sorted(tmpsettings.features))
+       tmpsettings.backup_changes("FEATURES")
+
 if opts.skip_manifest:
        tmpsettings["EBUILD_SKIP_MANIFEST"] = "1"
        tmpsettings.backup_changes("EBUILD_SKIP_MANIFEST")
index ac14aac490a8d4517158f5ea430d4e75bea9ec9f..501f57d0d324342e15d2743cae6bf0c32ea08276 100755 (executable)
@@ -121,7 +121,8 @@ die() {
                | sed -e '1d' -e 's:^:RETAIN-LEADING-SPACE:' \
                | while read -r n ; do eerror "  ${n#RETAIN-LEADING-SPACE}" ; done
        eerror
-       eerror "If you need support, post the topmost build error, and the call stack if relevant."
+       eerror "If you need support, post the output of 'emerge --info =$CATEGORY/$PF',"
+       eerror "the complete build log and the output of 'emerge -pqv =$CATEGORY/$PF'."
        if [[ -n ${EBUILD_OVERLAY_ECLASSES} ]] ; then
                eerror "This ebuild used the following eclasses from overlays:"
                local x
@@ -158,7 +159,7 @@ die() {
        fi
 
        [[ -n ${PORTAGE_LOG_FILE} ]] \
-               && eerror "A complete build log is located at '${PORTAGE_LOG_FILE}'."
+               && eerror "The complete build log is located at '${PORTAGE_LOG_FILE}'."
        if [ -f "${T}/environment" ] ; then
                eerror "The ebuild environment file is located at '${T}/environment'."
        elif [ -d "${T}" ] ; then
index bb99f2842a7774844663aa671d23ea884992bcd1..63e9879bad42cc7cc564ddac8dc63525c3cbf0ce 100644 (file)
@@ -330,6 +330,13 @@ specifications while differing from the installed set of packages as
 little as possible.  You should run with \fB\-\-pretend\fR first to make 
 sure the result is what you expect.
 .TP
+.BR "\-\-fail\-clean[=n]"
+Clean up temporary files after a build failure. This is
+particularly useful if you have \fBPORTAGE_TMPDIR\fR on
+tmpfs. If this option is enabled, you probably also want
+to enable \fBPORT_LOGDIR\fR (see \fBmake.conf\fR(5)) in
+order to save the build log.
+.TP
 .BR "\-\-fetchonly " (\fB\-f\fR)
 Instead of doing any package building, just perform fetches for all
 packages (fetch things from SRC_URI based upon USE setting).
index c0b48e92477aaab419331103dfaa22e5c450b32c..d16f5a1136d555a012c53f6b2ca139a01a53f895 100644 (file)
@@ -213,6 +213,13 @@ when a problem arises (normally due to a crash or disconnect).
 Enable fakeroot for the install and package phases when a non-root user runs
 the \fBebuild\fR(1) command.
 .TP
+.B fail\-clean
+Clean up temporary files after a build failure. This is particularly useful
+if you have \fBPORTAGE_TMPDIR\fR on tmpfs. If this feature is enabled, you
+probably also want to enable \fBPORT_LOGDIR\fR in order to save the build log.
+Both the \fBebuild\fR(1) command and the \fInoclean\fR feature cause the
+\fIfail\-clean\fR feature to be automatically disabled.
+.TP
 .B fixpackages
 Runs the script that will fix the dependencies in all binary packages.  This is 
 run whenever packages are moved around in the portage tree.  Please note that this 
@@ -269,7 +276,7 @@ portage feature called \fImultilib\-strict\fR. It will prevent emerge
 from putting 64bit libraries into anything other than (/usr)/lib64.
 .TP
 .B news
-Enable GLEP 42 new support. See
+Enable GLEP 42 news support. See
 \fIhttp://www.gentoo.org/proj/en/glep/glep-0042.html\fR.
 .TP
 .B noauto
index 51f018cb14e0067bac4f8c4e506b7681909447d7..fcf60d39c8eb128390bc62be9559554e3979fba8 100644 (file)
@@ -45,6 +45,11 @@ class EbuildPhase(CompositeTask):
                                        log_file.close()
 
                if self._default_exit(ebuild_process) != os.EX_OK:
+                       if self.phase != 'clean' and \
+                               'noclean' not in self.settings.features and \
+                               'fail-clean' in self.settings.features:
+                               self._fail_clean()
+                               return
                        self.wait()
                        return
 
@@ -80,7 +85,27 @@ class EbuildPhase(CompositeTask):
                if self._final_exit(post_phase) != os.EX_OK:
                        writemsg("!!! post %s failed; exiting.\n" % self.phase,
                                noiselevel=-1)
+                       if self.phase != 'clean' and \
+                               'noclean' not in self.settings.features and \
+                               'fail-clean' in self.settings.features:
+                               self._fail_clean()
+                               return
                self._current_task = None
                self.wait()
                return
 
+       def _fail_clean(self):
+               self.returncode = None
+               portage.elog.elog_process(self.pkg.cpv, self.settings)
+               phase = "clean"
+               clean_phase = EbuildPhase(background=self.background,
+                       pkg=self.pkg, phase=phase,
+                       scheduler=self.scheduler, settings=self.settings,
+                       tree=self.tree)
+               self._start_task(clean_phase, self._fail_clean_exit)
+               return
+
+       def _fail_clean_exit(self, clean_phase):
+               self._final_exit(clean_phase)
+               self.returncode = 1
+               self.wait()
index 9da79d38994b9dd1ff94b2ff78e41008cc7e3c41..e99972e6f7ef8efb9bb7a938c6d89b915461b462 100644 (file)
@@ -22,6 +22,7 @@ class PackageCounters(object):
                self.restrict_fetch           = 0
                self.restrict_fetch_satisfied = 0
                self.interactive              = 0
+               self.binary                   = 0
 
        def __str__(self):
                total_installs = self.upgrades + self.downgrades + self.newslot + self.new + self.reinst
@@ -50,6 +51,10 @@ class PackageCounters(object):
                        details.append("%s reinstall" % self.reinst)
                        if self.reinst > 1:
                                details[-1] += "s"
+               if self.binary > 0:
+                       details.append("%s binary" % self.binary)
+                       if self.binary > 1:
+                               details[-1] = details[-1][:-1] + "ies"
                if self.uninst > 0:
                        details.append("%s uninstall" % self.uninst)
                        if self.uninst > 1:
index 00c27925b6a131988c03d113d43af5c90f2cb287..f2247578b19faf8923e2f257608790e87f3a5daf 100644 (file)
@@ -816,19 +816,21 @@ class Scheduler(PollScheduler):
                        self.pkgsettings[root] = portage.config(
                                clone=root_config.settings)
 
+               keep_going = "--keep-going" in self.myopts
+               fetchonly = self._build_opts.fetchonly
+               mtimedb = self._mtimedb
+               failed_pkgs = self._failed_pkgs
+
                rval = self._generate_digests()
                if rval != os.EX_OK:
                        return rval
 
+               # TODO: Immediately recalculate deps here if --keep-going
+               #       is enabled and corrupt manifests are detected.
                rval = self._check_manifests()
-               if rval != os.EX_OK:
+               if rval != os.EX_OK and not keep_going:
                        return rval
 
-               keep_going = "--keep-going" in self.myopts
-               fetchonly = self._build_opts.fetchonly
-               mtimedb = self._mtimedb
-               failed_pkgs = self._failed_pkgs
-
                while True:
                        rval = self._merge()
                        if rval == os.EX_OK or fetchonly or not keep_going:
index 8816ac7dc6c5ef5b32c0d5545af2aa6951d2f74d..671410e163a8e10e2f504d539b9f44c074e9b1f2 100644 (file)
@@ -2378,6 +2378,19 @@ def adjust_config(myopts, settings):
                settings['FEATURES'] = ' '.join(sorted(settings.features))
                settings.backup_changes("FEATURES")
 
+       fail_clean = myopts.get('--fail-clean')
+       if fail_clean is not None:
+               if fail_clean is True and \
+                       'fail-clean' not in settings.features:
+                       settings.features.add('fail-clean')
+                       settings['FEATURES'] = ' '.join(sorted(settings.features))
+                       settings.backup_changes('FEATURES')
+               elif fail_clean == 'n' and \
+                       'fail-clean' in settings.features:
+                       settings.features.remove('fail-clean')
+                       settings['FEATURES'] = ' '.join(sorted(settings.features))
+                       settings.backup_changes('FEATURES')
+
        CLEAN_DELAY = 5
        try:
                CLEAN_DELAY = int(settings.get("CLEAN_DELAY", str(CLEAN_DELAY)))
index 19d351139242a27d68871e9717077c5b09df042e..5aed665276351593ffcd31c6ec8edacd8826b4c2 100644 (file)
@@ -1570,6 +1570,18 @@ class depgraph(object):
                                        expanded_atoms = [atom for atom in expanded_atoms \
                                                if atom.cp == installed_cp]
 
+                               # If a non-virtual package and one or more virtual packages
+                               # are in expanded_atoms, use the non-virtual package.
+                               if len(expanded_atoms) > 1:
+                                       number_of_virtuals = 0
+                                       for expanded_atom in expanded_atoms:
+                                               if expanded_atom.cp.startswith("virtual/"):
+                                                       number_of_virtuals += 1
+                                               else:
+                                                       candidate = expanded_atom
+                                       if len(expanded_atoms) - number_of_virtuals == 1:
+                                               expanded_atoms = [ candidate ]
+
                                if len(expanded_atoms) > 1:
                                        print()
                                        print()
@@ -4161,6 +4173,8 @@ class depgraph(object):
                                        if ordered:
                                                if pkg_merge:
                                                        counters.reinst += 1
+                                                       if pkg_type == "binary":
+                                                               counters.binary += 1
                                                elif pkg_status == "uninstall":
                                                        counters.uninst += 1
                                # filter out old-style virtual matches
@@ -4183,17 +4197,23 @@ class depgraph(object):
                                                        addl += turquoise("U")+blue("D")
                                                        if ordered:
                                                                counters.downgrades += 1
+                                                               if pkg_type == "binary":
+                                                                       counters.binary += 1
                                                else:
                                                        # Update in slot
                                                        addl += turquoise("U") + " "
                                                        if ordered:
                                                                counters.upgrades += 1
+                                                               if pkg_type == "binary":
+                                                                       counters.binary += 1
                                        else:
                                                # New slot, mark it new.
                                                addl = " " + green("NS") + fetch + "  "
                                                myoldbest = vardb.match(portage.cpv_getkey(pkg_key))
                                                if ordered:
                                                        counters.newslot += 1
+                                                       if pkg_type == "binary":
+                                                               counters.binary += 1
 
                                        if "--changelog" in self._frozen_config.myopts:
                                                inst_matches = vardb.match(pkg.slot_atom)
@@ -4210,6 +4230,8 @@ class depgraph(object):
                                        addl = " " + green("N") + " " + fetch + "  "
                                        if ordered:
                                                counters.new += 1
+                                               if pkg_type == "binary":
+                                                       counters.binary += 1
 
                                verboseadd = ""
                                repoadd = None
index c0a6d01d525cf84959d257b5bb8c461688302826..312952295b432e37444955d03c589d8448e6c544 100644 (file)
@@ -346,6 +346,15 @@ def help(myopts, havecolor=1):
                print("              it possible for developers to get a complete overview of the")
                print("              complete dependency tree of a certain package.")
                print()
+               print("       "+green("--fail-clean[=n]"))
+               desc = "Clean up temporary files after a build failure. This is " + \
+                       "particularly useful if you have PORTAGE_TMPDIR on " + \
+                       "tmpfs. If this option is enabled, you probably also want " + \
+                       "to enable PORT_LOGDIR (see make.conf(5)) in " + \
+                       "order to save the build log."
+               for line in wrap(desc, desc_width):
+                       print(desc_indent + line)
+               print()
                print("       "+green("--fetchonly")+" ("+green("-f")+" short option)")
                print("              Instead of doing any package building, just perform fetches for")
                print("              all packages (main package as well as all dependencies.) When")
index 9114322ae4e60cce2ad65db8c1197e9a3efa7bf4..9f284aecb1338c310491768935f1b9a70c71e173 100644 (file)
@@ -383,6 +383,7 @@ def insert_optional_args(args):
                '--deep'       : valid_integers,
                '--deselect'   : ('n',),
                '--binpkg-respect-use'   : ('n', 'y',),
+               '--fail-clean'           : ('n',),
                '--getbinpkg'            : ('n',),
                '--getbinpkgonly'        : ('n',),
                '--jobs'       : valid_integers,
@@ -538,6 +539,12 @@ def parse_opts(tmpcmdline, silent=False):
                        "choices" : ("True", "n")
                },
 
+               "--fail-clean": {
+                       "help"    : "clean temp files after build failure",
+                       "type"    : "choice",
+                       "choices" : ("True", "n")
+               },
+
                "--jobs": {
 
                        "shortopt" : "-j",
@@ -672,6 +679,9 @@ def parse_opts(tmpcmdline, silent=False):
        else:
                myoptions.complete_graph = None
 
+       if myoptions.fail_clean == "True":
+               myoptions.fail_clean = True
+
        if myoptions.getbinpkg in ("True",):
                myoptions.getbinpkg = True
        else:
index 7667ccc4c2a86e2fe7eb79564634fb1fec38221f..7c245f4b6b01ad111515b3104191b4d8afb24c7f 100644 (file)
@@ -3868,7 +3868,7 @@ def _test_pty_eof():
 
 # In some cases, openpty can be slow when it fails. Therefore,
 # stop trying to use it after the first failure.
-if platform.system() not in ["Linux"]:
+if platform.system() not in ["FreeBSD", "Linux"]:
        # Disable the use of openpty on Solaris as it seems Python's openpty
        # implementation doesn't play nice on Solaris with Portage's
        # behaviour causing hangs/deadlocks.
index 9c3dbfab6b73f97ba91f780dfddacca5035e785f..563d259c9b50b781a45b84acb2fc362d351b05fb 100644 (file)
@@ -5074,7 +5074,10 @@ class dblink(object):
 
                        # Process ebuild logfiles
                        elog_process(self.mycpv, self.settings, phasefilter=filter_mergephases)
-                       if retval == os.EX_OK and "noclean" not in self.settings.features:
+                       if 'noclean' not in self.settings.features and \
+                               (retval == os.EX_OK or \
+                               ('fail-clean' in self.settings.features and \
+                               os.path.isdir(self.settings['PORTAGE_BUILDDIR']))):
                                if myebuild is None:
                                        myebuild = os.path.join(inforoot, self.pkg + ".ebuild")