aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorFabian Groffen <grobian@gentoo.org>2014-09-28 19:52:16 +0200
committerFabian Groffen <grobian@gentoo.org>2014-09-28 19:52:16 +0200
commit990c5f4896b309fdcaf1dbbb5779177ecfcf6e74 (patch)
treef54ebb8d5bcbfea1986b9c73eee0ec3c5b390577 /bin
parentinstall_qa_check_macho: introduce QA_IGNORE_INSTALL_NAME_FILES (diff)
parentUse a single grep call for gcc warning checks (diff)
downloadportage-990c5f4896b309fdcaf1dbbb5779177ecfcf6e74.tar.gz
portage-990c5f4896b309fdcaf1dbbb5779177ecfcf6e74.tar.bz2
portage-990c5f4896b309fdcaf1dbbb5779177ecfcf6e74.zip
Merge remote-tracking branch 'overlays-gentoo-org/master' into prefix
Conflicts: bin/ebuild-helpers/emake bin/misc-functions.sh bin/portageq doc/Makefile pym/_emerge/EbuildBuild.py pym/portage/const.py pym/portage/dbapi/vartree.py pym/portage/package/ebuild/doebuild.py
Diffstat (limited to 'bin')
-rwxr-xr-xbin/archive-conf4
-rwxr-xr-xbin/binhost-snapshot4
-rwxr-xr-xbin/chpathtool.py8
-rwxr-xr-xbin/clean_locks4
-rwxr-xr-xbin/deprecated-path28
-rwxr-xr-xbin/dispatch-conf4
-rwxr-xr-xbin/ebuild4
-rwxr-xr-xbin/ebuild-helpers/emake4
-rwxr-xr-xbin/ebuild-helpers/xattr/install27
-rwxr-xr-xbin/ebuild-ipc.py20
-rwxr-xr-xbin/ebuild.sh131
-rwxr-xr-xbin/egencache4
-rwxr-xr-xbin/emaint4
-rwxr-xr-xbin/emerge14
-rwxr-xr-xbin/emerge-webrsync4
-rwxr-xr-xbin/env-update4
-rwxr-xr-xbin/fixpackages4
-rwxr-xr-xbin/glsa-check4
-rw-r--r--bin/install-qa-check.d/05double-D17
-rw-r--r--bin/install-qa-check.d/05prefix118
-rw-r--r--bin/install-qa-check.d/10executable-issues140
-rw-r--r--bin/install-qa-check.d/10ignored-flags99
-rw-r--r--bin/install-qa-check.d/20deprecated-directories18
-rw-r--r--bin/install-qa-check.d/20runtime-directories26
-rw-r--r--bin/install-qa-check.d/60bash-completion130
-rw-r--r--bin/install-qa-check.d/60openrc41
-rw-r--r--bin/install-qa-check.d/60pkgconfig15
-rw-r--r--bin/install-qa-check.d/60pngfix35
-rw-r--r--bin/install-qa-check.d/60systemd25
-rw-r--r--bin/install-qa-check.d/60udev21
-rw-r--r--bin/install-qa-check.d/80libraries167
-rw-r--r--bin/install-qa-check.d/80multilib-strict50
-rw-r--r--bin/install-qa-check.d/90gcc-warnings168
-rw-r--r--bin/install-qa-check.d/90world-writable27
-rw-r--r--bin/misc-functions.sh800
-rw-r--r--bin/phase-functions.sh153
-rw-r--r--bin/phase-helpers.sh40
-rwxr-xr-xbin/portageq339
-rwxr-xr-xbin/quickpkg8
-rwxr-xr-xbin/regenworld4
-rwxr-xr-xbin/repoman32
-rw-r--r--bin/save-ebuild-env.sh2
-rwxr-xr-xbin/xattr-helper.py6
43 files changed, 1630 insertions, 1127 deletions
diff --git a/bin/archive-conf b/bin/archive-conf
index 599e5693b..b427b8803 100755
--- a/bin/archive-conf
+++ b/bin/archive-conf
@@ -14,8 +14,8 @@ from __future__ import print_function
import sys
from os import path as osp
-pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
-sys.path.insert(0, pym_path)
+if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
portage._internal_caller = True
diff --git a/bin/binhost-snapshot b/bin/binhost-snapshot
index ce156a422..f289394ab 100755
--- a/bin/binhost-snapshot
+++ b/bin/binhost-snapshot
@@ -13,8 +13,8 @@ except ImportError:
from urlparse import urlparse
from os import path as osp
-pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
-sys.path.insert(0, pym_path)
+if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
portage._internal_caller = True
from portage.util._argparse import ArgumentParser
diff --git a/bin/chpathtool.py b/bin/chpathtool.py
index 7e9f26042..c4716d97d 100755
--- a/bin/chpathtool.py
+++ b/bin/chpathtool.py
@@ -2,9 +2,11 @@
# Copyright 2011-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-"""Helper tool for converting installed files to custom prefixes.
+doc = """Helper tool for converting installed files to custom prefixes.
In other words, eprefixy $D for Gentoo/Prefix."""
+__doc__ = doc
+
import io
import os
@@ -152,7 +154,7 @@ def chpath_inplace_symlink(filename, st, old, new):
def main(argv):
- parser = ArgumentParser(description=__doc__)
+ parser = ArgumentParser(description=doc)
try:
parser.add_argument('location', default=None,
help='root directory (e.g. $D)')
@@ -166,7 +168,7 @@ def main(argv):
except OptionError:
# Argument parsing compatibility for Python 2.6 using optparse.
if sys.hexversion < 0x2070000:
- parser = OptionParser(description=__doc__,
+ parser = OptionParser(description=doc,
usage="usage: %prog [-h] location old new\n\n" + \
" location: root directory (e.g. $D)\n" + \
" old: original build prefix (e.g. /)\n" + \
diff --git a/bin/clean_locks b/bin/clean_locks
index 73213b52b..d44162075 100755
--- a/bin/clean_locks
+++ b/bin/clean_locks
@@ -6,8 +6,8 @@ from __future__ import print_function
import sys, errno
from os import path as osp
-pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
-sys.path.insert(0, pym_path)
+if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
portage._internal_caller = True
diff --git a/bin/deprecated-path b/bin/deprecated-path
new file mode 100755
index 000000000..b8aaadbda
--- /dev/null
+++ b/bin/deprecated-path
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Copyright 2014 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# Author:
+#
+
+source /lib/gentoo/functions.sh
+
+scriptpath=${BASH_SOURCE[0]}
+scriptname=${scriptpath##*/}
+
+IFS=':'
+
+for path in ${PATH}; do
+ [[ -x ${path}/${scriptname} ]] || continue
+ [[ ${path}/${scriptname} -ef ${scriptpath} ]] && continue
+
+ unset IFS
+ eerror "Deprecation warning: Calling ${scriptname} from wrong path: '${scriptpath}'"
+ eerror "Correct path should be '${path}/${scriptname}', Please correct your scripts or file a bug with the maintainer..."
+ exec "${path}/${scriptname}" "$@"
+done
+
+unset IFS
+
+eerror "ERROR: portage file: deprecated-path: Failed to locate ${scriptname} in PATH"
+eerror "PATH: ${PATH}"
+exit 1
diff --git a/bin/dispatch-conf b/bin/dispatch-conf
index a1fe2061c..6f06b35a0 100755
--- a/bin/dispatch-conf
+++ b/bin/dispatch-conf
@@ -17,8 +17,8 @@ from stat import ST_GID, ST_MODE, ST_UID
from random import random
import atexit, re, shutil, stat, sys
from os import path as osp
-pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
-sys.path.insert(0, pym_path)
+if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
portage._internal_caller = True
from portage import os
diff --git a/bin/ebuild b/bin/ebuild
index bb0d79a75..aa35bb620 100755
--- a/bin/ebuild
+++ b/bin/ebuild
@@ -38,8 +38,8 @@ signal.signal(debug_signum, debug_signal)
import io
import os
from os import path as osp
-pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
-sys.path.insert(0, pym_path)
+if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
portage._internal_caller = True
from portage import os
diff --git a/bin/ebuild-helpers/emake b/bin/ebuild-helpers/emake
index 60286ec9d..dcb64a399 100755
--- a/bin/ebuild-helpers/emake
+++ b/bin/ebuild-helpers/emake
@@ -13,7 +13,7 @@ source "${PORTAGE_BIN_PATH:-@PORTAGE_BASE@/bin}"/isolated-functions.sh
if [[ $PORTAGE_QUIET != 1 ]] ; then
(
- for arg in ${MAKE:-make} $MAKEOPTS $EXTRA_EMAKE "$@" ; do
+ for arg in ${MAKE:-make} $MAKEOPTS "$@" $EXTRA_EMAKE ; do
[[ ${arg} == *" "* ]] \
&& printf "'%s' " "${arg}" \
|| printf "%s " "${arg}"
@@ -22,7 +22,7 @@ if [[ $PORTAGE_QUIET != 1 ]] ; then
) >&2
fi
-${MAKE:-make} SHELL="${BASH:-/bin/bash}" ${MAKEOPTS} ${EXTRA_EMAKE} "$@"
+${MAKE:-make} SHELL="${BASH:-/bin/bash}" ${MAKEOPTS} "$@" ${EXTRA_EMAKE}
ret=$?
[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit $ret
diff --git a/bin/ebuild-helpers/xattr/install b/bin/ebuild-helpers/xattr/install
index b1d23159a..233459fcc 100755
--- a/bin/ebuild-helpers/xattr/install
+++ b/bin/ebuild-helpers/xattr/install
@@ -4,9 +4,32 @@
PORTAGE_BIN_PATH=${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}
PORTAGE_PYM_PATH=${PORTAGE_PYM_PATH:-/usr/lib/portage/pym}
+INSTALL_XATTR=${EPREFIX}/usr/bin/install-xattr
# Use safe cwd, avoiding unsafe import for bug #469338.
export __PORTAGE_HELPER_CWD=${PWD}
cd "${PORTAGE_PYM_PATH}"
export __PORTAGE_HELPER_PATH=${BASH_SOURCE[0]}
-PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} \
- exec "${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}/install.py" "$@"
+
+if [[ ${PORTAGE_INSTALL_XATTR_IMPLEMENTATION} == "c" ]]; then
+ implementation="c"
+elif [[ ${PORTAGE_INSTALL_XATTR_IMPLEMENTATION} == "python" ]]; then
+ implementation="python"
+else
+ # If PORTAGE_INSTALL_XATTR_IMPLEMENTATION is unset or not set to "c" or "python"
+ # then we'll autodetect, preferring "c" but falling back on "python"
+ if [[ -x "${INSTALL_XATTR}" ]]; then
+ implementation="c"
+ else
+ implementation="python"
+ fi
+fi
+
+if [[ "${implementation}" == "c" ]]; then
+ exec "${INSTALL_XATTR}" "$@"
+elif [[ "${implementation}" == "python" ]]; then
+ PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} \
+ exec "${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}/install.py" "$@"
+else
+ echo "Unknown implementation for PORTAGE_INSTALL_XATTR_IMPLEMENTATION"
+ exit -1
+fi
diff --git a/bin/ebuild-ipc.py b/bin/ebuild-ipc.py
index 1c7290fd3..5a702417e 100755
--- a/bin/ebuild-ipc.py
+++ b/bin/ebuild-ipc.py
@@ -24,15 +24,21 @@ else:
signal.signal(debug_signum, debug_signal)
-# Avoid sandbox violations after python upgrade.
-pym_path = os.path.join(os.path.dirname(
- os.path.dirname(os.path.realpath(__file__))), "pym")
+if os.path.isfile(os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), ".portage_not_installed")):
+ pym_paths = [os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "pym")]
+ sys.path.insert(0, pym_paths[0])
+else:
+ import distutils.sysconfig
+ pym_paths = [os.path.join(distutils.sysconfig.get_python_lib(), x) for x in ("_emerge", "portage")]
+# Avoid sandbox violations after Python upgrade.
if os.environ.get("SANDBOX_ON") == "1":
sandbox_write = os.environ.get("SANDBOX_WRITE", "").split(":")
- if pym_path not in sandbox_write:
- sandbox_write.append(pym_path)
- os.environ["SANDBOX_WRITE"] = \
- ":".join(filter(None, sandbox_write))
+ for pym_path in pym_paths:
+ if pym_path not in sandbox_write:
+ sandbox_write.append(pym_path)
+ os.environ["SANDBOX_WRITE"] = ":".join(filter(None, sandbox_write))
+ del pym_path, sandbox_write
+del pym_paths
import portage
portage._internal_caller = True
diff --git a/bin/ebuild.sh b/bin/ebuild.sh
index ef19e5ec7..103caee1b 100755
--- a/bin/ebuild.sh
+++ b/bin/ebuild.sh
@@ -230,10 +230,10 @@ inherit() {
__export_funcs_var=__export_functions_$ECLASS_DEPTH
unset $__export_funcs_var
- if [ "${EBUILD_PHASE}" != "depend" ] && \
- [ "${EBUILD_PHASE}" != "nofetch" ] && \
- [[ ${EBUILD_PHASE} != *rm ]] && \
- [[ ${EMERGE_FROM} != "binary" ]] ; then
+ if [[ ${EBUILD_PHASE} != depend && ${EBUILD_PHASE} != nofetch && \
+ ${EBUILD_PHASE} != *rm && ${EMERGE_FROM} != "binary" && \
+ -z ${_IN_INSTALL_QA_CHECK} ]]
+ then
# This is disabled in the *rm phases because they frequently give
# false alarms due to INHERITED in /var/db/pkg being outdated
# in comparison the the eclasses from the portage tree. It's
@@ -256,70 +256,75 @@ inherit() {
debug-print "inherit: $1 -> $location"
[[ -z ${location} ]] && die "${1}.eclass could not be found by inherit()"
- #We need to back up the values of *DEPEND to B_*DEPEND
- #(if set).. and then restore them after the inherit call.
-
- #turn off glob expansion
- set -f
-
- # Retain the old data and restore it later.
- unset B_IUSE B_REQUIRED_USE B_DEPEND B_RDEPEND B_PDEPEND B_HDEPEND
- [ "${IUSE+set}" = set ] && B_IUSE="${IUSE}"
- [ "${REQUIRED_USE+set}" = set ] && B_REQUIRED_USE="${REQUIRED_USE}"
- [ "${DEPEND+set}" = set ] && B_DEPEND="${DEPEND}"
- [ "${RDEPEND+set}" = set ] && B_RDEPEND="${RDEPEND}"
- [ "${PDEPEND+set}" = set ] && B_PDEPEND="${PDEPEND}"
- [ "${HDEPEND+set}" = set ] && B_HDEPEND="${HDEPEND}"
- unset IUSE REQUIRED_USE DEPEND RDEPEND PDEPEND HDEPEND
- #turn on glob expansion
- set +f
+ # inherits in QA checks can't handle metadata assignments
+ if [[ -z ${_IN_INSTALL_QA_CHECK} ]]; then
+ #We need to back up the values of *DEPEND to B_*DEPEND
+ #(if set).. and then restore them after the inherit call.
+
+ #turn off glob expansion
+ set -f
+
+ # Retain the old data and restore it later.
+ unset B_IUSE B_REQUIRED_USE B_DEPEND B_RDEPEND B_PDEPEND B_HDEPEND
+ [ "${IUSE+set}" = set ] && B_IUSE="${IUSE}"
+ [ "${REQUIRED_USE+set}" = set ] && B_REQUIRED_USE="${REQUIRED_USE}"
+ [ "${DEPEND+set}" = set ] && B_DEPEND="${DEPEND}"
+ [ "${RDEPEND+set}" = set ] && B_RDEPEND="${RDEPEND}"
+ [ "${PDEPEND+set}" = set ] && B_PDEPEND="${PDEPEND}"
+ [ "${HDEPEND+set}" = set ] && B_HDEPEND="${HDEPEND}"
+ unset IUSE REQUIRED_USE DEPEND RDEPEND PDEPEND HDEPEND
+ #turn on glob expansion
+ set +f
+ fi
__qa_source "$location" || die "died sourcing $location in inherit()"
- #turn off glob expansion
- set -f
-
- # If each var has a value, append it to the global variable E_* to
- # be applied after everything is finished. New incremental behavior.
- [ "${IUSE+set}" = set ] && E_IUSE+="${E_IUSE:+ }${IUSE}"
- [ "${REQUIRED_USE+set}" = set ] && E_REQUIRED_USE+="${E_REQUIRED_USE:+ }${REQUIRED_USE}"
- [ "${DEPEND+set}" = set ] && E_DEPEND+="${E_DEPEND:+ }${DEPEND}"
- [ "${RDEPEND+set}" = set ] && E_RDEPEND+="${E_RDEPEND:+ }${RDEPEND}"
- [ "${PDEPEND+set}" = set ] && E_PDEPEND+="${E_PDEPEND:+ }${PDEPEND}"
- [ "${HDEPEND+set}" = set ] && E_HDEPEND+="${E_HDEPEND:+ }${HDEPEND}"
-
- [ "${B_IUSE+set}" = set ] && IUSE="${B_IUSE}"
- [ "${B_IUSE+set}" = set ] || unset IUSE
-
- [ "${B_REQUIRED_USE+set}" = set ] && REQUIRED_USE="${B_REQUIRED_USE}"
- [ "${B_REQUIRED_USE+set}" = set ] || unset REQUIRED_USE
-
- [ "${B_DEPEND+set}" = set ] && DEPEND="${B_DEPEND}"
- [ "${B_DEPEND+set}" = set ] || unset DEPEND
-
- [ "${B_RDEPEND+set}" = set ] && RDEPEND="${B_RDEPEND}"
- [ "${B_RDEPEND+set}" = set ] || unset RDEPEND
-
- [ "${B_PDEPEND+set}" = set ] && PDEPEND="${B_PDEPEND}"
- [ "${B_PDEPEND+set}" = set ] || unset PDEPEND
-
- [ "${B_HDEPEND+set}" = set ] && HDEPEND="${B_HDEPEND}"
- [ "${B_HDEPEND+set}" = set ] || unset HDEPEND
-
- #turn on glob expansion
- set +f
+ if [[ -z ${_IN_INSTALL_QA_CHECK} ]]; then
+ #turn off glob expansion
+ set -f
+
+ # If each var has a value, append it to the global variable E_* to
+ # be applied after everything is finished. New incremental behavior.
+ [ "${IUSE+set}" = set ] && E_IUSE+="${E_IUSE:+ }${IUSE}"
+ [ "${REQUIRED_USE+set}" = set ] && E_REQUIRED_USE+="${E_REQUIRED_USE:+ }${REQUIRED_USE}"
+ [ "${DEPEND+set}" = set ] && E_DEPEND+="${E_DEPEND:+ }${DEPEND}"
+ [ "${RDEPEND+set}" = set ] && E_RDEPEND+="${E_RDEPEND:+ }${RDEPEND}"
+ [ "${PDEPEND+set}" = set ] && E_PDEPEND+="${E_PDEPEND:+ }${PDEPEND}"
+ [ "${HDEPEND+set}" = set ] && E_HDEPEND+="${E_HDEPEND:+ }${HDEPEND}"
+
+ [ "${B_IUSE+set}" = set ] && IUSE="${B_IUSE}"
+ [ "${B_IUSE+set}" = set ] || unset IUSE
+
+ [ "${B_REQUIRED_USE+set}" = set ] && REQUIRED_USE="${B_REQUIRED_USE}"
+ [ "${B_REQUIRED_USE+set}" = set ] || unset REQUIRED_USE
+
+ [ "${B_DEPEND+set}" = set ] && DEPEND="${B_DEPEND}"
+ [ "${B_DEPEND+set}" = set ] || unset DEPEND
+
+ [ "${B_RDEPEND+set}" = set ] && RDEPEND="${B_RDEPEND}"
+ [ "${B_RDEPEND+set}" = set ] || unset RDEPEND
+
+ [ "${B_PDEPEND+set}" = set ] && PDEPEND="${B_PDEPEND}"
+ [ "${B_PDEPEND+set}" = set ] || unset PDEPEND
+
+ [ "${B_HDEPEND+set}" = set ] && HDEPEND="${B_HDEPEND}"
+ [ "${B_HDEPEND+set}" = set ] || unset HDEPEND
+
+ #turn on glob expansion
+ set +f
+
+ if [[ -n ${!__export_funcs_var} ]] ; then
+ for x in ${!__export_funcs_var} ; do
+ debug-print "EXPORT_FUNCTIONS: $x -> ${ECLASS}_$x"
+ declare -F "${ECLASS}_$x" >/dev/null || \
+ die "EXPORT_FUNCTIONS: ${ECLASS}_$x is not defined"
+ eval "$x() { ${ECLASS}_$x \"\$@\" ; }" > /dev/null
+ done
+ fi
+ unset $__export_funcs_var
- if [[ -n ${!__export_funcs_var} ]] ; then
- for x in ${!__export_funcs_var} ; do
- debug-print "EXPORT_FUNCTIONS: $x -> ${ECLASS}_$x"
- declare -F "${ECLASS}_$x" >/dev/null || \
- die "EXPORT_FUNCTIONS: ${ECLASS}_$x is not defined"
- eval "$x() { ${ECLASS}_$x \"\$@\" ; }" > /dev/null
- done
+ has $1 $INHERITED || export INHERITED="$INHERITED $1"
fi
- unset $__export_funcs_var
-
- has $1 $INHERITED || export INHERITED="$INHERITED $1"
shift
done
diff --git a/bin/egencache b/bin/egencache
index 4ec4108e8..e2f57a58a 100755
--- a/bin/egencache
+++ b/bin/egencache
@@ -41,8 +41,8 @@ import textwrap
import re
from os import path as osp
-pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
-sys.path.insert(0, pym_path)
+if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
portage._internal_caller = True
from portage import os, _encodings, _unicode_encode, _unicode_decode
diff --git a/bin/emaint b/bin/emaint
index 00711aa81..784d8613e 100755
--- a/bin/emaint
+++ b/bin/emaint
@@ -26,8 +26,8 @@ except KeyboardInterrupt:
sys.exit(1)
from os import path as osp
-pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
-sys.path.insert(0, pym_path)
+if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
portage._internal_caller = True
from portage.emaint.main import emaint_main
diff --git a/bin/emerge b/bin/emerge
index 273c0db04..ae6b1c131 100755
--- a/bin/emerge
+++ b/bin/emerge
@@ -36,21 +36,27 @@ try:
signal.signal(debug_signum, debug_signal)
from os import path as osp
- pym_path = osp.join(osp.dirname(osp.dirname(
- osp.realpath(__file__))), "pym")
- sys.path.insert(0, pym_path)
+ if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
portage._internal_caller = True
portage._disable_legacy_globals()
from _emerge.main import emerge_main
if __name__ == "__main__":
- from portage.exception import ParseError, PermissionDenied
+ from portage.exception import IsADirectory, ParseError, \
+ PermissionDenied
try:
retval = emerge_main()
except PermissionDenied as e:
sys.stderr.write("Permission denied: '%s'\n" % str(e))
sys.exit(e.errno)
+ except IsADirectory as e:
+ sys.stderr.write("'%s' is a directory, but should be a file!\n"
+ "See portage man page for information on "
+ "which files may be directories.\n" %
+ str(e))
+ sys.exit(e.errno)
except ParseError as e:
sys.stderr.write("%s\n" % str(e))
sys.exit(1)
diff --git a/bin/emerge-webrsync b/bin/emerge-webrsync
index 340c35915..dbcc294cf 100755
--- a/bin/emerge-webrsync
+++ b/bin/emerge-webrsync
@@ -257,12 +257,12 @@ sync_local() {
if has metadata-transfer ${FEATURES} ; then
__vecho "Updating cache ..."
- "${PORTAGE_BIN_PATH}/emerge" --metadata
+ emerge --metadata
fi
local post_sync=${PORTAGE_CONFIGROOT}etc/portage/bin/post_sync
[ -x "${post_sync}" ] && "${post_sync}"
# --quiet suppresses output if there are no relevant news items
- has news ${FEATURES} && "${PORTAGE_BIN_PATH}/emerge" --check-news --quiet
+ has news ${FEATURES} && emerge --check-news --quiet
return 0
}
diff --git a/bin/env-update b/bin/env-update
index aefbf21b6..5b99e66dd 100755
--- a/bin/env-update
+++ b/bin/env-update
@@ -26,8 +26,8 @@ if len(sys.argv) > 1:
usage(1)
from os import path as osp
-pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
-sys.path.insert(0, pym_path)
+if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
portage._internal_caller = True
diff --git a/bin/fixpackages b/bin/fixpackages
index a4e411da5..bc242b794 100755
--- a/bin/fixpackages
+++ b/bin/fixpackages
@@ -8,8 +8,8 @@ import os
import sys
from os import path as osp
-pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
-sys.path.insert(0, pym_path)
+if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
portage._internal_caller = True
from portage import os
diff --git a/bin/glsa-check b/bin/glsa-check
index 85d4c4149..78728d43c 100755
--- a/bin/glsa-check
+++ b/bin/glsa-check
@@ -8,8 +8,8 @@ import sys
import codecs
from os import path as osp
-pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
-sys.path.insert(0, pym_path)
+if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
portage._internal_caller = True
from portage import os
diff --git a/bin/install-qa-check.d/05double-D b/bin/install-qa-check.d/05double-D
new file mode 100644
index 000000000..1634afd78
--- /dev/null
+++ b/bin/install-qa-check.d/05double-D
@@ -0,0 +1,17 @@
+# Check for accidential install into ${D}/${D}
+
+DD_check() {
+ if [[ -d ${D%/}${D} ]] ; then
+ local -i INSTALLTOD=0
+ while read -r -d $'\0' i ; do
+ eqawarn "QA Notice: /${i##${D%/}${D}} installed in \${D}/\${D}"
+ ((INSTALLTOD++))
+ done < <(find "${D%/}${D}" -print0)
+ die "Aborting due to QA concerns: ${INSTALLTOD} files installed in ${D%/}${D}"
+ fi
+}
+
+DD_check
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/bin/install-qa-check.d/05prefix b/bin/install-qa-check.d/05prefix
new file mode 100644
index 000000000..32561e263
--- /dev/null
+++ b/bin/install-qa-check.d/05prefix
@@ -0,0 +1,118 @@
+# Prefix specific QA checks
+
+install_qa_check_prefix() {
+ [[ ${ED} == ${D} ]] && return
+
+ if [[ -d ${ED}/${D} ]] ; then
+ find "${ED}/${D}" | \
+ while read i ; do
+ eqawarn "QA Notice: /${i##${ED}/${D}} installed in \${ED}/\${D}"
+ done
+ die "Aborting due to QA concerns: files installed in ${ED}/${D}"
+ fi
+
+ if [[ -d ${ED}/${EPREFIX} ]] ; then
+ find "${ED}/${EPREFIX}/" | \
+ while read i ; do
+ eqawarn "QA Notice: ${i#${D}} double prefix"
+ done
+ die "Aborting due to QA concerns: double prefix files installed"
+ fi
+
+ if [[ -d ${D} ]] ; then
+ INSTALLTOD=$(find ${D%/} | egrep -v "^${ED}" | sed -e "s|^${D%/}||" | awk '{if (length($0) <= length("'"${EPREFIX}"'")) { if (substr("'"${EPREFIX}"'", 1, length($0)) != $0) {print $0;} } else if (substr($0, 1, length("'"${EPREFIX}"'")) != "'"${EPREFIX}"'") {print $0;} }')
+ if [[ -n ${INSTALLTOD} ]] ; then
+ eqawarn "QA Notice: the following files are outside of the prefix:"
+ eqawarn "${INSTALLTOD}"
+ die "Aborting due to QA concerns: there are files installed outside the prefix"
+ fi
+ fi
+
+ # all further checks rely on ${ED} existing
+ [[ -d ${ED} ]] || return
+
+ # check shebangs, bug #282539
+ rm -f "${T}"/non-prefix-shebangs-errs
+ local WHITELIST=" /usr/bin/env "
+ # this is hell expensive, but how else?
+ find "${ED}" -executable \! -type d -print0 \
+ | xargs -0 grep -H -n -m1 "^#!" \
+ | while read f ;
+ do
+ local fn=${f%%:*}
+ local pos=${f#*:} ; pos=${pos%:*}
+ local line=${f##*:}
+ # shebang always appears on the first line ;)
+ [[ ${pos} != 1 ]] && continue
+ local oldIFS=${IFS}
+ IFS=$'\r'$'\n'$'\t'" "
+ line=( ${line#"#!"} )
+ IFS=${oldIFS}
+ [[ ${WHITELIST} == *" ${line[0]} "* ]] && continue
+ local fp=${fn#${D}} ; fp=/${fp%/*}
+ # line[0] can be an absolutised path, bug #342929
+ local eprefix=$(canonicalize ${EPREFIX})
+ local rf=${fn}
+ # in case we deal with a symlink, make sure we don't replace it
+ # with a real file (sed -i does that)
+ if [[ -L ${fn} ]] ; then
+ rf=$(readlink ${fn})
+ [[ ${rf} != /* ]] && rf=${fn%/*}/${rf}
+ # ignore symlinks pointing to outside prefix
+ # as seen in sys-devel/native-cctools
+ [[ $(canonicalize "/${rf#${D}}") != ${eprefix}/* ]] && continue
+ fi
+ # does the shebang start with ${EPREFIX}, and does it exist?
+ if [[ ${line[0]} == ${EPREFIX}/* || ${line[0]} == ${eprefix}/* ]] ; then
+ if [[ ! -e ${ROOT%/}${line[0]} && ! -e ${D%/}${line[0]} ]] ; then
+ # hmm, refers explicitly to $EPREFIX, but doesn't exist,
+ # if it's in PATH that's wrong in any case
+ if [[ ":${PATH}:" == *":${fp}:"* ]] ; then
+ echo "${fn#${D}}:${line[0]} (explicit EPREFIX but target not found)" \
+ >> "${T}"/non-prefix-shebangs-errs
+ else
+ eqawarn "${fn#${D}} has explicit EPREFIX in shebang but target not found (${line[0]})"
+ fi
+ fi
+ continue
+ fi
+ # unprefixed shebang, is the script directly in $PATH or an init
+ # script?
+ if [[ ":${PATH}:${EPREFIX}/etc/init.d:" == *":${fp}:"* ]] ; then
+ if [[ -e ${EROOT}${line[0]} || -e ${ED}${line[0]} ]] ; then
+ # is it unprefixed, but we can just fix it because a
+ # prefixed variant exists
+ eqawarn "prefixing shebang of ${fn#${D}}"
+ # statement is made idempotent on purpose, because
+ # symlinks may point to the same target, and hence the
+ # same real file may be sedded multiple times since we
+ # read the shebangs in one go upfront for performance
+ # reasons
+ sed -i -e '1s:^#! \?'"${line[0]}"':#!'"${EPREFIX}"${line[0]}':' "${rf}"
+ continue
+ else
+ # this is definitely wrong: script in $PATH and invalid shebang
+ echo "${fn#${D}}:${line[0]} (script ${fn##*/} installed in PATH but interpreter ${line[0]} not found)" \
+ >> "${T}"/non-prefix-shebangs-errs
+ fi
+ else
+ # unprefixed/invalid shebang, but outside $PATH, this may be
+ # intended (e.g. config.guess) so remain silent by default
+ has stricter ${FEATURES} && \
+ eqawarn "invalid shebang in ${fn#${D}}: ${line[0]}"
+ fi
+ done
+ if [[ -e "${T}"/non-prefix-shebangs-errs ]] ; then
+ eqawarn "QA Notice: the following files use invalid (possible non-prefixed) shebangs:"
+ while read line ; do
+ eqawarn " ${line}"
+ done < "${T}"/non-prefix-shebangs-errs
+ rm -f "${T}"/non-prefix-shebangs-errs
+ die "Aborting due to QA concerns: invalid shebangs found"
+ fi
+}
+
+install_qa_check_prefix
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/bin/install-qa-check.d/10executable-issues b/bin/install-qa-check.d/10executable-issues
new file mode 100644
index 000000000..f765749b6
--- /dev/null
+++ b/bin/install-qa-check.d/10executable-issues
@@ -0,0 +1,140 @@
+# Check for major issues with built executables: insecure RPATHs,
+# text relocations, executable stacks
+
+elf_check() {
+ if type -P scanelf > /dev/null && ! has binchecks ${RESTRICT}; then
+ local insecure_rpath=0 tmp_quiet=${PORTAGE_QUIET}
+ local f x
+
+ # display warnings when using stricter because we die afterwards
+ if has stricter ${FEATURES} ; then
+ local PORTAGE_QUIET
+ fi
+
+ # Make sure we disallow insecure RUNPATH/RPATHs.
+ # 1) References to PORTAGE_BUILDDIR are banned because it's a
+ # security risk. We don't want to load files from a
+ # temporary directory.
+ # 2) If ROOT != "/", references to ROOT are banned because
+ # that directory won't exist on the target system.
+ # 3) Null paths are banned because the loader will search $PWD when
+ # it finds null paths.
+ local forbidden_dirs="${PORTAGE_BUILDDIR}"
+ if [[ -n "${ROOT}" && "${ROOT}" != "/" ]]; then
+ forbidden_dirs+=" ${ROOT}"
+ fi
+ local dir l rpath_files=$(scanelf -F '%F:%r' -qBR "${ED}")
+ f=""
+ for dir in ${forbidden_dirs}; do
+ for l in $(echo "${rpath_files}" | grep -E ":${dir}|::|: "); do
+ f+=" ${l%%:*}\n"
+ if ! has stricter ${FEATURES}; then
+ __vecho "Auto fixing rpaths for ${l%%:*}"
+ TMPDIR="${dir}" scanelf -BXr "${l%%:*}" -o /dev/null
+ fi
+ done
+ done
+
+ # Reject set*id binaries with $ORIGIN in RPATH #260331
+ x=$(
+ find "${ED}" -type f \( -perm -u+s -o -perm -g+s \) -print0 | \
+ xargs -0 scanelf -qyRF '%r %p' | grep '$ORIGIN'
+ )
+
+ # Print QA notice.
+ if [[ -n ${f}${x} ]] ; then
+ __vecho -ne '\n'
+ eqawarn "QA Notice: The following files contain insecure RUNPATHs"
+ eqawarn " Please file a bug about this at http://bugs.gentoo.org/"
+ eqawarn " with the maintaining herd of the package."
+ eqawarn "${f}${f:+${x:+\n}}${x}"
+ __vecho -ne '\n'
+ if [[ -n ${x} ]] || has stricter ${FEATURES} ; then
+ insecure_rpath=1
+ fi
+ fi
+
+ # TEXTRELs are baaaaaaaad
+ # Allow devs to mark things as ignorable ... e.g. things that are
+ # binary-only and upstream isn't cooperating (nvidia-glx) ... we
+ # allow ebuild authors to set QA_TEXTRELS_arch and QA_TEXTRELS ...
+ # the former overrides the latter ... regexes allowed ! :)
+ local qa_var="QA_TEXTRELS_${ARCH/-/_}"
+ [[ -n ${!qa_var} ]] && QA_TEXTRELS=${!qa_var}
+ [[ -n ${QA_STRICT_TEXTRELS} ]] && QA_TEXTRELS=""
+ export QA_TEXTRELS="${QA_TEXTRELS} lib*/modules/*.ko"
+ f=$(scanelf -qyRF '%t %p' "${ED}" | grep -v 'usr/lib/debug/')
+ if [[ -n ${f} ]] ; then
+ scanelf -qyRAF '%T %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-textrel.log
+ __vecho -ne '\n'
+ eqawarn "QA Notice: The following files contain runtime text relocations"
+ eqawarn " Text relocations force the dynamic linker to perform extra"
+ eqawarn " work at startup, waste system resources, and may pose a security"
+ eqawarn " risk. On some architectures, the code may not even function"
+ eqawarn " properly, if at all."
+ eqawarn " For more information, see http://hardened.gentoo.org/pic-fix-guide.xml"
+ eqawarn " Please include the following list of files in your report:"
+ eqawarn "${f}"
+ __vecho -ne '\n'
+ die_msg="${die_msg} textrels,"
+ sleep 1
+ fi
+
+ # Also, executable stacks only matter on linux (and just glibc atm ...)
+ f=""
+ case ${CTARGET:-${CHOST}} in
+ *-linux-gnu*)
+ # Check for files with executable stacks, but only on arches which
+ # are supported at the moment. Keep this list in sync with
+ # http://www.gentoo.org/proj/en/hardened/gnu-stack.xml (Arch Status)
+ case ${CTARGET:-${CHOST}} in
+ arm*|i?86*|ia64*|m68k*|s390*|sh*|x86_64*)
+ # Allow devs to mark things as ignorable ... e.g. things
+ # that are binary-only and upstream isn't cooperating ...
+ # we allow ebuild authors to set QA_EXECSTACK_arch and
+ # QA_EXECSTACK ... the former overrides the latter ...
+ # regexes allowed ! :)
+
+ qa_var="QA_EXECSTACK_${ARCH/-/_}"
+ [[ -n ${!qa_var} ]] && QA_EXECSTACK=${!qa_var}
+ [[ -n ${QA_STRICT_EXECSTACK} ]] && QA_EXECSTACK=""
+ qa_var="QA_WX_LOAD_${ARCH/-/_}"
+ [[ -n ${!qa_var} ]] && QA_WX_LOAD=${!qa_var}
+ [[ -n ${QA_STRICT_WX_LOAD} ]] && QA_WX_LOAD=""
+ export QA_EXECSTACK="${QA_EXECSTACK} lib*/modules/*.ko"
+ export QA_WX_LOAD="${QA_WX_LOAD} lib*/modules/*.ko"
+ f=$(scanelf -qyRAF '%e %p' "${ED}" | grep -v 'usr/lib/debug/')
+ ;;
+ esac
+ ;;
+ esac
+ if [[ -n ${f} ]] ; then
+ # One more pass to help devs track down the source
+ scanelf -qyRAF '%e %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-execstack.log
+ __vecho -ne '\n'
+ eqawarn "QA Notice: The following files contain writable and executable sections"
+ eqawarn " Files with such sections will not work properly (or at all!) on some"
+ eqawarn " architectures/operating systems. A bug should be filed at"
+ eqawarn " http://bugs.gentoo.org/ to make sure the issue is fixed."
+ eqawarn " For more information, see http://hardened.gentoo.org/gnu-stack.xml"
+ eqawarn " Please include the following list of files in your report:"
+ eqawarn " Note: Bugs should be filed for the respective maintainers"
+ eqawarn " of the package in question and not hardened@g.o."
+ eqawarn "${f}"
+ __vecho -ne '\n'
+ die_msg="${die_msg} execstacks"
+ sleep 1
+ fi
+
+ if [[ ${insecure_rpath} -eq 1 ]] ; then
+ die "Aborting due to serious QA concerns with RUNPATH/RPATH"
+ elif [[ -n ${die_msg} ]] && has stricter ${FEATURES} ; then
+ die "Aborting due to QA concerns: ${die_msg}"
+ fi
+ fi
+}
+
+elf_check
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/bin/install-qa-check.d/10ignored-flags b/bin/install-qa-check.d/10ignored-flags
new file mode 100644
index 000000000..7aa9eb695
--- /dev/null
+++ b/bin/install-qa-check.d/10ignored-flags
@@ -0,0 +1,99 @@
+# QA checks for ignored *FLAGS.
+
+ignored_flag_check() {
+ type -P scanelf > /dev/null || return
+ has binchecks ${RESTRICT} && return
+
+ local qa_var="QA_FLAGS_IGNORED_${ARCH/-/_}"
+ eval "[[ -n \${!qa_var} ]] && QA_FLAGS_IGNORED=(\"\${${qa_var}[@]}\")"
+ if [[ ${#QA_FLAGS_IGNORED[@]} -eq 1 ]] ; then
+ local shopts=$-
+ set -o noglob
+ QA_FLAGS_IGNORED=(${QA_FLAGS_IGNORED})
+ set +o noglob
+ set -${shopts}
+ fi
+
+ local f x
+
+ # Check for files built without respecting *FLAGS. Note that
+ # -frecord-gcc-switches must be in all *FLAGS variables, in
+ # order to avoid false positive results here.
+ # NOTE: This check must execute before prepall/prepstrip, since
+ # prepstrip strips the .GCC.command.line sections.
+ if [[ "${CFLAGS}" == *-frecord-gcc-switches* ]] && \
+ [[ "${CXXFLAGS}" == *-frecord-gcc-switches* ]] && \
+ [[ "${FFLAGS}" == *-frecord-gcc-switches* ]] && \
+ [[ "${FCFLAGS}" == *-frecord-gcc-switches* ]] ; then
+ rm -f "${T}"/scanelf-ignored-CFLAGS.log
+ for x in $(scanelf -qyRF '#k%p' -k '!.GCC.command.line' "${ED}") ; do
+ # Separate out file types that are known to support
+ # .GCC.command.line sections, using the `file` command
+ # similar to how prepstrip uses it.
+ f=$(file "${x}") || continue
+ [[ -z ${f} ]] && continue
+ if [[ ${f} == *"SB executable"* ||
+ ${f} == *"SB shared object"* ]] ; then
+ echo "${x}" >> "${T}"/scanelf-ignored-CFLAGS.log
+ fi
+ done
+
+ if [[ -f "${T}"/scanelf-ignored-CFLAGS.log ]] ; then
+
+ if [ "${QA_STRICT_FLAGS_IGNORED-unset}" = unset ] ; then
+ for x in "${QA_FLAGS_IGNORED[@]}" ; do
+ sed -e "s#^${x#/}\$##" -i "${T}"/scanelf-ignored-CFLAGS.log
+ done
+ fi
+ # Filter anything under /usr/lib/debug/ in order to avoid
+ # duplicate warnings for splitdebug files.
+ sed -e "s#^usr/lib/debug/.*##" -e "/^\$/d" -e "s#^#/#" \
+ -i "${T}"/scanelf-ignored-CFLAGS.log
+ f=$(<"${T}"/scanelf-ignored-CFLAGS.log)
+ if [[ -n ${f} ]] ; then
+ __vecho -ne '\n'
+ eqawarn "${BAD}QA Notice: Files built without respecting CFLAGS have been detected${NORMAL}"
+ eqawarn " Please include the following list of files in your report:"
+ eqawarn "${f}"
+ __vecho -ne '\n'
+ sleep 1
+ else
+ rm -f "${T}"/scanelf-ignored-CFLAGS.log
+ fi
+ fi
+ fi
+
+ # Check for files built without respecting LDFLAGS
+ if [[ "${LDFLAGS}" == *,--hash-style=gnu* ]] && \
+ ! has binchecks ${RESTRICT} ; then
+ f=$(scanelf -qyRF '#k%p' -k .hash "${ED}")
+ if [[ -n ${f} ]] ; then
+ echo "${f}" > "${T}"/scanelf-ignored-LDFLAGS.log
+ if [ "${QA_STRICT_FLAGS_IGNORED-unset}" = unset ] ; then
+ for x in "${QA_FLAGS_IGNORED[@]}" ; do
+ sed -e "s#^${x#/}\$##" -i "${T}"/scanelf-ignored-LDFLAGS.log
+ done
+ fi
+ # Filter anything under /usr/lib/debug/ in order to avoid
+ # duplicate warnings for splitdebug files.
+ sed -e "s#^usr/lib/debug/.*##" -e "/^\$/d" -e "s#^#/#" \
+ -i "${T}"/scanelf-ignored-LDFLAGS.log
+ f=$(<"${T}"/scanelf-ignored-LDFLAGS.log)
+ if [[ -n ${f} ]] ; then
+ __vecho -ne '\n'
+ eqawarn "${BAD}QA Notice: Files built without respecting LDFLAGS have been detected${NORMAL}"
+ eqawarn " Please include the following list of files in your report:"
+ eqawarn "${f}"
+ __vecho -ne '\n'
+ sleep 1
+ else
+ rm -f "${T}"/scanelf-ignored-LDFLAGS.log
+ fi
+ fi
+ fi
+}
+
+ignored_flag_check
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/bin/install-qa-check.d/20deprecated-directories b/bin/install-qa-check.d/20deprecated-directories
new file mode 100644
index 000000000..fb82bfe7a
--- /dev/null
+++ b/bin/install-qa-check.d/20deprecated-directories
@@ -0,0 +1,18 @@
+# Check for deprecated directories
+
+deprecated_dir_check() {
+ local x f=
+ for x in etc/app-defaults usr/man usr/info usr/X11R6 usr/doc usr/locale ; do
+ [[ -d ${ED}/$x ]] && f+=" $x\n"
+ done
+ if [[ -n $f ]] ; then
+ eqawarn "QA Notice: This ebuild installs into the following deprecated directories:"
+ eqawarn
+ eqawarn "$f"
+ fi
+}
+
+deprecated_dir_check
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/bin/install-qa-check.d/20runtime-directories b/bin/install-qa-check.d/20runtime-directories
new file mode 100644
index 000000000..2e21d6d04
--- /dev/null
+++ b/bin/install-qa-check.d/20runtime-directories
@@ -0,0 +1,26 @@
+# Check for directories that need to be created at runtime
+
+runtime_dir_check() {
+ # It's ok create these directories, but not to install into them. #493154
+ # TODO: We should add var/lib to this list.
+ local x f=
+ for x in var/cache var/lock var/run run ; do
+ if [[ ! -L ${ED}/${x} && -d ${ED}/${x} ]] ; then
+ if [[ -z $(find "${ED}/${x}" -prune -empty) ]] ; then
+ f+=$(cd "${ED}"; find "${x}" -printf ' %p\n')
+ fi
+ fi
+ done
+ if [[ -n ${f} ]] ; then
+ eqawarn "QA Notice: This ebuild installs into paths that should be created at runtime."
+ eqawarn " To fix, simply do not install into these directories. Instead, your package"
+ eqawarn " should create dirs on the fly at runtime as needed via init scripts/etc..."
+ eqawarn
+ eqawarn "${f}"
+ fi
+}
+
+runtime_dir_check
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/bin/install-qa-check.d/60bash-completion b/bin/install-qa-check.d/60bash-completion
new file mode 100644
index 000000000..c1547619a
--- /dev/null
+++ b/bin/install-qa-check.d/60bash-completion
@@ -0,0 +1,130 @@
+# QA checks for bash-completion files
+
+bashcomp_check() {
+ # Check for correct bash-completion install path.
+ local syscompdir=$(pkg-config --variable=completionsdir bash-completion 2>/dev/null)
+ : ${syscompdir:=${EPREFIX}/usr/share/bash-completion/completions}
+
+ local instcompdir
+ if [[ -d ${ED}/usr/share/bash-completion/completions ]]; then
+ instcompdir=${ED}/usr/share/bash-completion/completions
+ elif [[ -d ${ED}/usr/share/bash-completion ]]; then
+ if [[ ${syscompdir} != ${EPREFIX}/usr/share/bash-completion ]]; then
+ eqawarn "Bash completions were installed in legacy location. Please update"
+ eqawarn "the ebuild to get the install paths using bash-completion-r1.eclass."
+ eqawarn
+ fi
+
+ instcompdir=${ED}/usr/share/bash-completion
+ fi
+
+ # Do a few QA tests on bash completions.
+ if [[ -n ${instcompdir} && -f ${EROOT}/usr/share/bash-completion/bash_completion ]]; then
+ _get_completions() {
+ # source the file
+ source "${1}" &>/dev/null
+
+ [[ ${USED_HAVE} == yes ]] && echo '__HAVE_USED__'
+
+ # print the completed commands
+ while read -a args; do
+ [[ ${args[0]} == complete ]] || continue
+ # command always comes last, one per line
+ echo "${args[$(( ${#args[@]} - 1))]}"
+ done < <(complete -p)
+ }
+
+ # load the global helpers
+ source "${EROOT}"/usr/share/bash-completion/bash_completion
+
+ # clean up predefined completions
+ complete -r
+
+ # force all completions on
+ _have() {
+ return 0
+ }
+
+ local USED_HAVE=no
+ # add a replacement for have()
+ have() {
+ USED_HAVE=yes
+
+ unset -v have
+ _have ${1} && have=yes
+ }
+
+ local f c completions
+ local all_compls=()
+ local all_files=()
+ local qa_warnings=()
+
+ for f in "${instcompdir}"/*; do
+ # ignore directories and other non-files
+ [[ ! -f ${f} ]] && continue
+
+ # skip the common code file
+ # (in case we're run in /usr/share/bash-completion)
+ [[ ${f##*/} == bash_completion ]] && continue
+
+ completions=( $(_get_completions "${f}") )
+
+ if [[ ${completions[0]} == __HAVE_USED__ ]]; then
+ qa_warnings+=(
+ "${f##*/}: 'have' command is deprecated and must not be used."
+ )
+ unset 'completions[0]'
+ fi
+
+ if [[ -z ${completions[@]} ]]; then
+ qa_warnings+=(
+ "${f##*/}: does not define any completions (failed to source?)."
+ )
+ continue
+ fi
+
+ for c in "${completions[@]}"; do
+ if [[ ${c} == /* ]]; then
+ qa_warnings+=(
+ "${f##*/}: absolute paths can not be used for completions (on '${c}')."
+ )
+ else
+ all_compls+=( "${c}" )
+ fi
+ done
+
+ if ! has "${f##*/}" "${all_compls[@]}"; then
+ qa_warnings+=(
+ "${f##*/}: incorrect name, no completions for '${f##*/}' command defined."
+ )
+ fi
+
+ all_files+=( "${f##*/}" )
+ done
+
+ for c in "${all_compls[@]}"; do
+ if ! has "${c}" "${all_files[@]}"; then
+ qa_warnings+=(
+ "${c}: missing alias (symlink) for completed command."
+ )
+ fi
+ done
+
+ if [[ -n ${qa_warnings[@]} ]]; then
+ eqawarn "Problems with installed bash completions were found:"
+ eqawarn
+ for c in "${qa_warnings[@]}"; do
+ eqawarn " ${c}"
+ done
+ eqawarn
+ eqawarn "For more details on installing bash-completions, please see:"
+ eqawarn "https://wiki.gentoo.org/wiki/Bash/Installing_completion_files"
+ eqawarn
+ fi
+ fi
+}
+
+bashcomp_check
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/bin/install-qa-check.d/60openrc b/bin/install-qa-check.d/60openrc
new file mode 100644
index 000000000..9b7fc6d99
--- /dev/null
+++ b/bin/install-qa-check.d/60openrc
@@ -0,0 +1,41 @@
+# QA checks for OpenRC init.d files.
+
+openrc_check() {
+ # Sanity check syntax errors in init.d scripts
+ local d i
+ for d in /etc/conf.d /etc/init.d ; do
+ [[ -d ${ED}/${d} ]] || continue
+ for i in "${ED}"/${d}/* ; do
+ [[ -L ${i} ]] && continue
+ # if empty conf.d/init.d dir exists (baselayout), then i will be "/etc/conf.d/*" and not exist
+ [[ ! -e ${i} ]] && continue
+ if [[ ${d} == /etc/init.d && ${i} != *.sh ]] ; then
+ # skip non-shell-script for bug #451386
+ [[ $(head -n1 "${i}") =~ ^#!.*[[:space:]/](runscript|sh)$ ]] || continue
+ fi
+ bash -n "${i}" || die "The init.d file has syntax errors: ${i}"
+ done
+ done
+
+ local checkbashisms=$(type -P checkbashisms)
+ if [[ -n ${checkbashisms} ]] ; then
+ for d in /etc/init.d ; do
+ [[ -d ${ED}${d} ]] || continue
+ for i in "${ED}${d}"/* ; do
+ [[ -e ${i} ]] || continue
+ [[ -L ${i} ]] && continue
+ f=$("${checkbashisms}" -f "${i}" 2>&1)
+ [[ $? != 0 && -n ${f} ]] || continue
+ eqawarn "QA Notice: shell script appears to use non-POSIX feature(s):"
+ while read -r ;
+ do eqawarn " ${REPLY}"
+ done <<< "${f//${ED}}"
+ done
+ done
+ fi
+}
+
+openrc_check
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/bin/install-qa-check.d/60pkgconfig b/bin/install-qa-check.d/60pkgconfig
new file mode 100644
index 000000000..1b34c04db
--- /dev/null
+++ b/bin/install-qa-check.d/60pkgconfig
@@ -0,0 +1,15 @@
+# Check for pkg-config file issues
+
+pkgconfig_check() {
+ # Look for leaking LDFLAGS into pkg-config files
+ local f=$(egrep -sH '^Libs.*-Wl,(-O[012]|--hash-style)' "${ED}"/usr/*/pkgconfig/*.pc)
+ if [[ -n ${f} ]] ; then
+ eqawarn "QA Notice: pkg-config files with wrong LDFLAGS detected:"
+ eqawarn "${f//${D}}"
+ fi
+}
+
+pkgconfig_check
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/bin/install-qa-check.d/60pngfix b/bin/install-qa-check.d/60pngfix
new file mode 100644
index 000000000..8d53040b6
--- /dev/null
+++ b/bin/install-qa-check.d/60pngfix
@@ -0,0 +1,35 @@
+# Check for issues with PNG files
+
+pngfix_check() {
+ local pngfix=$(type -P pngfix)
+ if [[ -n ${pngfix} ]] ; then
+ local pngout=()
+ local next
+
+ while read -r -a pngout ; do
+ local error=""
+
+ case "${pngout[1]}" in
+ CHK)
+ error='invalid checksum'
+ ;;
+ TFB)
+ error='broken IDAT window length'
+ ;;
+ esac
+
+ if [[ -n ${error} ]] ; then
+ if [[ -z ${next} ]] ; then
+ eqawarn "QA Notice: broken .png files found:"
+ next=1
+ fi
+ eqawarn " ${pngout[@]:7}: ${error}"
+ fi
+ done < <(find "${ED}" -type f -name '*.png' -exec "${pngfix}" {} +)
+ fi
+}
+
+pngfix_check
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/bin/install-qa-check.d/60systemd b/bin/install-qa-check.d/60systemd
new file mode 100644
index 000000000..f134a3068
--- /dev/null
+++ b/bin/install-qa-check.d/60systemd
@@ -0,0 +1,25 @@
+# QA checks for systemd units.
+
+systemd_check() {
+ local systemddir f
+
+ # Common mistakes in systemd service files.
+ if type -P pkg-config >/dev/null && pkg-config --exists systemd; then
+ systemddir=$(pkg-config --variable=systemdsystemunitdir systemd)
+ else
+ systemddir=/usr/lib/systemd/system
+ fi
+ if [[ -d ${ED%/}${systemddir} ]]; then
+ f=$(grep -sH '^EnvironmentFile.*=.*/etc/conf\.d' "${ED%/}${systemddir}"/*.service)
+ if [[ -n ${f} ]] ; then
+ eqawarn "QA Notice: systemd units using /etc/conf.d detected:"
+ eqawarn "${f//${D}}"
+ eqawarn "See: https://wiki.gentoo.org/wiki/Project:Systemd/conf.d_files"
+ fi
+ fi
+}
+
+systemd_check
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/bin/install-qa-check.d/60udev b/bin/install-qa-check.d/60udev
new file mode 100644
index 000000000..4327d069d
--- /dev/null
+++ b/bin/install-qa-check.d/60udev
@@ -0,0 +1,21 @@
+# Check udev rule installs
+
+udev_check() {
+ set +f
+ local x f=
+ for x in "${ED}etc/udev/rules.d/"* "${ED}lib"*"/udev/rules.d/"* ; do
+ [[ -e ${x} ]] || continue
+ [[ ${x} == ${ED}lib/udev/rules.d/* ]] && continue
+ f+=" ${x#${ED}}\n"
+ done
+ if [[ -n $f ]] ; then
+ eqawarn "QA Notice: udev rules should be installed in /lib/udev/rules.d:"
+ eqawarn
+ eqawarn "$f"
+ fi
+}
+
+udev_check
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/bin/install-qa-check.d/80libraries b/bin/install-qa-check.d/80libraries
new file mode 100644
index 000000000..c83f27800
--- /dev/null
+++ b/bin/install-qa-check.d/80libraries
@@ -0,0 +1,167 @@
+# Check for issues with installed libraries
+
+lib_check() {
+ local f x i j
+
+ if type -P scanelf > /dev/null && ! has binchecks ${RESTRICT}; then
+ # Check for shared libraries lacking SONAMEs
+ local qa_var="QA_SONAME_${ARCH/-/_}"
+ eval "[[ -n \${!qa_var} ]] && QA_SONAME=(\"\${${qa_var}[@]}\")"
+ f=$(scanelf -ByF '%S %p' "${ED}"{,usr/}lib*/lib*.so* | awk '$2 == "" { print }' | sed -e "s:^[[:space:]]${ED}:/:")
+ if [[ -n ${f} ]] ; then
+ echo "${f}" > "${T}"/scanelf-missing-SONAME.log
+ if [[ "${QA_STRICT_SONAME-unset}" == unset ]] ; then
+ if [[ ${#QA_SONAME[@]} -gt 1 ]] ; then
+ for x in "${QA_SONAME[@]}" ; do
+ sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-SONAME.log
+ done
+ else
+ local shopts=$-
+ set -o noglob
+ for x in ${QA_SONAME} ; do
+ sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-SONAME.log
+ done
+ set +o noglob
+ set -${shopts}
+ fi
+ fi
+ sed -e "/^\$/d" -i "${T}"/scanelf-missing-SONAME.log
+ f=$(<"${T}"/scanelf-missing-SONAME.log)
+ if [[ -n ${f} ]] ; then
+ __vecho -ne '\n'
+ eqawarn "QA Notice: The following shared libraries lack a SONAME"
+ eqawarn "${f}"
+ __vecho -ne '\n'
+ sleep 1
+ else
+ rm -f "${T}"/scanelf-missing-SONAME.log
+ fi
+ fi
+
+ # Check for shared libraries lacking NEEDED entries
+ qa_var="QA_DT_NEEDED_${ARCH/-/_}"
+ eval "[[ -n \${!qa_var} ]] && QA_DT_NEEDED=(\"\${${qa_var}[@]}\")"
+ f=$(scanelf -ByF '%n %p' "${ED}"{,usr/}lib*/lib*.so* | awk '$2 == "" { print }' | sed -e "s:^[[:space:]]${ED}:/:")
+ if [[ -n ${f} ]] ; then
+ echo "${f}" > "${T}"/scanelf-missing-NEEDED.log
+ if [[ "${QA_STRICT_DT_NEEDED-unset}" == unset ]] ; then
+ if [[ ${#QA_DT_NEEDED[@]} -gt 1 ]] ; then
+ for x in "${QA_DT_NEEDED[@]}" ; do
+ sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-NEEDED.log
+ done
+ else
+ local shopts=$-
+ set -o noglob
+ for x in ${QA_DT_NEEDED} ; do
+ sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-NEEDED.log
+ done
+ set +o noglob
+ set -${shopts}
+ fi
+ fi
+ sed -e "/^\$/d" -i "${T}"/scanelf-missing-NEEDED.log
+ f=$(<"${T}"/scanelf-missing-NEEDED.log)
+ if [[ -n ${f} ]] ; then
+ __vecho -ne '\n'
+ eqawarn "QA Notice: The following shared libraries lack NEEDED entries"
+ eqawarn "${f}"
+ __vecho -ne '\n'
+ sleep 1
+ else
+ rm -f "${T}"/scanelf-missing-NEEDED.log
+ fi
+ fi
+ fi
+
+ # this should help to ensure that all (most?) shared libraries are executable
+ # and that all libtool scripts / static libraries are not executable
+ for i in "${ED}"opt/*/lib* \
+ "${ED}"lib* \
+ "${ED}"usr/lib* ; do
+ [[ ! -d ${i} ]] && continue
+
+ for j in "${i}"/*.so.* "${i}"/*.so ; do
+ [[ ! -e ${j} ]] && continue
+ [[ -L ${j} ]] && continue
+ [[ -x ${j} ]] && continue
+ __vecho "making executable: ${j#${ED}}"
+ chmod +x "${j}"
+ done
+
+ for j in "${i}"/*.a "${i}"/*.la ; do
+ [[ ! -e ${j} ]] && continue
+ [[ -L ${j} ]] && continue
+ [[ ! -x ${j} ]] && continue
+ __vecho "removing executable bit: ${j#${ED}}"
+ chmod -x "${j}"
+ done
+
+ for j in "${i}"/*.{a,dll,dylib,sl,so}.* "${i}"/*.{a,dll,dylib,sl,so} ; do
+ [[ ! -e ${j} ]] && continue
+ [[ ! -L ${j} ]] && continue
+ linkdest=$(readlink "${j}")
+ if [[ ${linkdest} == /* ]] ; then
+ __vecho -ne '\n'
+ eqawarn "QA Notice: Found an absolute symlink in a library directory:"
+ eqawarn " ${j#${D}} -> ${linkdest}"
+ eqawarn " It should be a relative symlink if in the same directory"
+ eqawarn " or a linker script if it crosses the /usr boundary."
+ fi
+ done
+ done
+
+ # When installing static libraries into /usr/lib and shared libraries into
+ # /lib, we have to make sure we have a linker script in /usr/lib along side
+ # the static library, or gcc will utilize the static lib when linking :(.
+ # http://bugs.gentoo.org/4411
+ local abort="no"
+ local a s
+ for a in "${ED}"usr/lib*/*.a ; do
+ # PREFIX LOCAL: support MachO objects
+ [[ ${CHOST} == *-darwin* ]] \
+ && s=${a%.a}.dylib \
+ || s=${a%.a}.so
+ # END PREFIX LOCAL
+ if [[ ! -e ${s} ]] ; then
+ s=${s%usr/*}${s##*/usr/}
+ if [[ -e ${s} ]] ; then
+ __vecho -ne '\n'
+ eqawarn "QA Notice: Missing gen_usr_ldscript for ${s##*/}"
+ abort="yes"
+ fi
+ fi
+ done
+ [[ ${abort} == "yes" ]] && die "add those ldscripts"
+
+ # Make sure people don't store libtool files or static libs in /lib
+ # PREFIX LOCAL: on AIX, "dynamic libs" have extension .a, so don't
+ # get false positives
+ [[ ${CHOST} == *-aix* ]] \
+ && f=$(ls "${ED}"lib*/*.la 2>/dev/null || true) \
+ || f=$(ls "${ED}"lib*/*.{a,la} 2>/dev/null)
+ # END PREFIX LOCAL
+ if [[ -n ${f} ]] ; then
+ __vecho -ne '\n'
+ eqawarn "QA Notice: Excessive files found in the / partition"
+ eqawarn "${f}"
+ __vecho -ne '\n'
+ die "static archives (*.a) and libtool library files (*.la) belong in /usr/lib*, not /lib*"
+ fi
+
+ # Verify that the libtool files don't contain bogus $D entries.
+ local abort=no gentoo_bug=no always_overflow=no
+ for a in "${ED}"usr/lib*/*.la ; do
+ s=${a##*/}
+ if grep -qs "${ED}" "${a}" ; then
+ __vecho -ne '\n'
+ eqawarn "QA Notice: ${s} appears to contain PORTAGE_TMPDIR paths"
+ abort="yes"
+ fi
+ done
+ [[ ${abort} == "yes" ]] && die "soiled libtool library files found"
+}
+
+lib_check
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/bin/install-qa-check.d/80multilib-strict b/bin/install-qa-check.d/80multilib-strict
new file mode 100644
index 000000000..436932e80
--- /dev/null
+++ b/bin/install-qa-check.d/80multilib-strict
@@ -0,0 +1,50 @@
+# Strict multilib directory checks
+multilib_strict_check() {
+ if has multilib-strict ${FEATURES} && \
+ [[ -x ${EPREFIX}/usr/bin/file && -x ${EPREFIX}/usr/bin/find ]] && \
+ [[ -n ${MULTILIB_STRICT_DIRS} && -n ${MULTILIB_STRICT_DENY} ]]
+ then
+ rm -f "${T}/multilib-strict.log"
+ local abort=no dir file
+ MULTILIB_STRICT_EXEMPT=$(echo ${MULTILIB_STRICT_EXEMPT} | sed -e 's:\([(|)]\):\\\1:g')
+ for dir in ${MULTILIB_STRICT_DIRS} ; do
+ [[ -d ${ED}/${dir} ]] || continue
+ for file in $(find ${ED}/${dir} -type f | grep -v "^${ED}/${dir}/${MULTILIB_STRICT_EXEMPT}"); do
+ if file ${file} | egrep -q "${MULTILIB_STRICT_DENY}" ; then
+ echo "${file#${ED}//}" >> "${T}/multilib-strict.log"
+ fi
+ done
+ done
+
+ if [[ -s ${T}/multilib-strict.log ]] ; then
+ if [[ ${#QA_MULTILIB_PATHS[@]} -eq 1 ]] ; then
+ local shopts=$-
+ set -o noglob
+ QA_MULTILIB_PATHS=(${QA_MULTILIB_PATHS})
+ set +o noglob
+ set -${shopts}
+ fi
+ if [ "${QA_STRICT_MULTILIB_PATHS-unset}" = unset ] ; then
+ local x
+ for x in "${QA_MULTILIB_PATHS[@]}" ; do
+ sed -e "s#^${x#/}\$##" -i "${T}/multilib-strict.log"
+ done
+ sed -e "/^\$/d" -i "${T}/multilib-strict.log"
+ fi
+ if [[ -s ${T}/multilib-strict.log ]] ; then
+ abort=yes
+ echo "Files matching a file type that is not allowed:"
+ while read -r ; do
+ echo " ${REPLY}"
+ done < "${T}/multilib-strict.log"
+ fi
+ fi
+
+ [[ ${abort} == yes ]] && die "multilib-strict check failed!"
+ fi
+}
+
+multilib_strict_check
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/bin/install-qa-check.d/90gcc-warnings b/bin/install-qa-check.d/90gcc-warnings
new file mode 100644
index 000000000..9703c39de
--- /dev/null
+++ b/bin/install-qa-check.d/90gcc-warnings
@@ -0,0 +1,168 @@
+# Check for important gcc warning
+
+gcc_warn_check() {
+ local f
+
+ # Evaluate misc gcc warnings
+ if [[ -n ${PORTAGE_LOG_FILE} && -r ${PORTAGE_LOG_FILE} ]] ; then
+ # In debug mode, this variable definition and corresponding grep calls
+ # will produce false positives if they're shown in the trace.
+ local reset_debug=0
+ if [[ ${-/x/} != $- ]] ; then
+ set +x
+ reset_debug=1
+ fi
+ local m msgs=(
+ # only will and does, no might :)
+ 'warning: .*will.*\[-Wstrict-aliasing\]'
+ 'warning: .*does.*\[-Wstrict-aliasing\]'
+ # implicit declaration of function ‘...’
+ 'warning: .*\[-Wimplicit-function-declaration\]'
+ # with -Wall, goes in pair with -Wimplicit-function-declaration
+ # but without -Wall, we need to assert for it alone
+ 'warning: .*incompatible implicit declaration of built-in function'
+ # 'is used uninitialized in this function' and some more
+ 'warning: .*\[-Wuninitialized\]'
+ # comparisons like ‘X<=Y<=Z’ do not have their mathematical meaning
+ 'warning: .*mathematical meaning*\[-Wparentheses\]'
+ # null argument where non-null required
+ 'warning: .*\[-Wnonnull\]'
+ # array subscript is above/below/outside array bounds
+ 'warning: .*\[-Warray-bounds\]'
+ # attempt to free a non-heap object
+ 'warning: .*\[-Wfree-nonheap-object\]'
+ # those three do not have matching -W flags, it seems
+ 'warning: .*will always overflow destination buffer'
+ 'warning: .*assuming pointer wraparound does not occur'
+ 'warning: .*escape sequence out of range'
+ # left/right-hand operand of comma expression has no effect
+ 'warning: .*comma.*\[-Wunused-value\]'
+ # converting to non-pointer type ... from NULL and likes
+ 'warning: .*\[-Wconversion-null\]'
+ # NULL used in arithmetic
+ 'warning: .*NULL.*\[-Wpointer-arith\]'
+ # pointer to a function used in arithmetic and likes
+ 'warning: .*function.*\[-Wpointer-arith\]'
+ # the address of ... will never be NULL and likes
+ # (uses of function refs & string constants in conditionals)
+ 'warning: .*\[-Waddress\]'
+ # outdated?
+ 'warning: .*too few arguments for format'
+ # format ... expects a matching ... argument
+ # (iow, too few arguments for format in new wording :))
+ 'warning: .*matching.*\[-Wformat=\]'
+ # function returns address of local variable
+ 'warning: .*\[-Wreturn-local-addr\]'
+ # argument to sizeof ... is the same expression as the source
+ 'warning: .*\[-Wsizeof-pointer-memaccess\]'
+ # iteration invokes undefined behavior
+ 'warning: .*\[-Waggressive-loop-optimizations\]'
+
+ # this may be valid code :/
+ #': warning: multi-character character constant'
+ # need to check these two ...
+ #': warning: assuming signed overflow does not occur when'
+ #': warning: comparison with string literal results in unspecified behav'
+ # yacc/lex likes to trigger this one
+ #': warning: extra tokens at end of .* directive'
+ # only gcc itself triggers this ?
+ #': warning: .*noreturn.* function does return'
+ # these throw false positives when 0 is used instead of NULL
+ #': warning: missing sentinel in function call'
+ #': warning: not enough variable arguments to fit a sentinel'
+ )
+
+ # join all messages into one grep-expression
+ local joined_msgs
+ printf -v joined_msgs '%s|' "${msgs[@]}"
+ joined_msgs=${joined_msgs%|}
+
+ local abort="no"
+ local grep_cmd=grep
+ [[ $PORTAGE_LOG_FILE = *.gz ]] && grep_cmd=zgrep
+
+ # force C locale to work around slow unicode locales #160234
+ f=$(LC_CTYPE=C LC_COLLATE=C "${grep_cmd}" -E "${joined_msgs}" "${PORTAGE_LOG_FILE}")
+ if [[ -n ${f} ]] ; then
+ abort="yes"
+ # for now, don't make this fatal (see bug #337031)
+ #if [[ ${f} == *'will always overflow destination buffer'* ]]; then
+ # always_overflow=yes
+ #fi
+ if [[ $always_overflow = yes ]] ; then
+ eerror
+ eerror "QA Notice: Package triggers severe warnings which indicate that it"
+ eerror " may exhibit random runtime failures."
+ eerror
+ eerror "${f}"
+ eerror
+ eerror " Please file a bug about this at http://bugs.gentoo.org/"
+ eerror " with the maintaining herd of the package."
+ eerror
+ else
+ __vecho -ne '\n'
+ eqawarn "QA Notice: Package triggers severe warnings which indicate that it"
+ eqawarn " may exhibit random runtime failures."
+ eqawarn "${f}"
+ __vecho -ne '\n'
+ fi
+ fi
+
+ local cat_cmd=cat
+ [[ $PORTAGE_LOG_FILE = *.gz ]] && cat_cmd=zcat
+ [[ $reset_debug = 1 ]] && set -x
+ # Use safe cwd, avoiding unsafe import for bug #469338.
+ f=$(cd "${PORTAGE_PYM_PATH}" ; $cat_cmd "${PORTAGE_LOG_FILE}" | \
+ "${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH"/check-implicit-pointer-usage.py || die "check-implicit-pointer-usage.py failed")
+ if [[ -n ${f} ]] ; then
+
+ # In the future this will be a forced "die". In preparation,
+ # increase the log level from "qa" to "eerror" so that people
+ # are aware this is a problem that must be fixed asap.
+
+ # just warn on 32bit hosts but bail on 64bit hosts
+ case ${CHOST} in
+ alpha*|hppa64*|ia64*|powerpc64*|mips64*|sparc64*|sparcv9*|x86_64*) gentoo_bug=yes ;;
+ esac
+
+ abort=yes
+
+ if [[ $gentoo_bug = yes ]] ; then
+ eerror
+ eerror "QA Notice: Package triggers severe warnings which indicate that it"
+ eerror " will almost certainly crash on 64bit architectures."
+ eerror
+ eerror "${f}"
+ eerror
+ eerror " Please file a bug about this at http://bugs.gentoo.org/"
+ eerror " with the maintaining herd of the package."
+ eerror
+ else
+ __vecho -ne '\n'
+ eqawarn "QA Notice: Package triggers severe warnings which indicate that it"
+ eqawarn " will almost certainly crash on 64bit architectures."
+ eqawarn "${f}"
+ __vecho -ne '\n'
+ fi
+
+ fi
+ if [[ ${abort} == "yes" ]] ; then
+ if [[ $gentoo_bug = yes || $always_overflow = yes ]] ; then
+ die "install aborted due to severe warnings shown above"
+ else
+ echo "Please do not file a Gentoo bug and instead" \
+ "report the above QA issues directly to the upstream" \
+ "developers of this software." | fmt -w 70 | \
+ while read -r line ; do eqawarn "${line}" ; done
+ eqawarn "Homepage: ${HOMEPAGE}"
+ has stricter ${FEATURES} && \
+ die "install aborted due to severe warnings shown above"
+ fi
+ fi
+ fi
+}
+
+gcc_warn_check
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/bin/install-qa-check.d/90world-writable b/bin/install-qa-check.d/90world-writable
new file mode 100644
index 000000000..635612dc8
--- /dev/null
+++ b/bin/install-qa-check.d/90world-writable
@@ -0,0 +1,27 @@
+# Check for world-writable files
+
+world_writable_check() {
+ # Now we look for all world writable files.
+ # PREFIX LOCAL: keep offset prefix in the reported files
+ local unsafe_files=$(find "${ED}" -type f -perm -2 | sed -e "s:^${D}:- :")
+ # END PREFIX LOCAL
+ if [[ -n ${unsafe_files} ]] ; then
+ __vecho "QA Security Notice: world writable file(s):"
+ __vecho "${unsafe_files}"
+ __vecho "- This may or may not be a security problem, most of the time it is one."
+ __vecho "- Please double check that $PF really needs a world writeable bit and file bugs accordingly."
+ sleep 1
+ fi
+
+ local unsafe_files=$(find "${ED}" -type f '(' -perm -2002 -o -perm -4002 ')' | sed -e "s:^${D}:/:")
+ if [[ -n ${unsafe_files} ]] ; then
+ eqawarn "QA Notice: Unsafe files detected (set*id and world writable)"
+ eqawarn "${unsafe_files}"
+ die "Unsafe files found in \${D}. Portage will not install them."
+ fi
+}
+
+world_writable_check
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh
index d92103f4f..1904c258f 100644
--- a/bin/misc-functions.sh
+++ b/bin/misc-functions.sh
@@ -1,5 +1,5 @@
#!@PORTAGE_BASH@
-# Copyright 1999-2013 Gentoo Foundation
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
#
# Miscellaneous shell functions that make use of the ebuild env but don't need
@@ -176,63 +176,32 @@ install_qa_check() {
cd "${D}" || die "cd failed"
# END PREFIX LOCAL
- qa_var="QA_FLAGS_IGNORED_${ARCH/-/_}"
- eval "[[ -n \${!qa_var} ]] && QA_FLAGS_IGNORED=(\"\${${qa_var}[@]}\")"
- if [[ ${#QA_FLAGS_IGNORED[@]} -eq 1 ]] ; then
- local shopts=$-
- set -o noglob
- QA_FLAGS_IGNORED=(${QA_FLAGS_IGNORED})
- set +o noglob
- set -${shopts}
- fi
+ # Run QA checks from install-qa-check.d.
+ # Note: checks need to be run *before* stripping.
+ local f
+ # TODO: handle nullglob-like
+ for f in "${PORTAGE_BIN_PATH}"/install-qa-check.d/*; do
+ # Run in a subshell to treat it like external script,
+ # but use 'source' to pass all variables through.
+ (
+ source "${f}" || eerror "Post-install QA check ${f##*/} failed to run"
+ )
+ done
- # Check for files built without respecting *FLAGS. Note that
- # -frecord-gcc-switches must be in all *FLAGS variables, in
- # order to avoid false positive results here.
- # NOTE: This check must execute before prepall/prepstrip, since
- # prepstrip strips the .GCC.command.line sections.
- if type -P scanelf > /dev/null && ! has binchecks ${RESTRICT} && \
- [[ "${CFLAGS}" == *-frecord-gcc-switches* ]] && \
- [[ "${CXXFLAGS}" == *-frecord-gcc-switches* ]] && \
- [[ "${FFLAGS}" == *-frecord-gcc-switches* ]] && \
- [[ "${FCFLAGS}" == *-frecord-gcc-switches* ]] ; then
- rm -f "${T}"/scanelf-ignored-CFLAGS.log
- for x in $(scanelf -qyRF '#k%p' -k '!.GCC.command.line' "${ED}") ; do
- # Separate out file types that are known to support
- # .GCC.command.line sections, using the `file` command
- # similar to how prepstrip uses it.
- f=$(file "${x}") || continue
- [[ -z ${f} ]] && continue
- if [[ ${f} == *"SB executable"* ||
- ${f} == *"SB shared object"* ]] ; then
- echo "${x}" >> "${T}"/scanelf-ignored-CFLAGS.log
+ # Run QA checks from repositories
+ # (yes, PORTAGE_ECLASS_LOCATIONS contains repo paths...)
+ local repo_location
+ for repo_location in "${PORTAGE_ECLASS_LOCATIONS[@]}"; do
+ for f in "${repo_location}"/metadata/install-qa-check.d/*; do
+ if [[ -f ${f} ]]; then
+ (
+ # allow inheriting eclasses
+ _IN_INSTALL_QA_CHECK=1
+ source "${f}" || eerror "Post-install QA check ${f##*/} failed to run"
+ )
fi
done
-
- if [[ -f "${T}"/scanelf-ignored-CFLAGS.log ]] ; then
-
- if [ "${QA_STRICT_FLAGS_IGNORED-unset}" = unset ] ; then
- for x in "${QA_FLAGS_IGNORED[@]}" ; do
- sed -e "s#^${x#/}\$##" -i "${T}"/scanelf-ignored-CFLAGS.log
- done
- fi
- # Filter anything under /usr/lib/debug/ in order to avoid
- # duplicate warnings for splitdebug files.
- sed -e "s#^usr/lib/debug/.*##" -e "/^\$/d" -e "s#^#/#" \
- -i "${T}"/scanelf-ignored-CFLAGS.log
- f=$(<"${T}"/scanelf-ignored-CFLAGS.log)
- if [[ -n ${f} ]] ; then
- __vecho -ne '\n'
- eqawarn "${BAD}QA Notice: Files built without respecting CFLAGS have been detected${NORMAL}"
- eqawarn " Please include the following list of files in your report:"
- eqawarn "${f}"
- __vecho -ne '\n'
- sleep 1
- else
- rm -f "${T}"/scanelf-ignored-CFLAGS.log
- fi
- fi
- fi
+ done
export STRIP_MASK
prepall
@@ -240,62 +209,6 @@ install_qa_check() {
ecompressdir --dequeue
ecompress --dequeue
- # Prefix specific checks
- [[ ${ED} != ${D} ]] && install_qa_check_prefix
-
- f=
- for x in etc/app-defaults usr/man usr/info usr/X11R6 usr/doc usr/locale ; do
- [[ -d ${ED}/$x ]] && f+=" $x\n"
- done
- if [[ -n $f ]] ; then
- eqawarn "QA Notice: This ebuild installs into the following deprecated directories:"
- eqawarn
- eqawarn "$f"
- fi
-
- # It's ok create these directories, but not to install into them. #493154
- # TODO: We should add var/lib to this list.
- f=
- for x in var/cache var/lock var/run run ; do
- if [[ ! -L ${ED}/${x} && -d ${ED}/${x} ]] ; then
- if [[ -z $(find "${ED}/${x}" -prune -empty) ]] ; then
- f+=$(cd "${ED}"; find "${x}" -printf ' %p\n')
- fi
- fi
- done
- if [[ -n ${f} ]] ; then
- eqawarn "QA Notice: This ebuild installs into paths that should be created at runtime."
- eqawarn " To fix, simply do not install into these directories. Instead, your package"
- eqawarn " should create dirs on the fly at runtime as needed via init scripts/etc..."
- eqawarn
- eqawarn "${f}"
- fi
-
- set +f
- f=
- for x in "${ED}etc/udev/rules.d/"* "${ED}lib"*"/udev/rules.d/"* ; do
- [[ -e ${x} ]] || continue
- [[ ${x} == ${ED}lib/udev/rules.d/* ]] && continue
- f+=" ${x#${ED}}\n"
- done
- if [[ -n $f ]] ; then
- eqawarn "QA Notice: udev rules should be installed in /lib/udev/rules.d:"
- eqawarn
- eqawarn "$f"
- fi
-
- # Now we look for all world writable files.
- # PREFIX LOCAL: keep offset in the paths
- local unsafe_files=$(find "${ED}" -type f -perm -2 | sed -e "s:^${D}:- :")
- # END PREFIX LOCAL
- if [[ -n ${unsafe_files} ]] ; then
- __vecho "QA Security Notice: world writable file(s):"
- __vecho "${unsafe_files}"
- __vecho "- This may or may not be a security problem, most of the time it is one."
- __vecho "- Please double check that $PF really needs a world writeable bit and file bugs accordingly."
- sleep 1
- fi
-
# PREFIX LOCAL:
# anything outside the prefix should be caught by the Prefix QA
# check, so if there's nothing in ED, we skip searching for QA
@@ -329,238 +242,6 @@ install_qa_check() {
}
install_qa_check_elf() {
- if type -P scanelf > /dev/null && ! has binchecks ${RESTRICT}; then
- local insecure_rpath=0 tmp_quiet=${PORTAGE_QUIET}
- local x
-
- # display warnings when using stricter because we die afterwards
- if has stricter ${FEATURES} ; then
- unset PORTAGE_QUIET
- fi
-
- # Make sure we disallow insecure RUNPATH/RPATHs.
- # 1) References to PORTAGE_BUILDDIR are banned because it's a
- # security risk. We don't want to load files from a
- # temporary directory.
- # 2) If ROOT != "/", references to ROOT are banned because
- # that directory won't exist on the target system.
- # 3) Null paths are banned because the loader will search $PWD when
- # it finds null paths.
- local forbidden_dirs="${PORTAGE_BUILDDIR}"
- if [[ -n "${ROOT}" && "${ROOT}" != "/" ]]; then
- forbidden_dirs+=" ${ROOT}"
- fi
- local dir l rpath_files=$(scanelf -F '%F:%r' -qBR "${ED}")
- f=""
- for dir in ${forbidden_dirs}; do
- for l in $(echo "${rpath_files}" | grep -E ":${dir}|::|: "); do
- f+=" ${l%%:*}\n"
- if ! has stricter ${FEATURES}; then
- __vecho "Auto fixing rpaths for ${l%%:*}"
- TMPDIR="${dir}" scanelf -BXr "${l%%:*}" -o /dev/null
- fi
- done
- done
-
- # Reject set*id binaries with $ORIGIN in RPATH #260331
- x=$(
- find "${ED}" -type f \( -perm -u+s -o -perm -g+s \) -print0 | \
- xargs -0 scanelf -qyRF '%r %p' | grep '$ORIGIN'
- )
-
- # Print QA notice.
- if [[ -n ${f}${x} ]] ; then
- __vecho -ne '\n'
- eqawarn "QA Notice: The following files contain insecure RUNPATHs"
- eqawarn " Please file a bug about this at http://bugs.gentoo.org/"
- eqawarn " with the maintaining herd of the package."
- eqawarn "${f}${f:+${x:+\n}}${x}"
- __vecho -ne '\n'
- if [[ -n ${x} ]] || has stricter ${FEATURES} ; then
- insecure_rpath=1
- fi
- fi
-
- # TEXTRELs are baaaaaaaad
- # Allow devs to mark things as ignorable ... e.g. things that are
- # binary-only and upstream isn't cooperating (nvidia-glx) ... we
- # allow ebuild authors to set QA_TEXTRELS_arch and QA_TEXTRELS ...
- # the former overrides the latter ... regexes allowed ! :)
- qa_var="QA_TEXTRELS_${ARCH/-/_}"
- [[ -n ${!qa_var} ]] && QA_TEXTRELS=${!qa_var}
- [[ -n ${QA_STRICT_TEXTRELS} ]] && QA_TEXTRELS=""
- export QA_TEXTRELS="${QA_TEXTRELS} lib*/modules/*.ko"
- f=$(scanelf -qyRF '%t %p' "${ED}" | grep -v 'usr/lib/debug/')
- if [[ -n ${f} ]] ; then
- scanelf -qyRAF '%T %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-textrel.log
- __vecho -ne '\n'
- eqawarn "QA Notice: The following files contain runtime text relocations"
- eqawarn " Text relocations force the dynamic linker to perform extra"
- eqawarn " work at startup, waste system resources, and may pose a security"
- eqawarn " risk. On some architectures, the code may not even function"
- eqawarn " properly, if at all."
- eqawarn " For more information, see http://hardened.gentoo.org/pic-fix-guide.xml"
- eqawarn " Please include the following list of files in your report:"
- eqawarn "${f}"
- __vecho -ne '\n'
- die_msg="${die_msg} textrels,"
- sleep 1
- fi
-
- # Also, executable stacks only matter on linux (and just glibc atm ...)
- f=""
- case ${CTARGET:-${CHOST}} in
- *-linux-gnu*)
- # Check for files with executable stacks, but only on arches which
- # are supported at the moment. Keep this list in sync with
- # http://www.gentoo.org/proj/en/hardened/gnu-stack.xml (Arch Status)
- case ${CTARGET:-${CHOST}} in
- arm*|i?86*|ia64*|m68k*|s390*|sh*|x86_64*)
- # Allow devs to mark things as ignorable ... e.g. things
- # that are binary-only and upstream isn't cooperating ...
- # we allow ebuild authors to set QA_EXECSTACK_arch and
- # QA_EXECSTACK ... the former overrides the latter ...
- # regexes allowed ! :)
-
- qa_var="QA_EXECSTACK_${ARCH/-/_}"
- [[ -n ${!qa_var} ]] && QA_EXECSTACK=${!qa_var}
- [[ -n ${QA_STRICT_EXECSTACK} ]] && QA_EXECSTACK=""
- qa_var="QA_WX_LOAD_${ARCH/-/_}"
- [[ -n ${!qa_var} ]] && QA_WX_LOAD=${!qa_var}
- [[ -n ${QA_STRICT_WX_LOAD} ]] && QA_WX_LOAD=""
- export QA_EXECSTACK="${QA_EXECSTACK} lib*/modules/*.ko"
- export QA_WX_LOAD="${QA_WX_LOAD} lib*/modules/*.ko"
- f=$(scanelf -qyRAF '%e %p' "${ED}" | grep -v 'usr/lib/debug/')
- ;;
- esac
- ;;
- esac
- if [[ -n ${f} ]] ; then
- # One more pass to help devs track down the source
- scanelf -qyRAF '%e %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-execstack.log
- __vecho -ne '\n'
- eqawarn "QA Notice: The following files contain writable and executable sections"
- eqawarn " Files with such sections will not work properly (or at all!) on some"
- eqawarn " architectures/operating systems. A bug should be filed at"
- eqawarn " http://bugs.gentoo.org/ to make sure the issue is fixed."
- eqawarn " For more information, see http://hardened.gentoo.org/gnu-stack.xml"
- eqawarn " Please include the following list of files in your report:"
- eqawarn " Note: Bugs should be filed for the respective maintainers"
- eqawarn " of the package in question and not hardened@g.o."
- eqawarn "${f}"
- __vecho -ne '\n'
- die_msg="${die_msg} execstacks"
- sleep 1
- fi
-
- # Check for files built without respecting LDFLAGS
- if [[ "${LDFLAGS}" == *,--hash-style=gnu* ]] && \
- ! has binchecks ${RESTRICT} ; then
- f=$(scanelf -qyRF '#k%p' -k .hash "${ED}")
- if [[ -n ${f} ]] ; then
- echo "${f}" > "${T}"/scanelf-ignored-LDFLAGS.log
- if [ "${QA_STRICT_FLAGS_IGNORED-unset}" = unset ] ; then
- for x in "${QA_FLAGS_IGNORED[@]}" ; do
- sed -e "s#^${x#/}\$##" -i "${T}"/scanelf-ignored-LDFLAGS.log
- done
- fi
- # Filter anything under /usr/lib/debug/ in order to avoid
- # duplicate warnings for splitdebug files.
- sed -e "s#^usr/lib/debug/.*##" -e "/^\$/d" -e "s#^#/#" \
- -i "${T}"/scanelf-ignored-LDFLAGS.log
- f=$(<"${T}"/scanelf-ignored-LDFLAGS.log)
- if [[ -n ${f} ]] ; then
- __vecho -ne '\n'
- eqawarn "${BAD}QA Notice: Files built without respecting LDFLAGS have been detected${NORMAL}"
- eqawarn " Please include the following list of files in your report:"
- eqawarn "${f}"
- __vecho -ne '\n'
- sleep 1
- else
- rm -f "${T}"/scanelf-ignored-LDFLAGS.log
- fi
- fi
- fi
-
- if [[ ${insecure_rpath} -eq 1 ]] ; then
- die "Aborting due to serious QA concerns with RUNPATH/RPATH"
- elif [[ -n ${die_msg} ]] && has stricter ${FEATURES} ; then
- die "Aborting due to QA concerns: ${die_msg}"
- fi
-
- # Check for shared libraries lacking SONAMEs
- qa_var="QA_SONAME_${ARCH/-/_}"
- eval "[[ -n \${!qa_var} ]] && QA_SONAME=(\"\${${qa_var}[@]}\")"
- f=$(scanelf -ByF '%S %p' "${ED}"{,usr/}lib*/lib*.so* | awk '$2 == "" { print }' | sed -e "s:^[[:space:]]${ED}:/:")
- if [[ -n ${f} ]] ; then
- echo "${f}" > "${T}"/scanelf-missing-SONAME.log
- if [[ "${QA_STRICT_SONAME-unset}" == unset ]] ; then
- if [[ ${#QA_SONAME[@]} -gt 1 ]] ; then
- for x in "${QA_SONAME[@]}" ; do
- sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-SONAME.log
- done
- else
- local shopts=$-
- set -o noglob
- for x in ${QA_SONAME} ; do
- sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-SONAME.log
- done
- set +o noglob
- set -${shopts}
- fi
- fi
- sed -e "/^\$/d" -i "${T}"/scanelf-missing-SONAME.log
- f=$(<"${T}"/scanelf-missing-SONAME.log)
- if [[ -n ${f} ]] ; then
- __vecho -ne '\n'
- eqawarn "QA Notice: The following shared libraries lack a SONAME"
- eqawarn "${f}"
- __vecho -ne '\n'
- sleep 1
- else
- rm -f "${T}"/scanelf-missing-SONAME.log
- fi
- fi
-
- # Check for shared libraries lacking NEEDED entries
- qa_var="QA_DT_NEEDED_${ARCH/-/_}"
- eval "[[ -n \${!qa_var} ]] && QA_DT_NEEDED=(\"\${${qa_var}[@]}\")"
- # PREFIX LOCAL: keep offset prefix in the recorded files
- f=$(scanelf -ByF '%n %p' "${ED}"{,usr/}lib*/lib*.so* | awk '$2 == "" { print }' | sed -e "s:^[[:space:]]${D}:/:")
- # END PREFIX LOCAL
- if [[ -n ${f} ]] ; then
- echo "${f}" > "${T}"/scanelf-missing-NEEDED.log
- if [[ "${QA_STRICT_DT_NEEDED-unset}" == unset ]] ; then
- if [[ ${#QA_DT_NEEDED[@]} -gt 1 ]] ; then
- for x in "${QA_DT_NEEDED[@]}" ; do
- sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-NEEDED.log
- done
- else
- local shopts=$-
- set -o noglob
- for x in ${QA_DT_NEEDED} ; do
- sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-NEEDED.log
- done
- set +o noglob
- set -${shopts}
- fi
- fi
- sed -e "/^\$/d" -i "${T}"/scanelf-missing-NEEDED.log
- f=$(<"${T}"/scanelf-missing-NEEDED.log)
- if [[ -n ${f} ]] ; then
- __vecho -ne '\n'
- eqawarn "QA Notice: The following shared libraries lack NEEDED entries"
- eqawarn "${f}"
- __vecho -ne '\n'
- sleep 1
- else
- rm -f "${T}"/scanelf-missing-NEEDED.log
- fi
- fi
-
- PORTAGE_QUIET=${tmp_quiet}
- fi
-
# Create NEEDED.ELF.2 regardless of RESTRICT=binchecks, since this info is
# too useful not to have (it's required for things like preserve-libs), and
# it's tempting for ebuild authors to set RESTRICT=binchecks for packages
@@ -591,441 +272,8 @@ install_qa_check_elf() {
}
install_qa_check_misc() {
- # PREFIX LOCAL: keep offset prefix in the reported files
- local unsafe_files=$(find "${ED}" -type f '(' -perm -2002 -o -perm -4002 ')' | sed -e "s:^${D}:/:")
- # END PREFIX LOCAL
- if [[ -n ${unsafe_files} ]] ; then
- eqawarn "QA Notice: Unsafe files detected (set*id and world writable)"
- eqawarn "${unsafe_files}"
- die "Unsafe files found in \${D}. Portage will not install them."
- fi
-
- if [[ -d ${D%/}${D} ]] ; then
- local -i INSTALLTOD=0
- while read -r -d $'\0' i ; do
- eqawarn "QA Notice: /${i##${D%/}${D}} installed in \${D}/\${D}"
- ((INSTALLTOD++))
- done < <(find "${D%/}${D}" -print0)
- die "Aborting due to QA concerns: ${INSTALLTOD} files installed in ${D%/}${D}"
- fi
-
- # Sanity check syntax errors in init.d scripts
- local d
- for d in /etc/conf.d /etc/init.d ; do
- [[ -d ${ED}/${d} ]] || continue
- for i in "${ED}"/${d}/* ; do
- [[ -L ${i} ]] && continue
- # if empty conf.d/init.d dir exists (baselayout), then i will be "/etc/conf.d/*" and not exist
- [[ ! -e ${i} ]] && continue
- if [[ ${d} == /etc/init.d && ${i} != *.sh ]] ; then
- # skip non-shell-script for bug #451386
- [[ $(head -n1 "${i}") =~ ^#!.*[[:space:]/](runscript|sh)$ ]] || continue
- fi
- bash -n "${i}" || die "The init.d file has syntax errors: ${i}"
- done
- done
-
- local checkbashisms=$(type -P checkbashisms)
- if [[ -n ${checkbashisms} ]] ; then
- for d in /etc/init.d ; do
- [[ -d ${ED}${d} ]] || continue
- for i in "${ED}${d}"/* ; do
- [[ -e ${i} ]] || continue
- [[ -L ${i} ]] && continue
- f=$("${checkbashisms}" -f "${i}" 2>&1)
- [[ $? != 0 && -n ${f} ]] || continue
- eqawarn "QA Notice: shell script appears to use non-POSIX feature(s):"
- while read -r ;
- do eqawarn " ${REPLY}"
- done <<< "${f//${ED}}"
- done
- done
- fi
-
- # Look for leaking LDFLAGS into pkg-config files
- f=$(egrep -sH '^Libs.*-Wl,(-O[012]|--hash-style)' "${ED}"/usr/*/pkgconfig/*.pc)
- if [[ -n ${f} ]] ; then
- eqawarn "QA Notice: pkg-config files with wrong LDFLAGS detected:"
- eqawarn "${f//${D}}"
- fi
-
- # this should help to ensure that all (most?) shared libraries are executable
- # and that all libtool scripts / static libraries are not executable
- local j
- for i in "${ED}"opt/*/lib* \
- "${ED}"lib* \
- "${ED}"usr/lib* ; do
- [[ ! -d ${i} ]] && continue
-
- for j in "${i}"/*.so.* "${i}"/*.so "${i}"/*.dylib "${i}"/*.dll ; do
- [[ ! -e ${j} ]] && continue
- [[ -L ${j} ]] && continue
- [[ -x ${j} ]] && continue
- __vecho "making executable: ${j#${ED}}"
- chmod +x "${j}"
- done
-
- for j in "${i}"/*.a "${i}"/*.la ; do
- [[ ! -e ${j} ]] && continue
- [[ -L ${j} ]] && continue
- [[ ! -x ${j} ]] && continue
- __vecho "removing executable bit: ${j#${ED}}"
- chmod -x "${j}"
- done
-
- for j in "${i}"/*.{a,dll,dylib,sl,so}.* "${i}"/*.{a,dll,dylib,sl,so} ; do
- [[ ! -e ${j} ]] && continue
- [[ ! -L ${j} ]] && continue
- linkdest=$(readlink "${j}")
- if [[ ${linkdest} == /* ]] ; then
- __vecho -ne '\n'
- eqawarn "QA Notice: Found an absolute symlink in a library directory:"
- eqawarn " ${j#${D}} -> ${linkdest}"
- eqawarn " It should be a relative symlink if in the same directory"
- eqawarn " or a linker script if it crosses the /usr boundary."
- fi
- done
- done
-
- # When installing static libraries into /usr/lib and shared libraries into
- # /lib, we have to make sure we have a linker script in /usr/lib along side
- # the static library, or gcc will utilize the static lib when linking :(.
- # http://bugs.gentoo.org/4411
- abort="no"
- local a s
- for a in "${ED}"usr/lib*/*.a ; do
- # PREFIX LOCAL: support MachO objects
- [[ ${CHOST} == *-darwin* ]] \
- && s=${a%.a}.dylib \
- || s=${a%.a}.so
- # END PREFIX LOCAL
- if [[ ! -e ${s} ]] ; then
- s=${s%usr/*}${s##*/usr/}
- if [[ -e ${s} ]] ; then
- __vecho -ne '\n'
- eqawarn "QA Notice: Missing gen_usr_ldscript for ${s##*/}"
- abort="yes"
- fi
- fi
- done
- [[ ${abort} == "yes" ]] && die "add those ldscripts"
-
- # Make sure people don't store libtool files or static libs in /lib
- # PREFIX LOCAL: on AIX, "dynamic libs" have extension .a, so don't
- # get false positives
- [[ ${CHOST} == *-aix* ]] \
- && f=$(ls "${ED}"lib*/*.la 2>/dev/null || true) \
- || f=$(ls "${ED}"lib*/*.{a,la} 2>/dev/null)
- # END PREFIX LOCAL
- if [[ -n ${f} ]] ; then
- __vecho -ne '\n'
- eqawarn "QA Notice: Excessive files found in the / partition"
- eqawarn "${f}"
- __vecho -ne '\n'
- die "static archives (*.a) and libtool library files (*.la) belong in /usr/lib*, not /lib*"
- fi
-
- # Verify that the libtool files don't contain bogus $D entries.
- local abort=no gentoo_bug=no always_overflow=no
- for a in "${ED}"usr/lib*/*.la ; do
- s=${a##*/}
- if grep -qs "${ED}" "${a}" ; then
- __vecho -ne '\n'
- eqawarn "QA Notice: ${s} appears to contain PORTAGE_TMPDIR paths"
- abort="yes"
- fi
- done
- [[ ${abort} == "yes" ]] && die "soiled libtool library files found"
-
- # Evaluate misc gcc warnings
- if [[ -n ${PORTAGE_LOG_FILE} && -r ${PORTAGE_LOG_FILE} ]] ; then
- # In debug mode, this variable definition and corresponding grep calls
- # will produce false positives if they're shown in the trace.
- local reset_debug=0
- if [[ ${-/x/} != $- ]] ; then
- set +x
- reset_debug=1
- fi
- local m msgs=(
- ": warning: dereferencing type-punned pointer will break strict-aliasing rules"
- ": warning: dereferencing pointer .* does break strict-aliasing rules"
- ": warning: implicit declaration of function"
- ": warning: incompatible implicit declaration of built-in function"
- ": warning: is used uninitialized in this function" # we'll ignore "may" and "might"
- ": warning: comparisons like X<=Y<=Z do not have their mathematical meaning"
- ": warning: null argument where non-null required"
- ": warning: array subscript is below array bounds"
- ": warning: array subscript is above array bounds"
- ": warning: attempt to free a non-heap object"
- ": warning: .* called with .*bigger.* than .* destination buffer"
- ": warning: call to .* will always overflow destination buffer"
- ": warning: assuming pointer wraparound does not occur when comparing"
- ": warning: hex escape sequence out of range"
- ": warning: [^ ]*-hand operand of comma .*has no effect"
- ": warning: converting to non-pointer type .* from NULL"
- ": warning: NULL used in arithmetic"
- ": warning: passing NULL to non-pointer argument"
- ": warning: the address of [^ ]* will always evaluate as"
- ": warning: the address of [^ ]* will never be NULL"
- ": warning: too few arguments for format"
- ": warning: reference to local variable .* returned"
- ": warning: returning reference to temporary"
- ": warning: function returns address of local variable"
- ": warning: .*\\[-Wsizeof-pointer-memaccess\\]"
- ": warning: .*\\[-Waggressive-loop-optimizations\\]"
- # this may be valid code :/
- #": warning: multi-character character constant"
- # need to check these two ...
- #": warning: assuming signed overflow does not occur when"
- #": warning: comparison with string literal results in unspecified behav"
- # yacc/lex likes to trigger this one
- #": warning: extra tokens at end of .* directive"
- # only gcc itself triggers this ?
- #": warning: .*noreturn.* function does return"
- # these throw false positives when 0 is used instead of NULL
- #": warning: missing sentinel in function call"
- #": warning: not enough variable arguments to fit a sentinel"
- )
- abort="no"
- i=0
- local grep_cmd=grep
- [[ $PORTAGE_LOG_FILE = *.gz ]] && grep_cmd=zgrep
- while [[ -n ${msgs[${i}]} ]] ; do
- m=${msgs[$((i++))]}
- # force C locale to work around slow unicode locales #160234
- f=$(LC_ALL=C $grep_cmd "${m}" "${PORTAGE_LOG_FILE}")
- if [[ -n ${f} ]] ; then
- abort="yes"
- # for now, don't make this fatal (see bug #337031)
- #case "$m" in
- # ": warning: call to .* will always overflow destination buffer") always_overflow=yes ;;
- #esac
- if [[ $always_overflow = yes ]] ; then
- eerror
- eerror "QA Notice: Package triggers severe warnings which indicate that it"
- eerror " may exhibit random runtime failures."
- eerror
- eerror "${f}"
- eerror
- eerror " Please file a bug about this at http://bugs.gentoo.org/"
- eerror " with the maintaining herd of the package."
- eerror
- else
- __vecho -ne '\n'
- eqawarn "QA Notice: Package triggers severe warnings which indicate that it"
- eqawarn " may exhibit random runtime failures."
- eqawarn "${f}"
- __vecho -ne '\n'
- fi
- fi
- done
- local cat_cmd=cat
- [[ $PORTAGE_LOG_FILE = *.gz ]] && cat_cmd=zcat
- [[ $reset_debug = 1 ]] && set -x
- # Use safe cwd, avoiding unsafe import for bug #469338.
- f=$(cd "${PORTAGE_PYM_PATH}" ; $cat_cmd "${PORTAGE_LOG_FILE}" | \
- "${PORTAGE_PYTHON:-@PREFIX_PORTAGE_PYTHON@}" "$PORTAGE_BIN_PATH"/check-implicit-pointer-usage.py || die "check-implicit-pointer-usage.py failed")
- if [[ -n ${f} ]] ; then
-
- # In the future this will be a forced "die". In preparation,
- # increase the log level from "qa" to "eerror" so that people
- # are aware this is a problem that must be fixed asap.
-
- # just warn on 32bit hosts but bail on 64bit hosts
- case ${CHOST} in
- alpha*|hppa64*|ia64*|powerpc64*|mips64*|sparc64*|sparcv9*|x86_64*) gentoo_bug=yes ;;
- esac
-
- abort=yes
-
- if [[ $gentoo_bug = yes ]] ; then
- eerror
- eerror "QA Notice: Package triggers severe warnings which indicate that it"
- eerror " will almost certainly crash on 64bit architectures."
- eerror
- eerror "${f}"
- eerror
- eerror " Please file a bug about this at http://bugs.gentoo.org/"
- eerror " with the maintaining herd of the package."
- eerror
- else
- __vecho -ne '\n'
- eqawarn "QA Notice: Package triggers severe warnings which indicate that it"
- eqawarn " will almost certainly crash on 64bit architectures."
- eqawarn "${f}"
- __vecho -ne '\n'
- fi
-
- fi
- if [[ ${abort} == "yes" ]] ; then
- if [[ $gentoo_bug = yes || $always_overflow = yes ]] ; then
- die "install aborted due to severe warnings shown above"
- else
- echo "Please do not file a Gentoo bug and instead" \
- "report the above QA issues directly to the upstream" \
- "developers of this software." | fmt -w 70 | \
- while read -r line ; do eqawarn "${line}" ; done
- eqawarn "Homepage: ${HOMEPAGE}"
- has stricter ${FEATURES} && \
- die "install aborted due to severe warnings shown above"
- fi
- fi
- fi
-
# Portage regenerates this on the installed system.
rm -f "${ED}"/usr/share/info/dir{,.gz,.bz2} || die "rm failed!"
-
- if has multilib-strict ${FEATURES} && \
- [[ -x ${EPREFIX}/usr/bin/file && -x ${EPREFIX}/usr/bin/find ]] && \
- [[ -n ${MULTILIB_STRICT_DIRS} && -n ${MULTILIB_STRICT_DENY} ]]
- then
- rm -f "${T}/multilib-strict.log"
- local abort=no dir file
- MULTILIB_STRICT_EXEMPT=$(echo ${MULTILIB_STRICT_EXEMPT} | sed -e 's:\([(|)]\):\\\1:g')
- for dir in ${MULTILIB_STRICT_DIRS} ; do
- [[ -d ${ED}/${dir} ]] || continue
- for file in $(find ${ED}/${dir} -type f | grep -v "^${ED}/${dir}/${MULTILIB_STRICT_EXEMPT}"); do
- if file ${file} | egrep -q "${MULTILIB_STRICT_DENY}" ; then
- echo "${file#${ED}//}" >> "${T}/multilib-strict.log"
- fi
- done
- done
-
- if [[ -s ${T}/multilib-strict.log ]] ; then
- if [[ ${#QA_MULTILIB_PATHS[@]} -eq 1 ]] ; then
- local shopts=$-
- set -o noglob
- QA_MULTILIB_PATHS=(${QA_MULTILIB_PATHS})
- set +o noglob
- set -${shopts}
- fi
- if [ "${QA_STRICT_MULTILIB_PATHS-unset}" = unset ] ; then
- for x in "${QA_MULTILIB_PATHS[@]}" ; do
- sed -e "s#^${x#/}\$##" -i "${T}/multilib-strict.log"
- done
- sed -e "/^\$/d" -i "${T}/multilib-strict.log"
- fi
- if [[ -s ${T}/multilib-strict.log ]] ; then
- abort=yes
- echo "Files matching a file type that is not allowed:"
- while read -r ; do
- echo " ${REPLY}"
- done < "${T}/multilib-strict.log"
- fi
- fi
-
- [[ ${abort} == yes ]] && die "multilib-strict check failed!"
- fi
-}
-
-install_qa_check_prefix() {
- if [[ -d ${ED%/}/${D} ]] ; then
- find "${ED%/}/${D}" | \
- while read i ; do
- eqawarn "QA Notice: /${i##${ED%/}/${D}} installed in \${ED}/\${D}"
- done
- die "Aborting due to QA concerns: files installed in ${ED}/${D}"
- fi
-
- if [[ -d ${ED%/}/${EPREFIX} ]] ; then
- find "${ED%/}/${EPREFIX}/" | \
- while read i ; do
- eqawarn "QA Notice: ${i#${D}} double prefix"
- done
- die "Aborting due to QA concerns: double prefix files installed"
- fi
-
- if [[ -d ${D} ]] ; then
- INSTALLTOD=$(find ${D%/} | egrep -v "^${ED}" | sed -e "s|^${D%/}||" | awk '{if (length($0) <= length("'"${EPREFIX}"'")) { if (substr("'"${EPREFIX}"'", 1, length($0)) != $0) {print $0;} } else if (substr($0, 1, length("'"${EPREFIX}"'")) != "'"${EPREFIX}"'") {print $0;} }')
- if [[ -n ${INSTALLTOD} ]] ; then
- eqawarn "QA Notice: the following files are outside of the prefix:"
- eqawarn "${INSTALLTOD}"
- die "Aborting due to QA concerns: there are files installed outside the prefix"
- fi
- fi
-
- # all further checks rely on ${ED} existing
- [[ -d ${ED} ]] || return
-
- # check shebangs, bug #282539
- rm -f "${T}"/non-prefix-shebangs-errs
- local WHITELIST=" /usr/bin/env "
- # this is hell expensive, but how else?
- find "${ED}" -executable \! -type d -print0 \
- | xargs -0 grep -H -n -m1 "^#!" \
- | while read f ;
- do
- local fn=${f%%:*}
- local pos=${f#*:} ; pos=${pos%:*}
- local line=${f##*:}
- # shebang always appears on the first line ;)
- [[ ${pos} != 1 ]] && continue
- local oldIFS=${IFS}
- IFS=$'\r'$'\n'$'\t'" "
- line=( ${line#"#!"} )
- IFS=${oldIFS}
- [[ ${WHITELIST} == *" ${line[0]} "* ]] && continue
- local fp=${fn#${D}} ; fp=/${fp%/*}
- # line[0] can be an absolutised path, bug #342929
- local eprefix=$(canonicalize ${EPREFIX})
- local rf=${fn}
- # in case we deal with a symlink, make sure we don't replace it
- # with a real file (sed -i does that)
- if [[ -L ${fn} ]] ; then
- rf=$(readlink ${fn})
- [[ ${rf} != /* ]] && rf=${fn%/*}/${rf}
- # ignore symlinks pointing to outside prefix
- # as seen in sys-devel/native-cctools
- [[ $(canonicalize "/${rf#${D}}") != ${eprefix}/* ]] && continue
- fi
- # does the shebang start with ${EPREFIX}, and does it exist?
- if [[ ${line[0]} == ${EPREFIX}/* || ${line[0]} == ${eprefix}/* ]] ; then
- if [[ ! -e ${ROOT%/}${line[0]} && ! -e ${D%/}${line[0]} ]] ; then
- # hmm, refers explicitly to $EPREFIX, but doesn't exist,
- # if it's in PATH that's wrong in any case
- if [[ ":${PATH}:" == *":${fp}:"* ]] ; then
- echo "${fn#${D}}:${line[0]} (explicit EPREFIX but target not found)" \
- >> "${T}"/non-prefix-shebangs-errs
- else
- eqawarn "${fn#${D}} has explicit EPREFIX in shebang but target not found (${line[0]})"
- fi
- fi
- continue
- fi
- # unprefixed shebang, is the script directly in $PATH or an init
- # script?
- if [[ ":${PATH}:${EPREFIX}/etc/init.d:" == *":${fp}:"* ]] ; then
- if [[ -e ${EROOT}${line[0]} || -e ${ED}${line[0]} ]] ; then
- # is it unprefixed, but we can just fix it because a
- # prefixed variant exists
- eqawarn "prefixing shebang of ${fn#${D}}"
- # statement is made idempotent on purpose, because
- # symlinks may point to the same target, and hence the
- # same real file may be sedded multiple times since we
- # read the shebangs in one go upfront for performance
- # reasons
- sed -i -e '1s:^#! \?'"${line[0]}"':#!'"${EPREFIX}"${line[0]}':' "${rf}"
- continue
- else
- # this is definitely wrong: script in $PATH and invalid shebang
- echo "${fn#${D}}:${line[0]} (script ${fn##*/} installed in PATH but interpreter ${line[0]} not found)" \
- >> "${T}"/non-prefix-shebangs-errs
- fi
- else
- # unprefixed/invalid shebang, but outside $PATH, this may be
- # intended (e.g. config.guess) so remain silent by default
- has stricter ${FEATURES} && \
- eqawarn "invalid shebang in ${fn#${D}}: ${line[0]}"
- fi
- done
- if [[ -e "${T}"/non-prefix-shebangs-errs ]] ; then
- eqawarn "QA Notice: the following files use invalid (possible non-prefixed) shebangs:"
- while read line ; do
- eqawarn " ${line}"
- done < "${T}"/non-prefix-shebangs-errs
- rm -f "${T}"/non-prefix-shebangs-errs
- die "Aborting due to QA concerns: invalid shebangs found"
- fi
}
install_qa_check_macho() {
diff --git a/bin/phase-functions.sh b/bin/phase-functions.sh
index 042fab53e..2dece5ada 100644
--- a/bin/phase-functions.sh
+++ b/bin/phase-functions.sh
@@ -382,6 +382,19 @@ __dyn_prepare() {
trap - SIGINT SIGQUIT
}
+# @FUNCTION: __start_distcc
+# @DESCRIPTION:
+# Start distcc-pump if necessary.
+__start_distcc() {
+ if has distcc $FEATURES && has distcc-pump $FEATURES ; then
+ if [[ -z $INCLUDE_SERVER_PORT ]] || [[ ! -w $INCLUDE_SERVER_PORT ]] ; then
+ # adding distcc to PATH repeatedly results in fatal distcc recursion :)
+ eval $(pump --startup | grep -v PATH)
+ trap "pump --shutdown >/dev/null" EXIT
+ fi
+ fi
+}
+
__dyn_configure() {
if [[ -e $PORTAGE_BUILDDIR/.configured ]] ; then
@@ -401,6 +414,7 @@ __dyn_configure() {
fi
trap __abort_configure SIGINT SIGQUIT
+ __start_distcc
__ebuild_phase pre_src_configure
@@ -434,13 +448,7 @@ __dyn_compile() {
fi
trap __abort_compile SIGINT SIGQUIT
-
- if has distcc $FEATURES && has distcc-pump $FEATURES ; then
- if [[ -z $INCLUDE_SERVER_PORT ]] || [[ ! -w $INCLUDE_SERVER_PORT ]] ; then
- eval $(pump --startup)
- trap "pump --shutdown" EXIT
- fi
- fi
+ __start_distcc
__ebuild_phase pre_src_compile
@@ -464,6 +472,8 @@ __dyn_test() {
fi
trap "__abort_test" SIGINT SIGQUIT
+ __start_distcc
+
if [ -d "${S}" ]; then
cd "${S}"
else
@@ -489,7 +499,11 @@ __dyn_test() {
local save_sp=${SANDBOX_PREDICT}
addpredict /
__ebuild_phase pre_src_test
+
+ __vecho ">>> Test phase: ${CATEGORY}/${PF}"
__ebuild_phase src_test
+ __vecho ">>> Completed testing ${CATEGORY}/${PF}"
+
>> "$PORTAGE_BUILDDIR/.tested" || \
die "Failed to create $PORTAGE_BUILDDIR/.tested"
__ebuild_phase post_src_test
@@ -509,6 +523,8 @@ __dyn_install() {
return 0
fi
trap "__abort_install" SIGINT SIGQUIT
+ __start_distcc
+
__ebuild_phase pre_src_install
if ___eapi_has_prefix_variables; then
@@ -735,91 +751,84 @@ __ebuild_phase_funcs() {
[ $# -ne 2 ] && die "expected exactly 2 args, got $#: $*"
local eapi=$1
local phase_func=$2
- local default_phases="pkg_nofetch src_unpack src_prepare src_configure
- src_compile src_install src_test"
- local x y default_func=""
-
- for x in pkg_nofetch src_unpack src_test ; do
- declare -F $x >/dev/null || \
- eval "$x() { __eapi0_$x \"\$@\" ; }"
+ local all_phases="src_compile pkg_config src_configure pkg_info
+ src_install pkg_nofetch pkg_postinst pkg_postrm pkg_preinst
+ src_prepare pkg_prerm pkg_pretend pkg_setup src_test src_unpack"
+ local x
+
+ # First, set up the error handlers for default*
+ for x in ${all_phases} ; do
+ eval "default_${x}() {
+ die \"default_${x}() is not supported in EAPI='${eapi}' in phase ${phase_func}\"
+ }"
done
+ # We can just call the specific handler -- it will either error out
+ # on invalid phase or run it.
+ eval "default() {
+ default_${phase_func}
+ }"
+
case "$eapi" in
+ 0|1) # EAPIs not supporting 'default'
- 0|1)
+ for x in pkg_nofetch src_unpack src_test ; do
+ declare -F $x >/dev/null || \
+ eval "$x() { __eapi0_$x; }"
+ done
if ! declare -F src_compile >/dev/null ; then
case "$eapi" in
0)
- src_compile() { __eapi0_src_compile "$@" ; }
+ src_compile() { __eapi0_src_compile; }
;;
*)
- src_compile() { __eapi1_src_compile "$@" ; }
+ src_compile() { __eapi1_src_compile; }
;;
esac
fi
-
- for x in $default_phases ; do
- eval "default_$x() {
- die \"default_$x() is not supported with EAPI='$eapi' during phase $phase_func\"
- }"
- done
-
- eval "default() {
- die \"default() is not supported with EAPI='$eapi' during phase $phase_func\"
- }"
-
;;
- *)
-
+ *) # EAPIs supporting 'default'
+
+ # defaults starting with EAPI 0
+ [[ ${phase_func} == pkg_nofetch ]] && \
+ default_pkg_nofetch() { __eapi0_pkg_nofetch; }
+ [[ ${phase_func} == src_unpack ]] && \
+ default_src_unpack() { __eapi0_src_unpack; }
+ [[ ${phase_func} == src_test ]] && \
+ default_src_test() { __eapi0_src_test; }
+
+ # defaults starting with EAPI 2
+ [[ ${phase_func} == src_prepare ]] && \
+ default_src_prepare() { __eapi2_src_prepare; }
+ [[ ${phase_func} == src_configure ]] && \
+ default_src_configure() { __eapi2_src_configure; }
+ [[ ${phase_func} == src_compile ]] && \
+ default_src_compile() { __eapi2_src_compile; }
+
+ # bind supported phases to the defaults
+ declare -F pkg_nofetch >/dev/null || \
+ pkg_nofetch() { default; }
+ declare -F src_unpack >/dev/null || \
+ src_unpack() { default; }
+ declare -F src_prepare >/dev/null || \
+ src_prepare() { default; }
declare -F src_configure >/dev/null || \
- src_configure() { __eapi2_src_configure "$@" ; }
-
+ src_configure() { default; }
declare -F src_compile >/dev/null || \
- src_compile() { __eapi2_src_compile "$@" ; }
-
- has $eapi 2 3 || declare -F src_install >/dev/null || \
- src_install() { __eapi4_src_install "$@" ; }
-
- if has $phase_func $default_phases ; then
-
- __eapi2_pkg_nofetch () { __eapi0_pkg_nofetch "$@" ; }
- __eapi2_src_unpack () { __eapi0_src_unpack "$@" ; }
- __eapi2_src_prepare () { true ; }
- __eapi2_src_test () { __eapi0_src_test "$@" ; }
- __eapi2_src_install () { die "$FUNCNAME is not supported" ; }
-
- for x in $default_phases ; do
- eval "default_$x() { __eapi2_$x \"\$@\" ; }"
- done
-
- eval "default() { __eapi2_$phase_func \"\$@\" ; }"
+ src_compile() { default; }
+ declare -F src_test >/dev/null || \
+ src_test() { default; }
- case "$eapi" in
- 2|3)
- ;;
- *)
- eval "default_src_install() { __eapi4_src_install \"\$@\" ; }"
- [[ $phase_func = src_install ]] && \
- eval "default() { __eapi4_$phase_func \"\$@\" ; }"
- ;;
- esac
-
- else
-
- for x in $default_phases ; do
- eval "default_$x() {
- die \"default_$x() is not supported in phase $default_func\"
- }"
- done
-
- eval "default() {
- die \"default() is not supported with EAPI='$eapi' during phase $phase_func\"
- }"
+ # defaults starting with EAPI 4
+ if ! has ${eapi} 2 3; then
+ [[ ${phase_func} == src_install ]] && \
+ default_src_install() { __eapi4_src_install; }
+ declare -F src_install >/dev/null || \
+ src_install() { default; }
fi
-
;;
esac
}
diff --git a/bin/phase-helpers.sh b/bin/phase-helpers.sh
index d2f78aa62..0ef083d32 100644
--- a/bin/phase-helpers.sh
+++ b/bin/phase-helpers.sh
@@ -521,23 +521,20 @@ econf() {
done
fi
+ local conf_args=()
if ___eapi_econf_passes_--disable-dependency-tracking || ___eapi_econf_passes_--disable-silent-rules; then
local conf_help=$("${ECONF_SOURCE}/configure" --help 2>/dev/null)
if ___eapi_econf_passes_--disable-dependency-tracking; then
- case "${conf_help}" in
- *--disable-dependency-tracking*)
- set -- --disable-dependency-tracking "$@"
- ;;
- esac
+ if [[ ${conf_help} == *--disable-dependency-tracking* ]]; then
+ conf_args+=( --disable-dependency-tracking )
+ fi
fi
if ___eapi_econf_passes_--disable-silent-rules; then
- case "${conf_help}" in
- *--disable-silent-rules*)
- set -- --disable-silent-rules "$@"
- ;;
- esac
+ if [[ ${conf_help} == *--disable-silent-rules* ]]; then
+ conf_args+=( --disable-silent-rules )
+ fi
fi
fi
@@ -554,7 +551,9 @@ econf() {
CONF_PREFIX=${CONF_PREFIX#*=}
[[ ${CONF_PREFIX} != /* ]] && CONF_PREFIX="/${CONF_PREFIX}"
[[ ${CONF_LIBDIR} != /* ]] && CONF_LIBDIR="/${CONF_LIBDIR}"
- set -- --libdir="$(__strip_duplicate_slashes "${CONF_PREFIX}${CONF_LIBDIR}")" "$@"
+ conf_args+=(
+ --libdir="$(__strip_duplicate_slashes "${CONF_PREFIX}${CONF_LIBDIR}")"
+ )
fi
# Handle arguments containing quoted whitespace (see bug #457136).
@@ -570,6 +569,7 @@ econf() {
--datadir="${EPREFIX}"/usr/share \
--sysconfdir="${EPREFIX}"/etc \
--localstatedir="${EPREFIX}"/var/lib \
+ "${conf_args[@]}" \
"$@" \
"${EXTRA_ECONF[@]}"
__vecho "${ECONF_SOURCE}/configure" "$@"
@@ -617,8 +617,8 @@ einstall() {
mandir="${ED}usr/share/man" \
sysconfdir="${ED}etc" \
${LOCAL_EXTRA_EINSTALL} \
- ${MAKEOPTS} ${EXTRA_EMAKE} -j1 \
- "$@" install
+ ${MAKEOPTS} -j1 \
+ "$@" ${EXTRA_EMAKE} install
fi
${MAKE:-make} prefix="${ED}usr" \
datadir="${ED}usr/share" \
@@ -627,8 +627,8 @@ einstall() {
mandir="${ED}usr/share/man" \
sysconfdir="${ED}etc" \
${LOCAL_EXTRA_EINSTALL} \
- ${MAKEOPTS} ${EXTRA_EMAKE} -j1 \
- "$@" install || die "einstall failed"
+ ${MAKEOPTS} -j1 \
+ "$@" ${EXTRA_EMAKE} install || die "einstall failed"
else
die "no Makefile found"
fi
@@ -667,15 +667,13 @@ __eapi0_src_test() {
internal_opts+=" -j1"
fi
if $emake_cmd ${internal_opts} check -n &> /dev/null; then
- __vecho ">>> Test phase [check]: ${CATEGORY}/${PF}"
+ __vecho "${emake_cmd} ${internal_opts} check" >&2
$emake_cmd ${internal_opts} check || \
die "Make check failed. See above for details."
elif $emake_cmd ${internal_opts} test -n &> /dev/null; then
- __vecho ">>> Test phase [test]: ${CATEGORY}/${PF}"
+ __vecho "${emake_cmd} ${internal_opts} test" >&2
$emake_cmd ${internal_opts} test || \
die "Make test failed. See above for details."
- else
- __vecho ">>> Test phase [none]: ${CATEGORY}/${PF}"
fi
}
@@ -684,6 +682,10 @@ __eapi1_src_compile() {
__eapi2_src_compile
}
+__eapi2_src_prepare() {
+ :
+}
+
__eapi2_src_configure() {
if [[ -x ${ECONF_SOURCE:-.}/configure ]] ; then
econf
diff --git a/bin/portageq b/bin/portageq
index ea9dfde24..7b9e17739 100755
--- a/bin/portageq
+++ b/bin/portageq
@@ -29,16 +29,16 @@ if os.environ.__contains__("PORTAGE_PYTHONPATH"):
else:
pym_path = os.path.join(os.path.dirname(
os.path.dirname(os.path.realpath(__file__))), "pym")
-# Avoid sandbox violations after python upgrade.
+# Avoid sandbox violations after Python upgrade.
if os.environ.get("SANDBOX_ON") == "1":
sandbox_write = os.environ.get("SANDBOX_WRITE", "").split(":")
- if pym_path not in sandbox_write:
- sandbox_write.append(pym_path)
- os.environ["SANDBOX_WRITE"] = \
- ":".join(filter(None, sandbox_write))
- del sandbox_write
+ for pym_path in pym_paths:
+ if pym_path not in sandbox_write:
+ sandbox_write.append(pym_path)
+ os.environ["SANDBOX_WRITE"] = ":".join(filter(None, sandbox_write))
+ del pym_path, sandbox_write
+del pym_paths
-sys.path.insert(0, pym_path)
import portage
portage._internal_caller = True
from portage import os
@@ -66,6 +66,10 @@ def uses_eroot(function):
function.uses_eroot = True
return function
+# global to hold all function docstrings to be used for argparse help.
+# Avoids python compilation level 2 optimization troubles.
+docstrings = {}
+
#-----------------------------------------------------------------------------
#
# To add functionality to this tool, add a function below.
@@ -73,10 +77,12 @@ def uses_eroot(function):
# The format for functions is:
#
# def function(argv):
-# """<list of options for this function>
+# <code>
+#
+# docstrings['function'] = """<list of options for this function>
# <description of the function>
# """
-# <code>
+# function.__doc__ = docstrings['function']
#
# "argv" is an array of the command line parameters provided after the command.
#
@@ -89,9 +95,6 @@ def uses_eroot(function):
@uses_eroot
def has_version(argv):
- """<eroot> <category/package>
- Return code 0 if it's available, 1 otherwise.
- """
if (len(argv) < 2):
print("ERROR: insufficient parameters!")
return 3
@@ -132,12 +135,14 @@ def has_version(argv):
noiselevel=-1)
return 2
+docstrings['has_version'] = """<eroot> <category/package>
+ Return code 0 if it's available, 1 otherwise.
+ """
+has_version.__doc__ = docstrings['has_version']
+
@uses_eroot
def best_version(argv):
- """<eroot> <category/package>
- Returns category/package-version (without .ebuild).
- """
if (len(argv) < 2):
print("ERROR: insufficient parameters!")
return 3
@@ -171,12 +176,14 @@ def best_version(argv):
except KeyError:
return 1
+docstrings['best_version'] = """<eroot> <category/package>
+ Returns category/package-version (without .ebuild).
+ """
+best_version.__doc__ = docstrings['best_version']
+
@uses_eroot
def mass_best_version(argv):
- """<eroot> [<category/package>]+
- Returns category/package-version (without .ebuild).
- """
if (len(argv) < 2):
print("ERROR: insufficient parameters!")
return 2
@@ -187,6 +194,11 @@ def mass_best_version(argv):
except KeyError:
return 1
+docstrings['mass_best_version'] = """<eroot> [<category/package>]+
+ Returns category/package-version (without .ebuild).
+ """
+mass_best_version.__doc__ = docstrings['mass_best_version']
+
@uses_eroot
def metadata(argv):
@@ -215,21 +227,17 @@ def metadata(argv):
print("Package not found: '%s'" % pkgspec, file=sys.stderr)
return 1
-metadata.__doc__ = """
+docstrings['metadata'] = """
<eroot> <pkgtype> <category/package> [<key>]+
Returns metadata values for the specified package.
Available keys: %s
""" % ','.join(sorted(x for x in portage.auxdbkeys \
if not x.startswith('UNUSED_')))
+metadata.__doc__ = docstrings['metadata']
@uses_eroot
def contents(argv):
- """<eroot> <category/package>
- List the files that are installed for a given package, with
- one file listed on each line. All file names will begin with
- <eroot>.
- """
if len(argv) != 2:
print("ERROR: expected 2 parameters, got %d!" % len(argv))
return 2
@@ -245,16 +253,16 @@ def contents(argv):
writemsg_stdout(''.join('%s\n' % x for x in sorted(db.getcontents())),
noiselevel=-1)
+docstrings['contents'] = """<eroot> <category/package>
+ List the files that are installed for a given package, with
+ one file listed on each line. All file names will begin with
+ <eroot>.
+ """
+contents.__doc__ = docstrings['contents']
+
@uses_eroot
def owners(argv):
- """<eroot> [<filename>]+
- Given a list of files, print the packages that own the files and which
- files belong to each package. Files owned by a package are listed on
- the lines below it, indented by a single tab character (\\t). All file
- paths must either start with <eroot> or be a basename alone.
- Returns 1 if no owners could be found, and 0 otherwise.
- """
if len(argv) < 2:
sys.stderr.write("ERROR: insufficient parameters!\n")
sys.stderr.flush()
@@ -325,13 +333,18 @@ def owners(argv):
return 0
return 1
+docstrings['owners'] = """<eroot> [<filename>]+
+ Given a list of files, print the packages that own the files and which
+ files belong to each package. Files owned by a package are listed on
+ the lines below it, indented by a single tab character (\\t). All file
+ paths must either start with <eroot> or be a basename alone.
+ Returns 1 if no owners could be found, and 0 otherwise.
+ """
+owners.__doc__ = docstrings['owners']
+
@uses_eroot
def is_protected(argv):
- """<eroot> <filename>
- Given a single filename, return code 0 if it's protected, 1 otherwise.
- The filename must begin with <eroot>.
- """
if len(argv) != 2:
sys.stderr.write("ERROR: expected 2 parameters, got %d!\n" % len(argv))
sys.stderr.flush()
@@ -372,13 +385,15 @@ def is_protected(argv):
return 0
return 1
+docstrings['is_protected'] = """<eroot> <filename>
+ Given a single filename, return code 0 if it's protected, 1 otherwise.
+ The filename must begin with <eroot>.
+ """
+is_protected.__doc__ = docstrings['is_protected']
+
@uses_eroot
def filter_protected(argv):
- """<eroot>
- Read filenames from stdin and write them to stdout if they are protected.
- All filenames are delimited by \\n and must begin with <eroot>.
- """
if len(argv) != 1:
sys.stderr.write("ERROR: expected 1 parameter, got %d!\n" % len(argv))
sys.stderr.flush()
@@ -430,14 +445,15 @@ def filter_protected(argv):
return 0
+docstrings['filter_protected'] = """<eroot>
+ Read filenames from stdin and write them to stdout if they are protected.
+ All filenames are delimited by \\n and must begin with <eroot>.
+ """
+filter_protected.__doc__ = docstrings['filter_protected']
+
@uses_eroot
def best_visible(argv):
- """<eroot> [pkgtype] <atom>
- Returns category/package-version (without .ebuild).
- The pkgtype argument defaults to "ebuild" if unspecified,
- otherwise it must be one of ebuild, binary, or installed.
- """
if (len(argv) < 2):
writemsg("ERROR: insufficient parameters!\n", noiselevel=-1)
return 2
@@ -512,14 +528,16 @@ def best_visible(argv):
return 1
-
-@uses_eroot
-def mass_best_visible(argv):
- """<eroot> [<type>] [<category/package>]+
+docstrings['best_visible'] = """<eroot> [pkgtype] <atom>
Returns category/package-version (without .ebuild).
The pkgtype argument defaults to "ebuild" if unspecified,
otherwise it must be one of ebuild, binary, or installed.
"""
+best_visible.__doc__ = docstrings['best_visible']
+
+
+@uses_eroot
+def mass_best_visible(argv):
type_map = {
"ebuild":"porttree",
"binary":"bintree",
@@ -539,12 +557,16 @@ def mass_best_visible(argv):
except KeyError:
return 1
+docstrings['mass_best_visible'] = """<eroot> [<type>] [<category/package>]+
+ Returns category/package-version (without .ebuild).
+ The pkgtype argument defaults to "ebuild" if unspecified,
+ otherwise it must be one of ebuild, binary, or installed.
+ """
+mass_best_visible.__doc__ = docstrings['mass_best_visible']
+
@uses_eroot
def all_best_visible(argv):
- """<eroot>
- Returns all best_visible packages (without .ebuild).
- """
if len(argv) < 1:
sys.stderr.write("ERROR: insufficient parameters!\n")
sys.stderr.flush()
@@ -556,14 +578,14 @@ def all_best_visible(argv):
if mybest:
print(mybest)
+docstrings['all_best_visible'] = """<eroot>
+ Returns all best_visible packages (without .ebuild).
+ """
+all_best_visible.__doc__ = docstrings['all_best_visible']
+
@uses_eroot
def match(argv):
- """<eroot> <atom>
- Returns a \\n separated list of category/package-version.
- When given an empty string, all installed packages will
- be listed.
- """
if len(argv) != 2:
print("ERROR: expected 2 parameters, got %d!" % len(argv))
return 2
@@ -605,20 +627,16 @@ def match(argv):
for cpv in results:
print(cpv)
+docstrings['match'] = """<eroot> <atom>
+ Returns a \\n separated list of category/package-version.
+ When given an empty string, all installed packages will
+ be listed.
+ """
+match.__doc__ = docstrings['match']
+
@uses_eroot
def expand_virtual(argv):
- """<eroot> <atom>
- Returns a \\n separated list of atoms expanded from a
- given virtual atom (GLEP 37 virtuals only),
- excluding blocker atoms. Satisfied
- virtual atoms are not included in the output, since
- they are expanded to real atoms which are displayed.
- Unsatisfied virtual atoms are displayed without
- any expansion. The "match" command can be used to
- resolve the returned atoms to specific installed
- packages.
- """
if len(argv) != 2:
writemsg("ERROR: expected 2 parameters, got %d!\n" % len(argv),
noiselevel=-1)
@@ -641,101 +659,134 @@ def expand_virtual(argv):
return os.EX_OK
+docstrings['expand_virtual'] = """<eroot> <atom>
+ Returns a \\n separated list of atoms expanded from a
+ given virtual atom (GLEP 37 virtuals only),
+ excluding blocker atoms. Satisfied
+ virtual atoms are not included in the output, since
+ they are expanded to real atoms which are displayed.
+ Unsatisfied virtual atoms are displayed without
+ any expansion. The "match" command can be used to
+ resolve the returned atoms to specific installed
+ packages.
+ """
+expand_virtual.__doc__ = docstrings['expand_virtual']
+
def vdb_path(_argv):
- """
- Returns the path used for the var(installed) package database for the
- set environment/configuration options.
- """
out = sys.stdout
out.write(os.path.join(portage.settings["EROOT"], portage.VDB_PATH) + "\n")
out.flush()
return os.EX_OK
-def gentoo_mirrors(_argv):
+docstrings['vdb_path'] = """
+ Returns the path used for the var(installed) package database for the
+ set environment/configuration options.
"""
+vdb_path.__doc__ = docstrings['vdb_path']
+
+
+def gentoo_mirrors(_argv):
+ print(portage.settings["GENTOO_MIRRORS"])
+
+docstrings['gentoo_mirrors'] = """
Returns the mirrors set to use in the portage configuration.
"""
- print(portage.settings["GENTOO_MIRRORS"])
+gentoo_mirrors.__doc__ = docstrings['gentoo_mirrors']
@uses_eroot
def repositories_configuration(argv):
- """<eroot>
- Returns the configuration of repositories.
- """
if len(argv) < 1:
print("ERROR: insufficient parameters!", file=sys.stderr)
return 3
sys.stdout.write(portage.db[argv[0]]["vartree"].settings.repositories.config_string())
sys.stdout.flush()
+docstrings['repositories_configuration'] = """<eroot>
+ Returns the configuration of repositories.
+ """
+repositories_configuration.__doc__ = docstrings['repositories_configuration']
+
+
@uses_eroot
def repos_config(argv):
- """
+ return repositories_configuration(argv)
+
+docstrings['repos_config'] = """
<eroot>
This is an alias for the repositories_configuration command.
"""
- return repositories_configuration(argv)
+repos_config.__doc__ = docstrings['repos_config']
+
def portdir(_argv):
- """
+ print("WARNING: 'portageq portdir' is deprecated. Use 'portageq repositories_configuration' instead.", file=sys.stderr)
+ print(portage.settings["PORTDIR"])
+
+docstrings['portdir'] = """
Returns the PORTDIR path.
Deprecated in favor of repositories_configuration command.
"""
- print("WARNING: 'portageq portdir' is deprecated. Use 'portageq repositories_configuration' instead.", file=sys.stderr)
- print(portage.settings["PORTDIR"])
+portdir.__doc__ = docstrings['portdir']
def config_protect(_argv):
- """
+ print(portage.settings["CONFIG_PROTECT"])
+
+docstrings['config_protect'] = """
Returns the CONFIG_PROTECT paths.
"""
- print(portage.settings["CONFIG_PROTECT"])
+config_protect.__doc__ = docstrings['config_protect']
def config_protect_mask(_argv):
- """
- Returns the CONFIG_PROTECT_MASK paths.
- """
print(portage.settings["CONFIG_PROTECT_MASK"])
+docstrings['config_protect_mask'] = """
+ Returns the CONFIG_PROTECT_MASK paths.
+ """
+config_protect_mask.__doc__ = docstrings['config_protect_mask']
def portdir_overlay(_argv):
- """
+ print("WARNING: 'portageq portdir_overlay' is deprecated. Use 'portageq repositories_configuration' instead.", file=sys.stderr)
+ print(portage.settings["PORTDIR_OVERLAY"])
+
+docstrings['portdir_overlay'] = """
Returns the PORTDIR_OVERLAY path.
Deprecated in favor of repositories_configuration command.
"""
- print("WARNING: 'portageq portdir_overlay' is deprecated. Use 'portageq repositories_configuration' instead.", file=sys.stderr)
- print(portage.settings["PORTDIR_OVERLAY"])
+portdir_overlay.__doc__ = docstrings['portdir_overlay']
def pkgdir(_argv):
- """
+ print(portage.settings["PKGDIR"])
+
+docstrings['pkgdir'] = """
Returns the PKGDIR path.
"""
- print(portage.settings["PKGDIR"])
+pkgdir.__doc__ = docstrings['pkgdir']
def distdir(_argv):
- """
+ print(portage.settings["DISTDIR"])
+
+docstrings['distdir'] = """
Returns the DISTDIR path.
"""
- print(portage.settings["DISTDIR"])
+distdir.__doc__ = docstrings['distdir']
def colormap(_argv):
- """
+ print(portage.output.colormap())
+
+docstrings['colormap'] = """
Display the color.map as environment variables.
"""
- print(portage.output.colormap())
+colormap.__doc__ = docstrings['colormap']
def envvar(argv):
- """<variable>+
- Returns a specific environment variable as exists prior to ebuild.sh.
- Similar to: emerge --verbose --info | egrep '^<variable>='
- """
verbose = "-v" in argv
if verbose:
argv.pop(argv.index("-v"))
@@ -752,23 +803,28 @@ def envvar(argv):
else:
print(portage.settings[arg])
+docstrings['envvar'] = """<variable>+
+ Returns a specific environment variable as exists prior to ebuild.sh.
+ Similar to: emerge --verbose --info | egrep '^<variable>='
+ """
+envvar.__doc__ = docstrings['envvar']
+
@uses_eroot
def get_repos(argv):
- """<eroot>
- Returns all repos with names (repo_name file) argv[0] = $EROOT
- """
if len(argv) < 1:
print("ERROR: insufficient parameters!")
return 2
print(" ".join(reversed(portage.db[argv[0]]["vartree"].settings.repositories.prepos_order)))
+docstrings['get_repos'] = """<eroot>
+ Returns all repos with names (repo_name file) argv[0] = $EROOT
+ """
+get_repos.__doc__ = docstrings['get_repos']
+
@uses_eroot
def master_repositories(argv):
- """<eroot> <repo_id>+
- Returns space-separated list of master repositories for specified repository.
- """
if len(argv) < 2:
print("ERROR: insufficient parameters!", file=sys.stderr)
return 3
@@ -784,18 +840,25 @@ def master_repositories(argv):
else:
print(" ".join(x.name for x in repo.masters))
+docstrings['master_repositories'] = """<eroot> <repo_id>+
+ Returns space-separated list of master repositories for specified repository.
+ """
+master_repositories.__doc__ = docstrings['master_repositories']
+
+
@uses_eroot
def master_repos(argv):
- """<eroot> <repo_id>+
+ return master_repositories(argv)
+
+docstrings['master_repos'] = """<eroot> <repo_id>+
This is an alias for the master_repositories command.
"""
- return master_repositories(argv)
+master_repos.__doc__ = docstrings['master_repos']
+
@uses_eroot
def get_repo_path(argv):
- """<eroot> <repo_id>+
- Returns the path to the repo named argv[1], argv[0] = $EROOT
- """
+
if len(argv) < 2:
print("ERROR: insufficient parameters!", file=sys.stderr)
return 3
@@ -809,12 +872,14 @@ def get_repo_path(argv):
return 1
print(path)
+docstrings['get_repo_path'] = """<eroot> <repo_id>+
+ Returns the path to the repo named argv[1], argv[0] = $EROOT
+ """
+get_repo_path.__doc__ = docstrings['get_repo_path']
+
@uses_eroot
def available_eclasses(argv):
- """<eroot> <repo_id>+
- Returns space-separated list of available eclasses for specified repository.
- """
if len(argv) < 2:
print("ERROR: insufficient parameters!", file=sys.stderr)
return 3
@@ -830,12 +895,14 @@ def available_eclasses(argv):
else:
print(" ".join(sorted(repo.eclass_db.eclasses)))
+docstrings['available_eclasses'] = """<eroot> <repo_id>+
+ Returns space-separated list of available eclasses for specified repository.
+ """
+available_eclasses.__doc__ = docstrings['available_eclasses']
+
@uses_eroot
def eclass_path(argv):
- """<eroot> <repo_id> <eclass>+
- Returns the path to specified eclass for specified repository.
- """
if len(argv) < 3:
print("ERROR: insufficient parameters!", file=sys.stderr)
return 3
@@ -859,12 +926,14 @@ def eclass_path(argv):
print(eclass.location)
return retval
+docstrings['eclass_path'] = """<eroot> <repo_id> <eclass>+
+ Returns the path to specified eclass for specified repository.
+ """
+eclass_path.__doc__ = docstrings['eclass_path']
+
@uses_eroot
def license_path(argv):
- """<eroot> <repo_id> <license>+
- Returns the path to specified license for specified repository.
- """
if len(argv) < 3:
print("ERROR: insufficient parameters!", file=sys.stderr)
return 3
@@ -890,15 +959,14 @@ def license_path(argv):
print(eclass_path)
return retval
+docstrings['license_path'] = """<eroot> <repo_id> <license>+
+ Returns the path to specified license for specified repository.
+ """
+license_path.__doc__ = docstrings['license_path']
+
@uses_eroot
def list_preserved_libs(argv):
- """<eroot>
- Print a list of libraries preserved during a package update in the form
- package: path. Returns 1 if no preserved libraries could be found,
- 0 otherwise.
- """
-
if len(argv) != 1:
print("ERROR: wrong number of arguments")
return 2
@@ -914,6 +982,13 @@ def list_preserved_libs(argv):
writemsg_stdout(''.join(msg), noiselevel=-1)
return rValue
+docstrings['list_preserved_libs'] = """<eroot>
+ Print a list of libraries preserved during a package update in the form
+ package: path. Returns 1 if no preserved libraries could be found,
+ 0 otherwise.
+ """
+list_preserved_libs.__doc__ = docstrings['list_preserved_libs']
+
class MaintainerEmailMatcher(object):
def __init__(self, maintainer_emails):
@@ -938,10 +1013,6 @@ class HerdMatcher(object):
def pquery(parser, opts, args):
- """[options] [atom]+
- Emulates a subset of Pkgcore's pquery tool.
- """
-
portdb = portage.db[portage.root]['porttree'].dbapi
root_config = RootConfig(portdb.settings,
portage.db[portage.root], None)
@@ -1120,6 +1191,11 @@ def pquery(parser, opts, args):
return os.EX_OK
+docstrings['pquery'] = """[options] [atom]+
+ Emulates a subset of Pkgcore's pquery tool.
+ """
+pquery.__doc__ = docstrings['pquery']
+
#-----------------------------------------------------------------------------
#
@@ -1217,10 +1293,7 @@ def usage(argv):
#
help_mode = '--help' in argv
for name in commands:
- # Drop non-functions
- obj = globals()[name]
-
- doc = obj.__doc__
+ doc = docstrings.get(name)
if (doc == None):
print(" " + name)
print(" MISSING DOCUMENTATION!")
diff --git a/bin/quickpkg b/bin/quickpkg
index d787ca1f3..7019fb351 100755
--- a/bin/quickpkg
+++ b/bin/quickpkg
@@ -2,7 +2,7 @@
# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import print_function
+from __future__ import division, print_function
import errno
import math
@@ -11,8 +11,8 @@ import sys
import tarfile
from os import path as osp
-pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
-sys.path.insert(0, pym_path)
+if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
portage._internal_caller = True
from portage import os
@@ -264,7 +264,7 @@ def quickpkg_main(options, args, eout):
size_str = "0"
else:
power_of_2 = math.log(size, 2)
- power_of_2 = 10*int(power_of_2/10)
+ power_of_2 = 10*(power_of_2//10)
unit = units.get(power_of_2)
if unit:
size = float(size)/(2**power_of_2)
diff --git a/bin/regenworld b/bin/regenworld
index d3fb9ed24..1c7678cd3 100755
--- a/bin/regenworld
+++ b/bin/regenworld
@@ -6,8 +6,8 @@ from __future__ import print_function
import sys
from os import path as osp
-pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
-sys.path.insert(0, pym_path)
+if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
portage._internal_caller = True
from portage import os
diff --git a/bin/repoman b/bin/repoman
index efab92183..918357747 100755
--- a/bin/repoman
+++ b/bin/repoman
@@ -32,8 +32,8 @@ except ImportError:
from urlparse import urlparse
from os import path as osp
-pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
-sys.path.insert(0, pym_path)
+if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
portage._internal_caller = True
portage._disable_legacy_globals()
@@ -62,7 +62,7 @@ from repoman import utilities
from repoman.herdbase import make_herd_base
from _emerge.Package import Package
from _emerge.RootConfig import RootConfig
-from _emerge.userquery import userquery
+from _emerge.UserQuery import UserQuery
import portage.checksum
import portage.const
import portage.repository.config
@@ -299,6 +299,7 @@ qahelp = {
"dependency.badindev": "User-visible ebuilds with unsatisfied dependencies (matched against *visible* ebuilds) in developing arch",
"dependency.badmaskedindev": "Masked ebuilds with unsatisfied dependencies (matched against *all* ebuilds) in developing arch",
"dependency.badtilde": "Uses the ~ dep operator with a non-zero revision part, which is useless (the revision is ignored)",
+ "dependency.perlcore": "This ebuild directly depends on a package in perl-core; it should use the corresponding virtual instead.",
"dependency.syntax": "Syntax error in dependency string (usually an extra/missing space/parenthesis)",
"dependency.unknown": "Ebuild has a dependency that refers to an unknown package (which may be valid if it is a blocker for a renamed/removed package, or is an alternative choice provided by an overlay)",
"file.executable": "Ebuilds, digests, metadata.xml, Manifest, and ChangeLog do not need the executable bit",
@@ -318,7 +319,6 @@ qahelp = {
"LICENSE.missing": "Ebuilds that have a missing or empty LICENSE variable",
"LICENSE.virtual": "Virtuals that have a non-empty LICENSE variable",
"DESCRIPTION.missing": "Ebuilds that have a missing or empty DESCRIPTION variable",
- "DESCRIPTION.punctuation": "DESCRIPTION ends with a period character",
"DESCRIPTION.toolong": "DESCRIPTION is over %d characters" % max_desc_len,
"EAPI.definition": "EAPI definition does not conform to PMS section 7.3.1 (first non-comment, non-blank line)",
"EAPI.deprecated": "Ebuilds that use features that are deprecated in the current EAPI",
@@ -387,7 +387,7 @@ qawarnings = set((
"dependency.badindev",
"dependency.badmaskedindev",
"dependency.badtilde",
-"DESCRIPTION.punctuation",
+"dependency.perlcore",
"DESCRIPTION.toolong",
"EAPI.deprecated",
"HOMEPAGE.virtual",
@@ -1895,12 +1895,6 @@ for x in effective_scanlist:
stats[myqakey] += 1
fails[myqakey].append(relative_path)
- if myaux['DESCRIPTION'][-1:] in ['.']:
- stats['DESCRIPTION.punctuation'] += 1
- fails['DESCRIPTION.punctuation'].append(
- "%s: DESCRIPTION ends with a '%s' character"
- % (relative_path, myaux['DESCRIPTION'][-1:]))
-
# 14 is the length of DESCRIPTION=""
if len(myaux['DESCRIPTION']) > max_desc_len:
stats['DESCRIPTION.toolong'] += 1
@@ -2042,16 +2036,16 @@ for x in effective_scanlist:
if atom == "||":
continue
+ is_blocker = atom.blocker
+
# Skip dependency.unknown for blockers, so that we
# don't encourage people to remove necessary blockers,
# as discussed in bug #382407.
- if atom.blocker is None and \
+ if not is_blocker and \
not portdb.xmatch("match-all", atom) and \
not atom.cp.startswith("virtual/"):
unknown_pkgs.add((mytype, atom.unevaluated_atom))
- is_blocker = atom.blocker
-
if catdir != "virtual":
if not is_blocker and \
atom.cp in suspect_virtual:
@@ -2060,6 +2054,13 @@ for x in effective_scanlist:
relative_path +
": %s: consider using '%s' instead of '%s'" %
(mytype, suspect_virtual[atom.cp], atom))
+ if not is_blocker and \
+ atom.cp.startswith("perl-core/"):
+ stats['dependency.perlcore'] += 1
+ fails['dependency.perlcore'].append(
+ relative_path +
+ ": %s: please use '%s' instead of '%s'" %
+ (mytype, atom.replace("perl-core/","virtual/perl-"), atom))
if buildtime and \
not is_blocker and \
@@ -2882,7 +2883,8 @@ else:
logging.info("myupdates: %s", myupdates)
logging.info("myheaders: %s", myheaders)
- if options.ask and userquery('Commit changes?', True) != 'Yes':
+ uq = UserQuery(options)
+ if options.ask and uq.query('Commit changes?', True) != 'Yes':
print("* aborting commit.")
sys.exit(128 + signal.SIGINT)
diff --git a/bin/save-ebuild-env.sh b/bin/save-ebuild-env.sh
index 194e46ea9..b790306d1 100644
--- a/bin/save-ebuild-env.sh
+++ b/bin/save-ebuild-env.sh
@@ -42,7 +42,7 @@ __save_ebuild_env() {
for x in pkg_setup pkg_nofetch src_unpack src_prepare src_configure \
src_compile src_test src_install pkg_preinst pkg_postinst \
- pkg_prerm pkg_postrm ; do
+ pkg_prerm pkg_postrm pkg_config pkg_info pkg_pretend ; do
unset -f default_$x __eapi{0,1,2,3,4}_$x
done
unset x
diff --git a/bin/xattr-helper.py b/bin/xattr-helper.py
index fdbed54ac..f84e94340 100755
--- a/bin/xattr-helper.py
+++ b/bin/xattr-helper.py
@@ -2,7 +2,7 @@
# Copyright 2012-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-"""Dump and restore extended attributes.
+doc = """Dump and restore extended attributes.
We use formats like that used by getfattr --dump. This is meant for shell
helpers to save/restore. If you're looking for a python/portage API, see
@@ -10,6 +10,8 @@ portage.util.movefile._copyxattr instead.
https://en.wikipedia.org/wiki/Extended_file_attributes
"""
+__doc__ = doc
+
import array
import os
@@ -147,7 +149,7 @@ def restore_xattrs(file_in):
def main(argv):
- parser = ArgumentParser(description=__doc__)
+ parser = ArgumentParser(description=doc)
parser.add_argument('paths', nargs='*', default=[])
actions = parser.add_argument_group('Actions')