Merged from trunk -r12288:12302
authorFabian Groffen <grobian@gentoo.org>
Thu, 25 Dec 2008 13:42:28 +0000 (13:42 -0000)
committerFabian Groffen <grobian@gentoo.org>
Thu, 25 Dec 2008 13:42:28 +0000 (13:42 -0000)
   | 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
bin/emerge
bin/prepstrip
bin/repoman
man/ebuild.5
man/make.conf.5
pym/_emerge/__init__.py
pym/portage/__init__.py
pym/portage/dbapi/bintree.py

index 80c4d744e7e433d1f0344914d994aaab2ea67976..1810c32a7dcce5eb8ab7fa2c89ff77546ef9498f 100755 (executable)
@@ -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
index 6988d519d34a552ffccfc514bd6dbf09f394e94d..8fed84c58be0e4c1478180f1fcc0c5d0f802f7fe 100755 (executable)
@@ -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
index a312397458f23d3950313f022eb4229b87d28710..5b8e87d047ab834389b3165b5b9f68e9cb280046 100755 (executable)
@@ -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
 
index 6286b2bfedb61c44e8888afd81f9ed6551fe34c8..2a1cafc900b66b123fad30a1c9a5abc701bffc15 100755 (executable)
@@ -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).
index d438addfb65fe1823ccd3c0efc997824c4993cf2..e71d9282a00aac65701c4841172f17bc0d095fce 100644 (file)
@@ -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
index 2f71dac1a369d28b2857f695f884a8de6f8aed09..9a0261e2553fbe178461f25bb335d302795ca95e 100644 (file)
@@ -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
index 3a4f4d76feee909406e22a598e1df8e875c6ab7b..2be2b1f8a9391a94f4e532681373cf3e70481805 100644 (file)
@@ -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:
index 816f84ce0221879e9c782448605a7e59f8fce7ca..758bc5814b7465e0424dc81f3621b1c29456c8ce 100644 (file)
@@ -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")
index f8485f340450eefa2482a085bd7c6d524b1a7c73..532062e2d7b0d775ba9741f68bfe2fc18ca37756 100644 (file)
@@ -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)