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
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
# 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
# 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
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')
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).
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
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
# 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
import select
import shlex
import shutil
+import signal
+import sys
import textwrap
import urlparse
import weakref
while self._exit_listener_stack:
self._exit_listener_stack.pop()(self)
-class PollTask(AsynchronousTask):
+class AbstractPollTask(AsynchronousTask):
__slots__ = ("scheduler",) + \
("_registered",)
_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:
self._unregister()
self.wait()
-class PipeReader(PollTask):
+class PipeReader(AbstractPollTask):
"""
Reads output from one or more files and saves it in memory,
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
self._final_exit(task)
self.wait()
-class SubProcess(PollTask):
+class SubProcess(AbstractPollTask):
__slots__ = ("pid",) + \
("_files", "_reg_id")
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
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
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()
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:
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")
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)