From 202adf5b9be7f9784d535d7ff551cf888a80f1a0 Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Thu, 25 Dec 2008 13:42:28 +0000 Subject: [PATCH] Merged from trunk -r12288:12302 | 12289 | Rename the PollTask class to AbstractPollTask. | | zmedico | | | 12290 | Move initial signal handlers to the launcher script. | | zmedico | | | 12291 | Make more code conditional on POLLIN events, where | | zmedico | appropriate. | | 12292 | Add SIGUSR1 signal handlers that call pdb.set_trace(). | | zmedico | Thanks to Brian Harring for the suggestion. | | 12293 | Bug #252304 - Restore the -V/--version option. | | zmedico | | | 12294 | Fix broken PATH comparisons when eliminating duplicate | | zmedico | entries inside binarytree.inject(). | | 12295 | Fix PATH comparison in binarytree.inject() some more. | | zmedico | | | 12296 | Bug #251976 - Add a QA_PRESTRIPPED variable for ebuilds to | | zmedico | disable warnings about pre-stripped files. | | 12297 | Replace QA_DT_HASH with QA_PRESTRIPPED where appropriate. | | zmedico | Thanks to Arfrever for reporting. Also, remove array support | | | since bash arrays don't export anyway. | | 12298 | Fix typo. | | zmedico | | | 12299 | Document QA_STRICT_PRESTRIPPED. | | zmedico | | | 12300 | Don't use 'local' builtin outside of a function. | | zmedico | | | 12301 | Bug #252374 - Warn if FEATURES=fakeroot is enabled, but the | | zmedico | fakeroot binary is not installed. | | 12302 | Make BinpkgFetcher use longs instead of floats when | | zmedico | synchronizing timestamps, since it's better not to rely on | | | float comparison here. | svn path=/main/branches/prefix/; revision=12346 --- bin/ebuild | 6 +++ bin/emerge | 22 ++++++++ bin/prepstrip | 21 ++++++-- bin/repoman | 7 +++ man/ebuild.5 | 5 ++ man/make.conf.5 | 4 ++ pym/_emerge/__init__.py | 101 +++++++++++++++++------------------ pym/portage/__init__.py | 5 ++ pym/portage/dbapi/bintree.py | 6 +-- 9 files changed, 117 insertions(+), 60 deletions(-) diff --git a/bin/ebuild b/bin/ebuild index 80c4d744e..1810c32a7 100755 --- a/bin/ebuild +++ b/bin/ebuild @@ -19,6 +19,11 @@ try: except KeyboardInterrupt: sys.exit(1) +def debug_signal(signum, frame): + import pdb + pdb.set_trace() +signal.signal(signal.SIGUSR1, debug_signal) + import optparse import os @@ -167,6 +172,7 @@ def discard_digests(myebuild, mysettings, mydbapi): finally: portage._doebuild_manifest_exempt_depend -= 1 +portage.settings.validate() # generate warning messages if necessary tmpsettings = portage.config(clone=portage.settings) if "test" in pargs: # This variable is a signal to config.regenerate() to diff --git a/bin/emerge b/bin/emerge index 6988d519d..8fed84c58 100755 --- a/bin/emerge +++ b/bin/emerge @@ -3,6 +3,28 @@ # Portage Emerge bits # $Id$ +import os +import sys +# This block ensures that ^C interrupts are handled quietly. +try: + import signal + + def exithandler(signum,frame): + signal.signal(signal.SIGINT, signal.SIG_IGN) + signal.signal(signal.SIGTERM, signal.SIG_IGN) + sys.exit(1) + + signal.signal(signal.SIGINT, exithandler) + signal.signal(signal.SIGTERM, exithandler) + signal.signal(signal.SIGPIPE, signal.SIG_DFL) + +except KeyboardInterrupt: + sys.exit(1) + +def debug_signal(signum, frame): + import pdb + pdb.set_trace() +signal.signal(signal.SIGUSR1, debug_signal) # for an explanation on this logic, see pym/_emerge/__init__.py import os diff --git a/bin/prepstrip b/bin/prepstrip index a31239745..5b8e87d04 100755 --- a/bin/prepstrip +++ b/bin/prepstrip @@ -80,12 +80,25 @@ save_elf_debug() { # They prevent us from getting the splitdebug data. if ! hasq binchecks ${RESTRICT} && \ ! hasq strip ${RESTRICT} ; then - f=$(scanelf -yqRBF '#k%F' -k '!.symtab' "$@") - if [[ -n ${f} ]] ; then + log=$T/scanelf-already-stripped.log + scanelf -yqRBF '#k%F' -k '!.symtab' "$@" | sed -e "s#^$D##" > "$log" + if [[ -n $QA_PRESTRIPPED && -s $log && \ + ${QA_STRICT_PRESTRIPPED-unset} = unset ]] ; then + shopts=$- + set -o noglob + for x in $QA_PRESTRIPPED ; do + sed -e "s#^${x#/}\$##" -i "$log" + done + set +o noglob + set -$shopts + fi + sed -e "/^\$/d" -e "s#^#/#" -i "$log" + if [[ -s $log ]] ; then vecho -e "\a\n" eqawarn "QA Notice: Pre-stripped files found:" - eqawarn "${f}" - echo "${f}" > "${T}"/scanelf-already-stripped.log + eqawarn "$(<"$log")" + else + rm -f "$log" fi fi diff --git a/bin/repoman b/bin/repoman index 6286b2bfe..2a1cafc90 100755 --- a/bin/repoman +++ b/bin/repoman @@ -175,6 +175,9 @@ def ParseArgs(args, qahelp): parser.add_option('-v', '--verbose', dest="verbosity", action='count', help='be very verbose in output', default=0) + parser.add_option('-V', '--version', dest='version', action='store_true', + help='show version info') + parser.add_option('-x', '--xmlparse', dest='xml_parse', action='store_true', default=False, help='forces the metadata.xml parse check to be carried out') @@ -421,6 +424,10 @@ no_exec = frozenset(["Manifest","ChangeLog","metadata.xml"]) options, arguments = ParseArgs(sys.argv, qahelp) +if options.version: + print "Portage", portage.VERSION + sys.exit(0) + # 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). diff --git a/man/ebuild.5 b/man/ebuild.5 index d438addfb..e71d9282a 100644 --- a/man/ebuild.5 +++ b/man/ebuild.5 @@ -500,6 +500,11 @@ The paths may contain regular expressions. This should contain a list of file paths, relative to the image directory, of files that contain .hash sections. The paths may contain regular expressions with escape\-quoted special characters. +.TP +\fBQA_PRESTRIPPED\fR +This should contain a list of file paths, relative to the image directory, of +files that contain pre-stripped binaries. The paths may contain regular +expressions with escape\-quoted special characters. .SH "PORTAGE DECLARATIONS" .TP .B inherit diff --git a/man/make.conf.5 b/man/make.conf.5 index 2f71dac1a..9a0261e25 100644 --- a/man/make.conf.5 +++ b/man/make.conf.5 @@ -595,6 +595,10 @@ settings from ebuilds. See also \fBebuild\fR(5). Set this to cause portage to ignore any \fIQA_DT_HASH\fR override settings from ebuilds. See also \fBebuild\fR(5). .TP +\fBQA_STRICT_PRESTRIPPED = \fI"set"\fR +Set this to cause portage to ignore any \fIQA_PRESTRIPPED\fR override +settings from ebuilds. See also \fBebuild\fR(5). +.TP .B RESUMECOMMAND This variable contains the command used for resuming package sources that have been partially downloaded. It should be defined using the same format diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index 3a4f4d76f..2be2b1f8a 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -3,23 +3,6 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -import sys -# This block ensures that ^C interrupts are handled quietly. -try: - import signal - - def exithandler(signum,frame): - signal.signal(signal.SIGINT, signal.SIG_IGN) - signal.signal(signal.SIGTERM, signal.SIG_IGN) - sys.exit(1) - - signal.signal(signal.SIGINT, exithandler) - signal.signal(signal.SIGTERM, exithandler) - signal.signal(signal.SIGPIPE, signal.SIG_DFL) - -except KeyboardInterrupt: - sys.exit(1) - import array from collections import deque import fcntl @@ -28,6 +11,8 @@ import logging import select import shlex import shutil +import signal +import sys import textwrap import urlparse import weakref @@ -1791,7 +1776,7 @@ class AsynchronousTask(SlotObject): while self._exit_listener_stack: self._exit_listener_stack.pop()(self) -class PollTask(AsynchronousTask): +class AbstractPollTask(AsynchronousTask): __slots__ = ("scheduler",) + \ ("_registered",) @@ -1801,6 +1786,9 @@ class PollTask(AsynchronousTask): _registered_events = PollConstants.POLLIN | PollConstants.POLLHUP | \ _exceptional_events + def _unregister(self): + raise NotImplementedError(self) + def _unregister_if_appropriate(self, event): if self._registered: if event & self._exceptional_events: @@ -1810,7 +1798,7 @@ class PollTask(AsynchronousTask): self._unregister() self.wait() -class PipeReader(PollTask): +class PipeReader(AbstractPollTask): """ Reads output from one or more files and saves it in memory, @@ -1861,23 +1849,24 @@ class PipeReader(PollTask): self._read_data = None def _output_handler(self, fd, event): - files = self.input_files - for f in files.itervalues(): - if fd == f.fileno(): - break - buf = array.array('B') if event & PollConstants.POLLIN: + + for f in self.input_files.itervalues(): + if fd == f.fileno(): + break + + buf = array.array('B') try: buf.fromfile(f, self._bufsize) except EOFError: pass - if buf: - self._read_data.append(buf.tostring()) - else: - self._unregister() - self.wait() + if buf: + self._read_data.append(buf.tostring()) + else: + self._unregister() + self.wait() self._unregister_if_appropriate(event) return self._registered @@ -2048,7 +2037,7 @@ class TaskSequence(CompositeTask): self._final_exit(task) self.wait() -class SubProcess(PollTask): +class SubProcess(AbstractPollTask): __slots__ = ("pid",) + \ ("_files", "_reg_id") @@ -2272,22 +2261,25 @@ class SpawnProcess(SubProcess): return portage.process.spawn(args, **kwargs) def _output_handler(self, fd, event): - files = self._files - buf = array.array('B') + if event & PollConstants.POLLIN: + + files = self._files + buf = array.array('B') try: buf.fromfile(files.process, self._bufsize) except EOFError: pass - if buf: - if not self.background: - buf.tofile(files.stdout) - files.stdout.flush() - buf.tofile(files.log) - files.log.flush() - else: - self._unregister() - self.wait() + + if buf: + if not self.background: + buf.tofile(files.stdout) + files.stdout.flush() + buf.tofile(files.log) + files.log.flush() + else: + self._unregister() + self.wait() self._unregister_if_appropriate(event) return self._registered @@ -2298,18 +2290,20 @@ class SpawnProcess(SubProcess): the only purpose of the pipe is to allow the scheduler to monitor the process from inside a poll() loop. """ - files = self._files - buf = array.array('B') + if event & PollConstants.POLLIN: + + buf = array.array('B') try: - buf.fromfile(files.process, self._bufsize) + buf.fromfile(self._files.process, self._bufsize) except EOFError: pass - if buf: - pass - else: - self._unregister() - self.wait() + + if buf: + pass + else: + self._unregister() + self.wait() self._unregister_if_appropriate(event) return self._registered @@ -2934,9 +2928,10 @@ class EbuildMetadataPhase(SubProcess): portage.process.spawned_pids.remove(self.pid) def _output_handler(self, fd, event): - files = self._files + if event & PollConstants.POLLIN: - self._raw_metadata.append(files.ebuild.read()) + self._raw_metadata.append(self._files.ebuild.read()) + if not self._raw_metadata[-1] or event & PollConstants.POLLHUP: # Split lines here so they can be counted inside _set_returncode(). self._raw_metadata = "".join(self._raw_metadata).splitlines() @@ -3567,12 +3562,12 @@ class BinpkgFetcher(SpawnProcess): remote_mtime = bintree._remotepkgs[self.pkg.cpv].get("MTIME") if remote_mtime is not None: try: - remote_mtime = float(remote_mtime) + remote_mtime = long(remote_mtime) except ValueError: pass else: try: - local_mtime = os.stat(self.pkg_path).st_mtime + local_mtime = long(os.stat(self.pkg_path).st_mtime) except OSError: pass else: diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 816f84ce0..758bc5814 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -1815,6 +1815,11 @@ class config(object): writemsg("!!! /etc/portage/profile/virtuals. Please move it to\n") writemsg("!!! this new location.\n\n") + if "fakeroot" in self.features and \ + not portage.process.fakeroot_capable: + writemsg("!!! FEATURES=fakeroot is enabled, but the " + \ + "fakeroot binary is not installed.\n", noiselevel=-1) + def loadVirtuals(self,root): """Not currently used by portage.""" writemsg("DEPRECATED: portage.config.loadVirtuals\n") diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py index f8485f340..532062e2d 100644 --- a/pym/portage/dbapi/bintree.py +++ b/pym/portage/dbapi/bintree.py @@ -871,14 +871,14 @@ class binarytree(object): return # If found, remove package(s) with duplicate path. - path = d.get("PATH") + path = d.get("PATH", "") for i in xrange(len(pkgindex.packages) - 1, -1, -1): d2 = pkgindex.packages[i] - if path is not None and path == d2.get("PATH"): + if path and path == d2.get("PATH"): # Handle path collisions in $PKGDIR/All # when CPV is not identical. del pkgindex.packages[i] - elif cpv == d2.get("CPV") and path == d2.get("PATH"): + elif cpv == d2.get("CPV") and path == d2.get("PATH", ""): del pkgindex.packages[i] pkgindex.packages.append(d) -- 2.26.2