From: Fabian Groffen Date: Mon, 1 Dec 2008 20:56:01 +0000 (-0000) Subject: Merged from trunk -r12040:12057 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=6c978b4868b2fa51abcb5eaafc64ea1232b96764;p=portage.git Merged from trunk -r12040:12057 | 12041 | Add some hints about bash binary corruption and hardware | | zmedico | malfunction to the message that's displayed when bash exits | | | unexpectedly. | | 12043 | Add new @unavailable package set which contains all | | zmedico | installed packages for which there are no visible ebuilds | | | corresponding to the same $CATEGORY/$PN:$SLOT. | | 12044 | Add back accidentally removed @downgrade set. Thanks to | | zmedico | Arfrever. | | 12045 | When displaying anscestors of an unstatisfied dependency | | zmedico | (code from bug #245358), avoid a potential infinite loop and | | | memory leak triggered by circular dependencies. Thanks to | | | Peter Weller for reporting. | | 12047 | Add docs for all of the supported commands. | | zmedico | | | 12049 | Bug #247548 - Remove 'last' and 'lfull' commands since | | zmedico | nobody uses them. Thanks to Alec Warner . | | 12051 | Fix the code from bug #245358 so that it's guaranteed to | | zmedico | traverse all the way to a root node, even when circular deps | | | are encountered. | | 12053 | Bug #188780 - Make the read_int() function show a more human | | zmedico | readable error message, instead of the 'value too great for | | | base' message when the user enters an invalid value such as | | | '1y'. | | 12055 | Fix SIGINT and SIGTERM trap handling so the temp dir always | | zmedico | cleaned up when killed. | | 12057 | Add a note about negative IUSE default settings being | | zmedico | ineffective given the default USE_ORDER setting which causes | | | profile and user configuration settings to override them. | svn path=/main/branches/prefix/; revision=12130 --- diff --git a/bin/emaint b/bin/emaint index c5135212b..8ec7cadd3 100755 --- a/bin/emaint +++ b/bin/emaint @@ -4,6 +4,7 @@ import os import re import signal import sys +import textwrap import time from optparse import OptionParser, OptionValueError @@ -20,6 +21,8 @@ import portage.const, portage.exception, portage.output class WorldHandler(object): + short_desc = "Fix problems in the world file" + def name(): return "world" name = staticmethod(name) @@ -105,6 +108,8 @@ class WorldHandler(object): class BinhostHandler(object): + short_desc = "Generate a metadata index for binary packages" + def name(): return "binhost" name = staticmethod(name) @@ -317,6 +322,9 @@ class MoveHandler(object): return errors class MoveInstalled(MoveHandler): + + short_desc = "Perform package move updates for installed packages" + def name(): return "moveinst" name = staticmethod(name) @@ -325,6 +333,9 @@ class MoveInstalled(MoveHandler): MoveHandler.__init__(self, portage.db[myroot]["vartree"]) class MoveBinary(MoveHandler): + + short_desc = "Perform package move updates for binary packages" + def name(): return "movebin" name = staticmethod(name) @@ -409,6 +420,9 @@ class ProgressHandler(object): raise NotImplementedError(self) class CleanResume(object): + + short_desc = "Discard emerge --resume merge lists" + def name(): return "cleanresume" name = staticmethod(name) @@ -485,12 +499,20 @@ def emaint_main(myargv): setattr(parser, var, str(option)) - usage = "usage: emaint [options] " + " | ".join(module_names) + usage = "usage: emaint [options] COMMAND" - usage+= "\n\nCurrently emaint can only check and fix problems with one's world\n" - usage+= "file. Future versions will integrate other portage check-and-fix\n" - usage+= "tools and provide a single interface to system health checks." + desc = "The emaint program provides an interface to system health " + \ + "checks and maintenance. See the emaint(1) man page for " + \ + "for additional information about the following commands:" + usage += "\n\n" + for line in textwrap.wrap(desc, 65): + usage += "%s\n" % line + usage += "\n" + usage += " %s" % "all".ljust(15) + \ + "Perform all supported commands\n" + for m in module_names[1:]: + usage += " %s%s\n" % (m.ljust(15), modules[m].short_desc) parser = OptionParser(usage=usage, version=portage.VERSION) parser.add_option("-c", "--check", help="check for problems", diff --git a/bin/etc-update b/bin/etc-update index a9b056831..0a0f829c3 100755 --- a/bin/etc-update +++ b/bin/etc-update @@ -223,7 +223,8 @@ read_int() { read my_input # failed integer conversions will break a loop unless they're enclosed # in a subshell. - echo "${my_input}" | ( declare -i x; read x) && break + echo "${my_input}" | ( declare -i x; read x) 2>/dev/null && break + echo -n "Value '$my_input' is not valid. Please enter an integer value:" >&2 done echo ${my_input} } @@ -445,10 +446,9 @@ Please select from the menu above (-1 to exit, losing this merge): " } die() { - trap "" TERM - trap "" KILL + trap SIGTERM SIGINT - if [ ${2} -eq 0 ]; then + if [ "$2" -eq 0 ]; then echo "Exiting: ${1}" scan > /dev/null [ ${count} -gt 0 ] && echo "NOTE: ${count} updates remaining" @@ -500,7 +500,8 @@ export PORTAGE_TMPDIR export EROOT=${ROOT%/}${EPREFIX}/ TMP="${PORTAGE_TMPDIR}/etc-update-$$" -trap die term +trap "die terminated 1" SIGTERM +trap "die interrupted 1" SIGINT [ -w ${PORTAGE_CONFIGROOT}etc ] || die "Need write access to ${PORTAGE_CONFIGROOT}etc" 1 #echo $PORTAGE_TMPDIR diff --git a/bin/repoman b/bin/repoman index e3148d972..43fc033da 100755 --- a/bin/repoman +++ b/bin/repoman @@ -25,11 +25,6 @@ import platform from itertools import chain, izip from stat import S_ISDIR, ST_CTIME -try: - import cPickle as pickle -except ImportError: - import pickle - try: import cStringIO as StringIO except ImportError: @@ -149,8 +144,6 @@ def ParseArgs(args, qahelp): 'fix' : 'Fix simple QA issues (stray digests, missing digests)', 'full' : 'Scan directory tree and print all issues (not a summary)', 'help' : 'Show this screen', - 'last' : 'Remember report from last run', - 'lfull' : 'Remember report from last run (full listing)', 'manifest' : 'Generate a Manifest (fetches files if necessary)', 'scan' : 'Scan directory tree for QA issues' } @@ -226,7 +219,7 @@ def ParseArgs(args, qahelp): break if not opts.mode: - opts.mode = 'full' #default to full + opts.mode = 'full' if opts.mode == 'ci': opts.mode = 'commit' # backwards compat shortcut @@ -424,61 +417,8 @@ suspect_rdepend = frozenset([ # file.executable no_exec = frozenset(["Manifest","ChangeLog","metadata.xml"]) -def last(full=False): - """Print the results of the last repoman run - Args: - full - Print the complete results, if false, print a summary - Returns: - Doesn't return (invokes sys.exit() - """ - #Retrieve and unpickle stats and fails from saved files - savedf=open(os.path.join(portage.const.CACHE_PATH, 'repo.stats'),'r') - stats = pickle.load(savedf) - savedf.close() - savedf=open(os.path.join(portage.const.CACHE_PATH, 'repo.fails'),'r') - fails = pickle.load(savedf) - savedf.close() - - #dofail will be set to 1 if we have failed in at least one non-warning category - dofail=0 - #dowarn will be set to 1 if we tripped any warnings - dowarn=0 - #dofull will be set if we should print a "repoman full" informational message - dofull=0 - - dofull = options.mode not in ("full", "lfull") - - for x in qacats: - if not stats[x]: - continue - dowarn = 1 - if x not in qawarnings: - dofail = 1 - - print - print green("RepoMan remembers...") - print - style_file = ConsoleStyleFile(sys.stdout) - console_writer = StyleWriter(file=style_file, maxcol=9999) - console_writer.style_listener = style_file.new_styles - f = formatter.AbstractFormatter(console_writer) - utilities.format_qa_output(f, stats, fails, dofull, dofail, options, qawarnings) - print - if dofull: - print bold("Note: type \"repoman lfull\" for a complete listing of repomans last run.") - print - if dowarn and not dofail: - print green("RepoMan sez:"),"\"You only gave me a partial QA payment last time?\n I took it, but I wasn't happy.\"" - elif not dofail: - print green("RepoMan sez:"),"\"If everyone were like you, I'd be out of business!\"" - print - sys.exit(0) - options, arguments = ParseArgs(sys.argv, qahelp) -if options.mode in ('last', 'lfull'): - last('lfull' in options.mode) - # Set this to False when an extraordinary issue (generally # something other than a QA issue) makes it impossible to # commit (like if Manifest generation fails). @@ -1608,24 +1548,12 @@ for x in scanlist: if options.mode == "manifest": sys.exit(dofail) -#Pickle and save results for instant reuse in last and lfull -if os.access(portage.const.CACHE_PATH, os.W_OK): - for myobj, fname in (stats, "repo.stats"), (fails, "repo.fails"): - fpath = os.path.join(portage.const.CACHE_PATH, fname) - savef = open(fpath, 'w') - pickle.dump(myobj, savef) - savef.close() - portage.apply_secpass_permissions(fpath, gid=portage.portage_gid, - mode=0664) - -# TODO(antarus) This function and last () look familiar ;) - #dofail will be set to 1 if we have failed in at least one non-warning category dofail=0 #dowarn will be set to 1 if we tripped any warnings dowarn=0 #dofull will be set if we should print a "repoman full" informational message -dofull = options.mode not in ("full", "lfull") +dofull = options.mode != 'full' for x in qacats: if not stats[x]: diff --git a/cnf/sets.conf b/cnf/sets.conf index dd2ccb410..0be4827bc 100644 --- a/cnf/sets.conf +++ b/cnf/sets.conf @@ -64,3 +64,9 @@ files = /lib/modules [downgrade] class = portage.sets.dbapi.DowngradeSet world-candidate = False + +# Installed packages for which there are no visible ebuilds +# corresponding to the same $CATEGORY/$PN:$SLOT. +[unavailable] +class = portage.sets.dbapi.UnavailableSet +world-candidate = False diff --git a/doc/config/sets.docbook b/doc/config/sets.docbook index d993024bd..dc26b1a0c 100644 --- a/doc/config/sets.docbook +++ b/doc/config/sets.docbook @@ -522,6 +522,20 @@ + + portage.sets.dbapi.UnavailableSet + + Package set which contains all installed + packages for which there are no visible ebuilds + corresponding to the same $CATEGORY/$PN:$SLOT. + This class supports the following options: + + metadata-source: Optional, defaults to + "porttree". Specifies the repository to use for getting the metadata + to check. + + + portage.sets.dbapi.DowngradeSet @@ -571,6 +585,7 @@ live-rebuild: uses VariableSet module-rebuild: uses OwnerSet downgrade: uses DowngradeSet + unavailable: uses UnavailableSet Additionally the default configuration includes a multi set section based on the StaticFileSet defaults that creates a set for each diff --git a/man/ebuild.5 b/man/ebuild.5 index 76cd27e68..d438addfb 100644 --- a/man/ebuild.5 +++ b/man/ebuild.5 @@ -196,7 +196,9 @@ arch related flags (see \fBKEYWORDS\fR). Beginning with \fBEAPI 1\fR, it is possible to prefix flags with + or - in order to create default settings that respectively enable or disable the corresponding \fBUSE\fR flags. For details about \fBUSE\fR flag stacking order, refer to the \fBUSE_ORDER\fR -variable in \fBmake.conf\fR(5). +variable in \fBmake.conf\fR(5). Given the default \fBUSE_ORDER\fR setting, +negative IUSE default settings are ineffective since profile and user +configuration settings override them. .TP \fBDEPEND\fR This should contain a list of all packages that are required for the diff --git a/man/emaint.1 b/man/emaint.1 index 31624b208..63854c02e 100644 --- a/man/emaint.1 +++ b/man/emaint.1 @@ -4,10 +4,32 @@ emaint \- performs system health checks and maintenance .SH SYNOPSIS .BR emaint [\fIoptions\fR] -[\fBall\fR | \fBworld\fR] +[\fBall\fR | \fBbinhost\fR | \fBcleanresume\fR | \ +\fBmovebin\fR | \fBmoveinst\fR | \fBworld\fR] .SH DESCRIPTION -.B emaint -checks for and fixes problems in the portage \fIworld\fR file. +The emaint program provides an interface to system health +checks and maintenance. +.SH COMMANDS +.TP +.BR all +Perform all supported commands. +.TP +.BR binhost +Generate a metadata index for binary packages located in \fBPKGDIR\fR (for +download by remote clients). See the \fBPORTAGE_BINHOST\fR documentation in +the \fBmake.conf\fR(5) man page for additional information. +.TP +.BR cleanresume +Discard merge lists saved for the \fBemerge\fR(1) \fB--resume\fR action. +.TP +.BR movebin +Perform package move updates for binary packages located in \fBPKGDIR\fR. +.TP +.BR moveinst +Perform package move updates for installed packages. +.TP +.BR world +Fix problems in the \fIworld\fR file. .SH OPTIONS .TP .B \-c, \-\-check diff --git a/man/repoman.1 b/man/repoman.1 index 14165aae9..c6d83d5cd 100644 --- a/man/repoman.1 +++ b/man/repoman.1 @@ -59,9 +59,6 @@ Show this screen .B full Scan directory tree for QA issues (full listing) .TP -.B last -Remember report from last run -.TP .B help Show this screen .TP @@ -71,9 +68,6 @@ Scan directory tree for QA issues (short listing) .B fix Fix simple QA issues (stray digests, missing digests) .TP -.B lfull -Remember report from last run (full listing) -.TP .B manifest Generate a Manifest (fetches files if necessary) .TP diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index e758e8b35..a1e24b7b3 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -5435,19 +5435,26 @@ class depgraph(object): print "\nemerge: there are no ebuilds to satisfy "+green(xinfo)+"." # Show parent nodes and the argument that pulled them in. + traversed_nodes = set() node = myparent msg = [] while node is not None: + traversed_nodes.add(node) msg.append('(dependency required by "%s" [%s])' % \ (colorize('INFORM', str(node.cpv)), node.type_name)) - parent = None + # When traversing to parents, prefer arguments over packages + # since arguments are root nodes. Never traverse the same + # package twice, in order to prevent an infinite loop. + selected_parent = None for parent in self.digraph.parent_nodes(node): if isinstance(parent, DependencyArg): msg.append('(dependency required by "%s" [argument])' % \ (colorize('INFORM', str(parent)))) - parent = None + selected_parent = None break - node = parent + if parent not in traversed_nodes: + selected_parent = parent + node = selected_parent for line in msg: print line diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index a5bfd78b3..12c303ebb 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -5179,7 +5179,9 @@ def _doebuild_exit_status_check(mydo, settings): "is known to be triggered " + \ "by things such as failed variable " + \ "assignments (bug #190128) or bad substitution " + \ - "errors (bug #200313)." + "errors (bug #200313). This behavior may also be " + \ + "triggered by a corrupt bash binary or a hardware " + \ + "problem such as memory or cpu malfunction." return msg def _doebuild_exit_status_check_and_log(settings, mydo, retval): diff --git a/pym/portage/sets/dbapi.py b/pym/portage/sets/dbapi.py index 877c45cee..65d05a2ae 100644 --- a/pym/portage/sets/dbapi.py +++ b/pym/portage/sets/dbapi.py @@ -179,6 +179,33 @@ class DowngradeSet(PackageSet): singleBuilder = classmethod(singleBuilder) +class UnavailableSet(EverythingSet): + + _operations = ["unmerge"] + + description = "Package set which contains all installed " + \ + "packages for which there are no visible ebuilds " + \ + "corresponding to the same $CATEGORY/$PN:$SLOT." + + def __init__(self, vardb, metadatadb=None): + super(UnavailableSet, self).__init__(vardb) + self._metadatadb = metadatadb + + def _filter(self, atom): + return not self._metadatadb.match(atom) + + def singleBuilder(cls, options, settings, trees): + + metadatadb = options.get("metadata-source", "porttree") + if not metadatadb in trees: + raise SetConfigError(("invalid value '%s' for option " + \ + "metadata-source") % (metadatadb,)) + + return cls(trees["vartree"].dbapi, + metadatadb=trees[metadatadb].dbapi) + + singleBuilder = classmethod(singleBuilder) + class CategorySet(PackageSet): _operations = ["merge", "unmerge"] diff --git a/pym/repoman/utilities.py b/pym/repoman/utilities.py index cee52186e..6003deeac 100644 --- a/pym/repoman/utilities.py +++ b/pym/repoman/utilities.py @@ -211,7 +211,7 @@ def format_qa_output(formatter, stats, fails, dofull, dofail, options, qawarning Returns: None (modifies formatter) """ - full = options.mode in ("full", "lfull") + full = options.mode == 'full' # we only want key value pairs where value > 0 for category, number in \ itertools.ifilter(lambda myitem: myitem[1] > 0, stats.iteritems()):