aboutsummaryrefslogtreecommitdiff
path: root/data
diff options
context:
space:
mode:
authorArthur Zamarin <arthurzam@gentoo.org>2022-11-01 09:46:27 +0200
committerArthur Zamarin <arthurzam@gentoo.org>2022-11-01 18:49:10 +0200
commit52a3d668722bedda48baaa054ed12e82335dcb42 (patch)
tree97ae1bf2691b433507deb63283507e3dd3b08559 /data
parenttests: small cleanup (diff)
downloadpkgcore-52a3d668722bedda48baaa054ed12e82335dcb42.tar.gz
pkgcore-52a3d668722bedda48baaa054ed12e82335dcb42.tar.bz2
pkgcore-52a3d668722bedda48baaa054ed12e82335dcb42.zip
setup.py: reorder data files
Store all data files (files that should be installed into `/usr` outside python lib location) in one main "data" directory, with direct subdirs matching the once installed on system. This is preparation for moving to flit backend. Signed-off-by: Arthur Zamarin <arthurzam@gentoo.org>
Diffstat (limited to 'data')
-rw-r--r--data/lib/pkgcore/ebd/eapi/0/global.bash38
-rw-r--r--data/lib/pkgcore/ebd/eapi/0/phase.bash93
-rw-r--r--data/lib/pkgcore/ebd/eapi/0/src_compile.bash66
-rw-r--r--data/lib/pkgcore/ebd/eapi/0/src_install.bash100
-rw-r--r--data/lib/pkgcore/ebd/eapi/1/global.bash10
-rw-r--r--data/lib/pkgcore/ebd/eapi/2/global.bash15
-rw-r--r--data/lib/pkgcore/ebd/eapi/2/phase.bash11
-rw-r--r--data/lib/pkgcore/ebd/eapi/2/pkg_nofetch.bash1
-rw-r--r--data/lib/pkgcore/ebd/eapi/2/src_compile.bash4
-rw-r--r--data/lib/pkgcore/ebd/eapi/2/src_configure.bash73
-rw-r--r--data/lib/pkgcore/ebd/eapi/2/src_prepare.bash1
-rw-r--r--data/lib/pkgcore/ebd/eapi/2/src_test.bash1
-rw-r--r--data/lib/pkgcore/ebd/eapi/2/src_unpack.bash1
-rw-r--r--data/lib/pkgcore/ebd/eapi/4/global.bash19
-rw-r--r--data/lib/pkgcore/ebd/eapi/4/phase.bash3
-rw-r--r--data/lib/pkgcore/ebd/eapi/4/src_configure.bash5
-rw-r--r--data/lib/pkgcore/ebd/eapi/4/src_install.bash3
-rw-r--r--data/lib/pkgcore/ebd/eapi/5/global.bash16
-rw-r--r--data/lib/pkgcore/ebd/eapi/5/phase.bash6
-rw-r--r--data/lib/pkgcore/ebd/eapi/5/src_configure.bash5
-rw-r--r--data/lib/pkgcore/ebd/eapi/6/global.bash22
-rw-r--r--data/lib/pkgcore/ebd/eapi/6/phase.bash5
-rw-r--r--data/lib/pkgcore/ebd/eapi/6/src_configure.bash8
-rw-r--r--data/lib/pkgcore/ebd/eapi/6/src_install.bash34
-rw-r--r--data/lib/pkgcore/ebd/eapi/6/src_prepare.bash8
-rw-r--r--data/lib/pkgcore/ebd/eapi/7/global.bash187
-rw-r--r--data/lib/pkgcore/ebd/eapi/7/src_configure.bash7
-rw-r--r--data/lib/pkgcore/ebd/eapi/7/src_install.bash3
-rw-r--r--data/lib/pkgcore/ebd/eapi/8/global.bash14
-rw-r--r--data/lib/pkgcore/ebd/eapi/8/phase.bash9
-rw-r--r--data/lib/pkgcore/ebd/eapi/8/src_configure.bash8
-rw-r--r--data/lib/pkgcore/ebd/eapi/common.bash153
-rw-r--r--data/lib/pkgcore/ebd/eapi/depend.bash116
-rw-r--r--data/lib/pkgcore/ebd/ebuild-daemon-lib.bash148
-rw-r--r--data/lib/pkgcore/ebd/ebuild-daemon.bash405
-rw-r--r--data/lib/pkgcore/ebd/ebuild-default-functions.bash247
-rw-r--r--data/lib/pkgcore/ebd/ebuild-env-utils.bash136
-rw-r--r--data/lib/pkgcore/ebd/ebuild.bash531
-rw-r--r--data/lib/pkgcore/ebd/exit-handling.bash122
-rwxr-xr-xdata/lib/pkgcore/ebd/generate_eapi_cmd_list79
-rwxr-xr-xdata/lib/pkgcore/ebd/generate_eapi_func_list36
-rwxr-xr-xdata/lib/pkgcore/ebd/generate_eapi_lib87
-rwxr-xr-xdata/lib/pkgcore/ebd/generate_global_func_list72
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/dosed22
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/emake4
l---------data/lib/pkgcore/ebd/helpers/0/pkg_postinst/fowners1
l---------data/lib/pkgcore/ebd/helpers/0/pkg_postinst/fperms1
l---------data/lib/pkgcore/ebd/helpers/0/pkg_postinst/keepdir1
l---------data/lib/pkgcore/ebd/helpers/0/pkg_preinst/dodir1
l---------data/lib/pkgcore/ebd/helpers/0/pkg_preinst/fowners1
l---------data/lib/pkgcore/ebd/helpers/0/pkg_preinst/fperms1
l---------data/lib/pkgcore/ebd/helpers/0/pkg_preinst/keepdir1
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/dobin3
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/doconfd4
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/dodir3
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/dodoc3
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/doenvd4
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/doexe6
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/dohard1
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/dohtml3
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/doinfo3
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/doinitd4
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/doins11
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/dolib12
l---------data/lib/pkgcore/ebd/helpers/0/src_install/dolib.a1
l---------data/lib/pkgcore/ebd/helpers/0/src_install/dolib.so1
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/doman3
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/domo7
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/dosbin3
l---------data/lib/pkgcore/ebd/helpers/0/src_install/dosym1
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/fowners7
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/fperms7
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/0/src_install/keepdir3
l---------data/lib/pkgcore/ebd/helpers/0/src_install/newbin1
l---------data/lib/pkgcore/ebd/helpers/0/src_install/newconfd1
l---------data/lib/pkgcore/ebd/helpers/0/src_install/newdoc1
l---------data/lib/pkgcore/ebd/helpers/0/src_install/newenvd1
l---------data/lib/pkgcore/ebd/helpers/0/src_install/newexe1
l---------data/lib/pkgcore/ebd/helpers/0/src_install/newinitd1
l---------data/lib/pkgcore/ebd/helpers/0/src_install/newins1
l---------data/lib/pkgcore/ebd/helpers/0/src_install/newlib.a1
l---------data/lib/pkgcore/ebd/helpers/0/src_install/newlib.so1
l---------data/lib/pkgcore/ebd/helpers/0/src_install/newman1
l---------data/lib/pkgcore/ebd/helpers/0/src_install/newsbin1
l---------data/lib/pkgcore/ebd/helpers/4/dosed1
l---------data/lib/pkgcore/ebd/helpers/4/src_install/dohard1
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/5/src_install/doheader4
l---------data/lib/pkgcore/ebd/helpers/5/src_install/newheader1
l---------data/lib/pkgcore/ebd/helpers/6/src_install/dohtml1
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/7/nonfatal5
l---------data/lib/pkgcore/ebd/helpers/7/src_install/dohtml1
l---------data/lib/pkgcore/ebd/helpers/7/src_install/dolib1
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/8/src_install/doconfd5
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/8/src_install/doenvd5
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/8/src_install/doheader5
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/8/src_install/doinitd5
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/common/pkgcore-ebuild-helper75
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/common/pkgcore-ipc-helper71
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/common/prepalldocs67
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/common/prepallstrip7
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/common/prepinfo64
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/common/prepman63
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/common/prepstrip66
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/internals/_generic_new22
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/internals/banned3
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/internals/deprecated15
-rw-r--r--data/lib/pkgcore/ebd/helpers/internals/helper-lib.bash80
-rwxr-xr-xdata/lib/pkgcore/ebd/helpers/internals/prepall88
-rw-r--r--data/lib/pkgcore/ebd/isolated-functions.bash366
-rw-r--r--data/lib/pkgcore/shell/bash/pkgcore.bash91
-rwxr-xr-xdata/lib/pkgcore/shell/bin/pkgcore-sh-helper16
-rwxr-xr-xdata/lib/pkgcore/shell/bin/psite47
-rw-r--r--data/lib/pkgcore/shell/pkgcore.sh90
-rw-r--r--data/lib/pkgcore/shell/zsh/pkgcore.zsh348
-rw-r--r--data/share/bash-completion/completions/pquery153
-rw-r--r--data/share/pkgcore/config/make.globals (renamed from data/config/make.globals)0
-rw-r--r--data/share/pkgcore/config/repos.conf (renamed from data/config/repos.conf)0
-rw-r--r--data/share/pkgcore/stubconfig/repos.conf (renamed from data/stubconfig/repos.conf)0
-rw-r--r--data/share/pkgcore/stubrepo/metadata/layout.conf (renamed from data/stubrepo/metadata/layout.conf)0
-rw-r--r--data/share/pkgcore/stubrepo/profiles/arch.list (renamed from data/stubrepo/profiles/arch.list)0
-rw-r--r--data/share/pkgcore/stubrepo/profiles/default/make.defaults (renamed from data/stubrepo/profiles/default/make.defaults)0
-rw-r--r--data/share/pkgcore/stubrepo/profiles/profiles.desc (renamed from data/stubrepo/profiles/profiles.desc)0
-rw-r--r--data/share/pkgcore/stubrepo/profiles/repo_name (renamed from data/stubrepo/profiles/repo_name)0
-rw-r--r--data/share/pkgcore/xml-schema/metadata.xsd (renamed from data/xml-schema/metadata.xsd)0
-rw-r--r--data/share/zsh/site-functions/_pkgcore725
125 files changed, 5534 insertions, 0 deletions
diff --git a/data/lib/pkgcore/ebd/eapi/0/global.bash b/data/lib/pkgcore/ebd/eapi/0/global.bash
new file mode 100644
index 000000000..e0365984f
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/0/global.bash
@@ -0,0 +1,38 @@
+__phase_pkg_nofetch() {
+ [[ -z ${SRC_URI} ]] && return
+
+ echo "!!! The following are listed in SRC_URI for ${PN}:"
+ local fp
+ __shopt_push -f
+ for fp in ${SRC_URI}; do
+ echo "!!! ${fp}"
+ done
+ __shopt_pop
+}
+
+__phase_src_unpack() { [[ -n ${A} ]] && unpack ${A}; }
+
+__phase_src_compile() {
+ if [[ -x ./configure ]]; then
+ econf
+ fi
+ if [[ -f Makefile || -f GNUmakefile || -f makefile ]]; then
+ emake || die "emake failed"
+ fi
+}
+
+__phase_src_test() {
+ addpredict /
+ local extra_args=( ${EXTRA_EMAKE} -j1 )
+ if make check -n &> /dev/null; then
+ echo ">>> Test phase [check]: ${CATEGORY}/${PF}"
+ emake "${extra_args[@]}" check || die "make check failed, see above for details"
+ elif make test -n &> /dev/null; then
+ emake "${extra_args[@]}" test || die "make test failed, see above for details"
+ else
+ echo ">>> Test phase [none]: ${CATEGORY}/${PF}"
+ fi
+ SANDBOX_PREDICT=${SANDBOX_PREDICT%:/}
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/eapi/0/phase.bash b/data/lib/pkgcore/ebd/eapi/0/phase.bash
new file mode 100644
index 000000000..b5ae8de13
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/0/phase.bash
@@ -0,0 +1,93 @@
+## Package manager query commands
+
+has_version() { return $(__ebd_ipc_cmd ${FUNCNAME} "" "$@"); }
+best_version() { __ebd_ipc_cmd ${FUNCNAME} "" "$@"; }
+
+## USE flag commands
+
+use() {
+ if [[ ! ${1#!} =~ ${PKGCORE_IUSE_EFFECTIVE} ]]; then
+ die "USE flag '${1#!}' not in IUSE for ${CATEGORY}/${PF}"
+ fi
+
+ # Ensure USE is split on normal IFS.
+ local IFS=$' \t\n'
+
+ if [[ ${1:0:1} == "!" ]]; then
+ ! __safe_has "${1#!}" ${USE}
+ else
+ __safe_has "$1" ${USE}
+ fi
+}
+
+usev() {
+ if use "$1"; then
+ echo "${1#!}"
+ return 0
+ fi
+ return 1
+}
+
+useq() {
+ use "$@"
+}
+
+use_with() {
+ if [[ -z $1 ]]; then
+ echo "!!! use_with() called without a parameter." >&2
+ echo "!!! use_with <USEFLAG> [<flagname> [value]]" >&2
+ return
+ fi
+
+ local uw_suffix=""
+ if __safe_has "${EAPI}" 0 1 2 3; then
+ uw_suffix=${3:+=$3}
+ else
+ uw_suffix=${3+=$3}
+ fi
+
+ local uword=$2
+ if [[ -z ${uword} ]]; then
+ uword=$1
+ fi
+
+ if use "$1"; then
+ echo "--with-${uword}${uw_suffix}"
+ return 0
+ fi
+ echo "--without-${uword}"
+ return 1
+}
+
+use_enable() {
+ if [[ -z $1 ]]; then
+ echo "!!! use_enable() called without a parameter." >&2
+ echo "!!! use_enable <USEFLAG> [<flagname> [value]]" >&2
+ return
+ fi
+
+ local ue_suffix=""
+ if __safe_has "${EAPI}" 0 1 2 3; then
+ ue_suffix=${3:+=$3}
+ else
+ ue_suffix=${3+=$3}
+ fi
+
+ local uword=$2
+ if [[ -z ${uword} ]]; then
+ uword=$1
+ fi
+
+ if use "$1"; then
+ echo "--enable-${uword}${ue_suffix}"
+ return 0
+ fi
+ echo "--disable-${uword}"
+ return 1
+}
+
+## Misc commands
+
+unpack() { __ebd_ipc_cmd ${FUNCNAME} "" "$@"; }
+
+:
diff --git a/data/lib/pkgcore/ebd/eapi/0/src_compile.bash b/data/lib/pkgcore/ebd/eapi/0/src_compile.bash
new file mode 100644
index 000000000..feb82ef57
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/0/src_compile.bash
@@ -0,0 +1,66 @@
+econf() {
+ local ret
+ ECONF_SOURCE=${ECONF_SOURCE:-.}
+ if [[ ! -x ${ECONF_SOURCE}/configure ]]; then
+ [[ -f ${ECONF_SOURCE}/configure ]] && die "configure script isn't executable"
+ die "no configure script found"
+ fi
+
+ if [[ -d /usr/share/gnuconfig ]]; then
+ local x
+ find "${WORKDIR}" -type f \( -name config.guess -o -name config.sub \) | \
+ while read x; do
+ echo "econf: replacing ${x} with /usr/share/gnuconfig/${x##*/}"
+ cp -f "/usr/share/gnuconfig/${x##*/}" "${x}"
+ done
+ fi
+
+ # if the profile defines a location to install libs to aside from default, pass it on.
+ # if the ebuild passes in --libdir, they're responsible for the conf_libdir fun.
+ local CONF_LIBDIR=$(__get_libdir)
+ if [[ -n ${CONF_LIBDIR} && $* != *"--libdir="* ]]; then
+ if [[ $* == *"--exec-prefix="* ]]; then
+ local args=$(echo $*)
+ local -a prefix=( $(echo ${args/*--exec-prefix[= ]}) )
+ CONF_PREFIX=${prefix/--*}
+ [[ ${CONF_PREFIX} != /* ]] && CONF_PREFIX=/${CONF_PREFIX}
+ elif [[ $* == *"--prefix="* ]]; then
+ local args=$(echo $*)
+ local -a pref=( $(echo ${args/*--prefix[= ]}) )
+ CONF_PREFIX=${prefix/--*}
+ [[ ${CONF_PREFIX} != /* ]] && CONF_PREFIX=/${CONF_PREFIX}
+ else
+ CONF_PREFIX=/usr
+ fi
+ export CONF_PREFIX
+ [[ ${CONF_LIBDIR} != /* ]] && CONF_LIBDIR=/${CONF_LIBDIR}
+ set -- --libdir="$(__strip_duplicate_slashes "${CONF_PREFIX}${CONF_LIBDIR}")" "$@"
+ fi
+
+ # Reset IFS since we're interpreting user supplied EXTRA_ECONF.
+ local IFS=$' \t\n'
+ set -- "${ECONF_SOURCE}/configure" \
+ --prefix="${EPREFIX}"/usr \
+ ${CBUILD:+--build="${CBUILD}"} \
+ --host="${CHOST}" \
+ ${CTARGET:+--target="${CTARGET}"} \
+ --mandir="${EPREFIX}"/usr/share/man \
+ --infodir="${EPREFIX}"/usr/share/info \
+ --datadir="${EPREFIX}"/usr/share \
+ --sysconfdir="${EPREFIX}"/etc \
+ --localstatedir="${EPREFIX}"/var/lib \
+ "$@" \
+ ${EXTRA_ECONF}
+
+ echo "$@"
+
+ if ! "$@"; then
+ if [[ -s config.log ]]; then
+ echo
+ echo "!!! Please attach the config.log to your bug report:"
+ echo "!!! ${PWD}/config.log"
+ fi
+ die "econf failed"
+ fi
+ return $?
+}
diff --git a/data/lib/pkgcore/ebd/eapi/0/src_install.bash b/data/lib/pkgcore/ebd/eapi/0/src_install.bash
new file mode 100644
index 000000000..c8c036405
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/0/src_install.bash
@@ -0,0 +1,100 @@
+# Install destination commands
+
+into() {
+ ${PKGCORE_PREFIX_SUPPORT} || local ED=${D}
+ if [[ $1 == "/" ]]; then
+ export PKGCORE_DESTTREE=""
+ else
+ export PKGCORE_DESTTREE=$1
+ fi
+
+ # only EAPI <= 6 supports DESTTREE
+ ${PKGCORE_HAS_DESTTREE} && export DESTTREE=${PKGCORE_DESTTREE}
+}
+
+insinto() {
+ ${PKGCORE_PREFIX_SUPPORT} || local ED=${D}
+ if [[ $1 == "/" ]]; then
+ export PKGCORE_INSDESTTREE=""
+ else
+ export PKGCORE_INSDESTTREE=$1
+ fi
+
+ # only EAPI <= 6 supports INSDESTTREE
+ ${PKGCORE_HAS_DESTTREE} && export INSDESTTREE=${PKGCORE_INSDESTTREE}
+}
+
+exeinto() {
+ ${PKGCORE_PREFIX_SUPPORT} || local ED=${D}
+ if [[ $1 == "/" ]]; then
+ export PKGCORE_EXEDESTTREE=""
+ else
+ export PKGCORE_EXEDESTTREE=$1
+ fi
+}
+
+docinto() {
+ ${PKGCORE_PREFIX_SUPPORT} || local ED=${D}
+ if [[ $1 == "/" ]]; then
+ export PKGCORE_DOCDESTTREE=""
+ else
+ export PKGCORE_DOCDESTTREE=$1
+ fi
+}
+
+# Install options commands
+
+insopts() {
+ { has -s "$@" || has --strip "$@"; } && \
+ ewarn "insopts shouldn't be given -s; stripping should be left to the manager."
+ export INSOPTIONS=$@
+}
+
+diropts() {
+ export DIROPTIONS=$@
+}
+
+exeopts() {
+ { has -s "$@" || has --strip "$@"; } && \
+ ewarn "exeopts shouldn't be given -s; stripping should be left to the manager."
+ export EXEOPTIONS=$@
+}
+
+libopts() {
+ { has -s "$@" || has --strip "$@"; } && \
+ ewarn "libopts shouldn't be given -s; stripping should be left to the manager."
+ export LIBOPTIONS=$@
+}
+
+# Install command
+
+einstall() {
+ ${PKGCORE_PREFIX_SUPPORT} || local ED=${D}
+ # CONF_PREFIX is only set if they didn't pass in libdir above
+ local LOCAL_EXTRA_EINSTALL=( ${EXTRA_EINSTALL} )
+ local CONF_LIBDIR=$(__get_libdir)
+ if [[ -n ${CONF_LIBDIR} && ${CONF_PREFIX:-unset} != "unset" ]]; then
+ local EI_DESTLIBDIR=${ED%%/}/${CONF_PREFIX%%/}/${CONF_LIBDIR%%/}/
+ LOCAL_EXTRA_EINSTALL+=( libdir=${EI_DESTLIBDIR} )
+ unset -v EI_DESTLIBDIR
+ fi
+
+ if ! [[ -f Makefile || -f GNUmakefile || -f makefile ]]; then
+ die "no Makefile found"
+ fi
+
+ # Reset IFS for LOCAL_EXTRA_EINSTALL, should users be up to something.
+ local IFS=$' \t\n'
+ set -- \
+ ${MAKE:-make} \
+ prefix="${ED}/usr" \
+ datadir="${ED}/usr/share" \
+ infodir="${ED}/usr/share/info" \
+ localstatedir="${ED}/var/lib" \
+ mandir="${ED}/usr/share/man" \
+ sysconfdir="${ED}/etc" \
+ ${LOCAL_EXTRA_EINSTALL[@]} \
+ "$@" install
+ [[ ${PKGCORE_DEBUG} != 0 ]] && "$@" -n
+ "$@" || die "einstall failed"
+}
diff --git a/data/lib/pkgcore/ebd/eapi/1/global.bash b/data/lib/pkgcore/ebd/eapi/1/global.bash
new file mode 100644
index 000000000..34f6b1a40
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/1/global.bash
@@ -0,0 +1,10 @@
+__phase_src_compile() {
+ if [[ -x ${ECONF_SOURCE:-.}/configure ]]; then
+ econf
+ fi
+ if [[ -f Makefile || -f GNUmakefile || -f makefile ]]; then
+ emake || die "emake failed"
+ fi
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/eapi/2/global.bash b/data/lib/pkgcore/ebd/eapi/2/global.bash
new file mode 100644
index 000000000..74dd78858
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/2/global.bash
@@ -0,0 +1,15 @@
+__phase_src_prepare() { :; }
+
+__phase_src_configure() {
+ if [[ -x ${ECONF_SOURCE:-.}/configure ]]; then
+ econf
+ fi
+}
+
+__phase_src_compile() {
+ if [[ -f Makefile || -f GNUmakefile || -f makefile ]]; then
+ emake || die "emake failed"
+ fi
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/eapi/2/phase.bash b/data/lib/pkgcore/ebd/eapi/2/phase.bash
new file mode 100644
index 000000000..b5c2c80b4
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/2/phase.bash
@@ -0,0 +1,11 @@
+default() {
+ if __is_function default_pkg_${EBUILD_PHASE}; then
+ default_pkg_${EBUILD_PHASE}
+ elif __is_function default_src_${EBUILD_PHASE}; then
+ default_src_${EBUILD_PHASE}
+ else
+ die "default is not available in ebuild phase '${EBUILD_PHASE}'"
+ fi
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/eapi/2/pkg_nofetch.bash b/data/lib/pkgcore/ebd/eapi/2/pkg_nofetch.bash
new file mode 100644
index 000000000..542968cb1
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/2/pkg_nofetch.bash
@@ -0,0 +1 @@
+default_pkg_nofetch() { __phase_pkg_nofetch; }
diff --git a/data/lib/pkgcore/ebd/eapi/2/src_compile.bash b/data/lib/pkgcore/ebd/eapi/2/src_compile.bash
new file mode 100644
index 000000000..787714d89
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/2/src_compile.bash
@@ -0,0 +1,4 @@
+# moved to src_configure
+unset -f econf
+
+default_src_compile() { __phase_src_compile; }
diff --git a/data/lib/pkgcore/ebd/eapi/2/src_configure.bash b/data/lib/pkgcore/ebd/eapi/2/src_configure.bash
new file mode 100644
index 000000000..e0067312d
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/2/src_configure.bash
@@ -0,0 +1,73 @@
+econf() {
+ local ret
+ ECONF_SOURCE=${ECONF_SOURCE:-.}
+ if [[ ! -x ${ECONF_SOURCE}/configure ]]; then
+ [[ -f ${ECONF_SOURCE}/configure ]] && die "configure script isn't executable"
+ die "no configure script found"
+ fi
+
+ if [[ -d /usr/share/gnuconfig ]]; then
+ local x
+ find "${WORKDIR}" -type f \( -name config.guess -o -name config.sub \) | \
+ while read x; do
+ echo "econf: replacing ${x} with /usr/share/gnuconfig/${x##*/}"
+ cp -f "/usr/share/gnuconfig/${x##*/}" "${x}"
+ done
+ fi
+
+ # if the profile defines a location to install libs to aside from default, pass it on.
+ # if the ebuild passes in --libdir, they're responsible for the conf_libdir fun.
+ local CONF_LIBDIR=$(__get_libdir)
+ if [[ -n ${CONF_LIBDIR} && $* != *"--libdir="* ]]; then
+ if [[ $* == *"--exec-prefix="* ]]; then
+ local args=$(echo $*)
+ local -a prefix=( $(echo ${args/*--exec-prefix[= ]}) )
+ CONF_PREFIX=${prefix/--*}
+ [[ ${CONF_PREFIX} != /* ]] && CONF_PREFIX=/${CONF_PREFIX}
+ elif [[ $* == *"--prefix="* ]]; then
+ local args=$(echo $*)
+ local -a prefix=( $(echo ${args/*--prefix[= ]}) )
+ CONF_PREFIX=${prefix/--*}
+ [[ ${CONF_PREFIX} != /* ]] && CONF_PREFIX=/${CONF_PREFIX}
+ else
+ CONF_PREFIX=/usr
+ fi
+ export CONF_PREFIX
+ [[ ${CONF_LIBDIR} != /* ]] && CONF_LIBDIR=/${CONF_LIBDIR}
+ set -- --libdir="$(__strip_duplicate_slashes "${CONF_PREFIX}${CONF_LIBDIR}")" "$@"
+ fi
+
+ # get EAPI specific arguments
+ local help_text=$("${ECONF_SOURCE}/configure" --help 2> /dev/null)
+ set -- $(__run_eapi_funcs --override __econf_options "${help_text}") "$@"
+
+ # Reset IFS since we're interpreting user supplied EXTRA_ECONF.
+ local IFS=$' \t\n'
+ set -- "${ECONF_SOURCE}/configure" \
+ --prefix="${EPREFIX}"/usr \
+ ${CBUILD:+--build="${CBUILD}"} \
+ --host="${CHOST}" \
+ ${CTARGET:+--target="${CTARGET}"} \
+ --mandir="${EPREFIX}"/usr/share/man \
+ --infodir="${EPREFIX}"/usr/share/info \
+ --datadir="${EPREFIX}"/usr/share \
+ --sysconfdir="${EPREFIX}"/etc \
+ --localstatedir="${EPREFIX}"/var/lib \
+ "$@" \
+ ${EXTRA_ECONF}
+
+ echo "$@"
+
+ if ! "$@"; then
+ if [[ -s config.log ]]; then
+ echo
+ echo "!!! Please attach the config.log to your bug report:"
+ echo "!!! ${PWD}/config.log"
+ fi
+ die "econf failed"
+ fi
+ return $?
+}
+
+
+default_src_configure() { __phase_src_configure; }
diff --git a/data/lib/pkgcore/ebd/eapi/2/src_prepare.bash b/data/lib/pkgcore/ebd/eapi/2/src_prepare.bash
new file mode 100644
index 000000000..0038c6159
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/2/src_prepare.bash
@@ -0,0 +1 @@
+default_src_prepare() { __phase_src_prepare; }
diff --git a/data/lib/pkgcore/ebd/eapi/2/src_test.bash b/data/lib/pkgcore/ebd/eapi/2/src_test.bash
new file mode 100644
index 000000000..e1b0749a4
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/2/src_test.bash
@@ -0,0 +1 @@
+default_src_test() { __phase_src_test; }
diff --git a/data/lib/pkgcore/ebd/eapi/2/src_unpack.bash b/data/lib/pkgcore/ebd/eapi/2/src_unpack.bash
new file mode 100644
index 000000000..684d0b437
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/2/src_unpack.bash
@@ -0,0 +1 @@
+default_src_unpack() { __phase_src_unpack; }
diff --git a/data/lib/pkgcore/ebd/eapi/4/global.bash b/data/lib/pkgcore/ebd/eapi/4/global.bash
new file mode 100644
index 000000000..c8ca5d110
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/4/global.bash
@@ -0,0 +1,19 @@
+__phase_src_install() {
+ if [[ -f Makefile || -f GNUmakefile || -f makefile ]]; then
+ emake DESTDIR="${D}" install
+ fi
+
+ local docs PKGCORE_DOCDESTTREE=
+ if ! docs=$(declare -p DOCS 2> /dev/null); then
+ for docs in README* ChangeLog AUTHORS NEWS TODO CHANGES \
+ THANKS BUGS FAQ CREDITS CHANGELOG; do
+ [[ -s ${docs} ]] && dodoc "${docs}"
+ done
+ elif [[ ${docs} == "declare -a "* ]]; then
+ dodoc "${DOCS[@]}"
+ else
+ dodoc ${DOCS}
+ fi
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/eapi/4/phase.bash b/data/lib/pkgcore/ebd/eapi/4/phase.bash
new file mode 100644
index 000000000..f075cb485
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/4/phase.bash
@@ -0,0 +1,3 @@
+nonfatal() { PKGCORE_NONFATAL=true "$@"; }
+
+:
diff --git a/data/lib/pkgcore/ebd/eapi/4/src_configure.bash b/data/lib/pkgcore/ebd/eapi/4/src_configure.bash
new file mode 100644
index 000000000..5f859526a
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/4/src_configure.bash
@@ -0,0 +1,5 @@
+__econf_options_eapi4() {
+ if [[ $1 == *"--disable-dependency-tracking"* ]]; then
+ echo --disable-dependency-tracking
+ fi
+}
diff --git a/data/lib/pkgcore/ebd/eapi/4/src_install.bash b/data/lib/pkgcore/ebd/eapi/4/src_install.bash
new file mode 100644
index 000000000..50918ed02
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/4/src_install.bash
@@ -0,0 +1,3 @@
+default_src_install() { __phase_src_install; }
+
+docompress() { __ebd_ipc_cmd ${FUNCNAME} "" "$@"; }
diff --git a/data/lib/pkgcore/ebd/eapi/5/global.bash b/data/lib/pkgcore/ebd/eapi/5/global.bash
new file mode 100644
index 000000000..c9dfe178d
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/5/global.bash
@@ -0,0 +1,16 @@
+# parallel tests are allowed (no forced -j1)
+__phase_src_test() {
+ addpredict /
+ local extra_args=( ${EXTRA_EMAKE} )
+ if make check -n &> /dev/null; then
+ echo ">>> Test phase [check]: ${CATEGORY}/${PF}"
+ emake "${extra_args[@]}" check || die "make check failed, see above for details"
+ elif make test -n &> /dev/null; then
+ emake "${extra_args[@]}" test || die "make test failed, see above for details"
+ else
+ echo ">>> Test phase [none]: ${CATEGORY}/${PF}"
+ fi
+ SANDBOX_PREDICT=${SANDBOX_PREDICT%:/}
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/eapi/5/phase.bash b/data/lib/pkgcore/ebd/eapi/5/phase.bash
new file mode 100644
index 000000000..8fe6ab01b
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/5/phase.bash
@@ -0,0 +1,6 @@
+usex() {
+ use "$1" && echo "${2-yes}$4" || echo "${3-no}$5"
+ return 0
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/eapi/5/src_configure.bash b/data/lib/pkgcore/ebd/eapi/5/src_configure.bash
new file mode 100644
index 000000000..5d3c9c390
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/5/src_configure.bash
@@ -0,0 +1,5 @@
+__econf_options_eapi5() {
+ if [[ $1 == *"--disable-silent-rules"* ]]; then
+ echo --disable-silent-rules
+ fi
+}
diff --git a/data/lib/pkgcore/ebd/eapi/6/global.bash b/data/lib/pkgcore/ebd/eapi/6/global.bash
new file mode 100644
index 000000000..3766014c3
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/6/global.bash
@@ -0,0 +1,22 @@
+__phase_src_prepare() {
+ local patches
+ if patches=$(declare -p PATCHES 2> /dev/null); then
+ if [[ ${patches} == "declare -a "* ]]; then
+ [[ ${#PATCHES[@]} -gt 0 ]] && eapply "${PATCHES[@]}"
+ else
+ [[ -n ${PATCHES} ]] && eapply ${PATCHES}
+ fi
+ fi
+
+ eapply_user
+}
+
+__phase_src_install() {
+ if [[ -f Makefile || -f GNUmakefile || -f makefile ]]; then
+ emake DESTDIR="${D}" install
+ fi
+
+ einstalldocs
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/eapi/6/phase.bash b/data/lib/pkgcore/ebd/eapi/6/phase.bash
new file mode 100644
index 000000000..bbdb3ac3e
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/6/phase.bash
@@ -0,0 +1,5 @@
+in_iuse() { [[ $1 =~ ${PKGCORE_IUSE_EFFECTIVE} ]]; }
+
+get_libdir() { __get_libdir lib; }
+
+:
diff --git a/data/lib/pkgcore/ebd/eapi/6/src_configure.bash b/data/lib/pkgcore/ebd/eapi/6/src_configure.bash
new file mode 100644
index 000000000..4385001cc
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/6/src_configure.bash
@@ -0,0 +1,8 @@
+__econf_options_eapi6() {
+ if [[ $1 == *"--docdir"* ]]; then
+ echo --docdir="${EPREFIX}"/usr/share/doc/${PF}
+ fi
+ if [[ $1 == *"--htmldir"* ]]; then
+ echo --htmldir="${EPREFIX}"/usr/share/doc/${PF}/html
+ fi
+}
diff --git a/data/lib/pkgcore/ebd/eapi/6/src_install.bash b/data/lib/pkgcore/ebd/eapi/6/src_install.bash
new file mode 100644
index 000000000..ad9d26b12
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/6/src_install.bash
@@ -0,0 +1,34 @@
+PKGCORE_BANNED_FUNCS=( einstall )
+
+einstalldocs() {
+ local docs PKGCORE_DOCDESTTREE=
+ if ! docs=$(declare -p DOCS 2> /dev/null); then
+ local -a DOCS
+ for docs in README* ChangeLog AUTHORS NEWS TODO CHANGES \
+ THANKS BUGS FAQ CREDITS CHANGELOG; do
+ [[ -s ${docs} ]] && DOCS+=( ${docs} )
+ done
+ if [[ ${#DOCS[@]} -gt 0 ]]; then
+ dodoc "${DOCS[@]}" || return $?
+ fi
+ elif [[ ${docs} == "declare -a "* ]]; then
+ if [[ ${#DOCS[@]} -gt 0 ]]; then
+ dodoc -r "${DOCS[@]}" || return $?
+ fi
+ elif [[ -n ${DOCS} ]]; then
+ dodoc -r ${DOCS} || return $?
+ fi
+
+ PKGCORE_DOCDESTTREE=html
+ if ! docs=$(declare -p HTML_DOCS 2> /dev/null); then
+ :
+ elif [[ ${docs} == "declare -a "* ]]; then
+ if [[ ${#HTML_DOCS[@]} -gt 0 ]]; then
+ dodoc -r "${HTML_DOCS[@]}" || return $?
+ fi
+ elif [[ -n ${HTML_DOCS} ]]; then
+ dodoc -r ${HTML_DOCS} || return $?
+ fi
+
+ return 0
+}
diff --git a/data/lib/pkgcore/ebd/eapi/6/src_prepare.bash b/data/lib/pkgcore/ebd/eapi/6/src_prepare.bash
new file mode 100644
index 000000000..0e07021c9
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/6/src_prepare.bash
@@ -0,0 +1,8 @@
+eapply() { __ebd_ipc_cmd ${FUNCNAME} "" "$@"; }
+
+eapply_user() {
+ [[ -f ${T}/.user_patches_applied ]] && return
+ __ebd_ipc_cmd ${FUNCNAME} "" "$@"
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/eapi/7/global.bash b/data/lib/pkgcore/ebd/eapi/7/global.bash
new file mode 100644
index 000000000..8fb3a5260
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/7/global.bash
@@ -0,0 +1,187 @@
+__ver_parse_range() {
+ local range=${1}
+ local max=${2}
+
+ [[ ${range} == [0-9]* ]] || die "${FUNCNAME}: range must start with a number"
+ start=${range%-*}
+ [[ ${range} == *-* ]] && end=${range#*-} || end=${start}
+ if [[ ${end} ]]; then
+ [[ ${start} -le ${end} ]] || die "${FUNCNAME}: end of range must be >= start"
+ [[ ${end} -le ${max} ]] || end=${max}
+ else
+ end=${max}
+ fi
+}
+
+__ver_split() {
+ local v=${1} LC_ALL=C
+
+ comp=()
+
+ # get separators and components
+ local s c
+ while [[ ${v} ]]; do
+ # cut the separator
+ s=${v%%[a-zA-Z0-9]*}
+ v=${v:${#s}}
+ # cut the next component; it can be either digits or letters
+ [[ ${v} == [0-9]* ]] && c=${v%%[^0-9]*} || c=${v%%[^a-zA-Z]*}
+ v=${v:${#c}}
+
+ comp+=( "${s}" "${c}" )
+ done
+}
+
+ver_cut() {
+ local range=${1}
+ local v=${2:-${PV}}
+ local start end
+ local -a comp
+
+ __ver_split "${v}"
+ local max=$((${#comp[@]}/2))
+ __ver_parse_range "${range}" "${max}"
+
+ local IFS=
+ if [[ ${start} -gt 0 ]]; then
+ start=$(( start*2 - 1 ))
+ fi
+ echo "${comp[*]:start:end*2-start}"
+}
+
+ver_rs() {
+ local v
+ (( ${#} & 1 )) && v=${@: -1} || v=${PV}
+ local start end i
+ local -a comp
+
+ __ver_split "${v}"
+ local max=$((${#comp[@]}/2 - 1))
+
+ while [[ ${#} -ge 2 ]]; do
+ __ver_parse_range "${1}" "${max}"
+ for (( i = start*2; i <= end*2; i+=2 )); do
+ [[ ${i} -eq 0 && -z ${comp[i]} ]] && continue
+ comp[i]=${2}
+ done
+ shift 2
+ done
+
+ local IFS=
+ echo "${comp[*]}"
+}
+
+__ver_compare_int() {
+ local a=$1 b=$2 d=$(( ${#1}-${#2} ))
+
+ # Zero-pad to equal length if necessary.
+ if [[ ${d} -gt 0 ]]; then
+ printf -v b "%0${d}d%s" 0 "${b}"
+ elif [[ ${d} -lt 0 ]]; then
+ printf -v a "%0$(( -d ))d%s" 0 "${a}"
+ fi
+
+ [[ ${a} > ${b} ]] && return 3
+ [[ ${a} == "${b}" ]]
+}
+
+__ver_compare() {
+ local va=${1} vb=${2} a an al as ar b bn bl bs br re LC_ALL=C
+
+ re="^([0-9]+(\.[0-9]+)*)([a-z]?)((_(alpha|beta|pre|rc|p)[0-9]*)*)(-r[0-9]+)?$"
+
+ [[ ${va} =~ ${re} ]] || die "${FUNCNAME}: invalid version: ${va}"
+ an=${BASH_REMATCH[1]}
+ al=${BASH_REMATCH[3]}
+ as=${BASH_REMATCH[4]}
+ ar=${BASH_REMATCH[7]}
+
+ [[ ${vb} =~ ${re} ]] || die "${FUNCNAME}: invalid version: ${vb}"
+ bn=${BASH_REMATCH[1]}
+ bl=${BASH_REMATCH[3]}
+ bs=${BASH_REMATCH[4]}
+ br=${BASH_REMATCH[7]}
+
+ # Compare numeric components (PMS algorithm 3.2)
+ # First component
+ __ver_compare_int "${an%%.*}" "${bn%%.*}" || return
+
+ while [[ ${an} == *.* && ${bn} == *.* ]]; do
+ # Other components (PMS algorithm 3.3)
+ an=${an#*.}
+ bn=${bn#*.}
+ a=${an%%.*}
+ b=${bn%%.*}
+ if [[ ${a} == 0* || ${b} == 0* ]]; then
+ # Remove any trailing zeros
+ [[ ${a} =~ 0+$ ]] && a=${a%"${BASH_REMATCH[0]}"}
+ [[ ${b} =~ 0+$ ]] && b=${b%"${BASH_REMATCH[0]}"}
+ [[ ${a} > ${b} ]] && return 3
+ [[ ${a} < ${b} ]] && return 1
+ else
+ __ver_compare_int "${a}" "${b}" || return
+ fi
+ done
+ [[ ${an} == *.* ]] && return 3
+ [[ ${bn} == *.* ]] && return 1
+
+ # Compare letter components (PMS algorithm 3.4)
+ [[ ${al} > ${bl} ]] && return 3
+ [[ ${al} < ${bl} ]] && return 1
+
+ # Compare suffixes (PMS algorithm 3.5)
+ as=${as#_}${as:+_}
+ bs=${bs#_}${bs:+_}
+ while [[ -n ${as} && -n ${bs} ]]; do
+ # Compare each suffix (PMS algorithm 3.6)
+ a=${as%%_*}
+ b=${bs%%_*}
+ if [[ ${a%%[0-9]*} == "${b%%[0-9]*}" ]]; then
+ __ver_compare_int "${a##*[a-z]}" "${b##*[a-z]}" || return
+ else
+ # Check for p first
+ [[ ${a%%[0-9]*} == p ]] && return 3
+ [[ ${b%%[0-9]*} == p ]] && return 1
+ # Hack: Use that alpha < beta < pre < rc alphabetically
+ [[ ${a} > ${b} ]] && return 3 || return 1
+ fi
+ as=${as#*_}
+ bs=${bs#*_}
+ done
+ if [[ -n ${as} ]]; then
+ [[ ${as} == p[_0-9]* ]] && return 3 || return 1
+ elif [[ -n ${bs} ]]; then
+ [[ ${bs} == p[_0-9]* ]] && return 1 || return 3
+ fi
+
+ # Compare revision components (PMS algorithm 3.7)
+ __ver_compare_int "${ar#-r}" "${br#-r}" || return
+
+ return 2
+}
+
+ver_test() {
+ local va op vb
+
+ if [[ $# -eq 3 ]]; then
+ va=${1}
+ shift
+ else
+ va=${PVR}
+ fi
+
+ [[ $# -eq 2 ]] || die "${FUNCNAME}: bad number of arguments"
+
+ op=${1}
+ vb=${2}
+
+ case ${op} in
+ -eq|-ne|-lt|-le|-gt|-ge) ;;
+ *) die "${FUNCNAME}: invalid operator: ${op}" ;;
+ esac
+
+ __ver_compare "${va}" "${vb}"
+ test $? "${op}" 2
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/eapi/7/src_configure.bash b/data/lib/pkgcore/ebd/eapi/7/src_configure.bash
new file mode 100644
index 000000000..1ff999c65
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/7/src_configure.bash
@@ -0,0 +1,7 @@
+__econf_options_eapi7() {
+ if [[ $1 == *"--with-sysroot"* ]]; then
+ echo --with-sysroot="${ESYSROOT:-/}"
+ fi
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/eapi/7/src_install.bash b/data/lib/pkgcore/ebd/eapi/7/src_install.bash
new file mode 100644
index 000000000..5e7337046
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/7/src_install.bash
@@ -0,0 +1,3 @@
+PKGCORE_BANNED_FUNCS=( libopts )
+
+dostrip() { __ebd_ipc_cmd ${FUNCNAME} "" "$@"; }
diff --git a/data/lib/pkgcore/ebd/eapi/8/global.bash b/data/lib/pkgcore/ebd/eapi/8/global.bash
new file mode 100644
index 000000000..574e071c9
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/8/global.bash
@@ -0,0 +1,14 @@
+__phase_src_prepare() {
+ local patches
+ if patches=$(declare -p PATCHES 2> /dev/null); then
+ if [[ ${patches} == "declare -a "* ]]; then
+ [[ ${#PATCHES[@]} -gt 0 ]] && eapply -- "${PATCHES[@]}"
+ else
+ [[ -n ${PATCHES} ]] && eapply -- ${PATCHES}
+ fi
+ fi
+
+ eapply_user
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/eapi/8/phase.bash b/data/lib/pkgcore/ebd/eapi/8/phase.bash
new file mode 100644
index 000000000..efeccd889
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/8/phase.bash
@@ -0,0 +1,9 @@
+PKGCORE_BANNED_FUNCS=( hasq hasv useq )
+
+usev() {
+ if use "$1"; then
+ echo "${2:-${1#!}}"
+ return 0
+ fi
+ return 1
+}
diff --git a/data/lib/pkgcore/ebd/eapi/8/src_configure.bash b/data/lib/pkgcore/ebd/eapi/8/src_configure.bash
new file mode 100644
index 000000000..ed94b52bf
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/8/src_configure.bash
@@ -0,0 +1,8 @@
+__econf_options_eapi8() {
+ if [[ $1 == *"--datarootdir"* ]]; then
+ echo "--datarootdir=${EPREFIX}/usr/share"
+ fi
+ if [[ $1 == *"--disable-static"* || $1 == *"--enable-static"* ]]; then
+ echo "--disable-static"
+ fi
+}
diff --git a/data/lib/pkgcore/ebd/eapi/common.bash b/data/lib/pkgcore/ebd/eapi/common.bash
new file mode 100644
index 000000000..daff5b2f0
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/common.bash
@@ -0,0 +1,153 @@
+# Common EAPI functionality (mainly phase related)
+
+# debug-print() gets called from many places with verbose status information useful
+# for tracking down problems. The output is in ${T}/eclass-debug.log.
+# You can set ECLASS_DEBUG_OUTPUT to redirect the output somewhere else as well.
+# The special "on" setting echoes the information, mixing it with the rest of the
+# emerge output.
+# You can override the setting by exporting a new one from the console, or you can
+# set a new default in make.*. Here the default is "" or unset.
+
+# in the future might use e* from /etc/init.d/functions.sh if i feel like it
+debug-print() {
+ if __safe_has ${EBUILD_PHASE} depend nofetch pretend config info postinst; then
+ return
+ fi
+ # if ${T} isn't defined, we're in dep calculation mode and
+ # shouldn't do anything
+ [[ -z ${T} ]] && return 0
+
+ local _item
+ for _item in "$@"; do
+ # extra user-configurable targets
+ if [[ ${ECLASS_DEBUG_OUTPUT} == "on" ]]; then
+ echo "debug: ${_item}"
+ elif [[ -n ${ECLASS_DEBUG_OUTPUT} ]]; then
+ echo "debug: ${_item}" >> "${ECLASS_DEBUG_OUTPUT}"
+ fi
+
+ # default target
+ echo "${_item}" >> "${T}"/eclass-debug.log
+ chmod g+w "${T}"/eclass-debug.log &> /dev/null
+ done
+ # let the portage user own/write to this file
+}
+
+# The following 2 functions are debug-print() wrappers
+
+debug-print-function() {
+ local str="$1: entering function"
+ shift
+ debug-print "${str}, parameters: $*"
+}
+
+debug-print-section() {
+ debug-print "now in section $*"
+}
+
+__get_libdir() {
+ local libdir=$1 libdir_var="LIBDIR_${ABI}"
+ [[ -n ${ABI} && -n ${!libdir_var} ]] && libdir=${!libdir_var}
+ echo "${libdir}"
+}
+
+__phase_pre_phase() {
+ if [[ -d ${S} ]]; then
+ cd "${S}"
+ elif __safe_has "${EAPI}" 0 1 2 3; then
+ cd "${WORKDIR}"
+ elif [[ -n ${A} ]]; then
+ die "source directory '${S}' doesn't exist, but \${A} isn't empty (see S-WORKDIR-FALLBACK in PMS)"
+ else
+ local phase
+ # eapi4 blatant idiocy...
+ for phase in unpack prepare configure compile test install; do
+ [[ ${phase} == ${EBUILD_PHASE} ]] && break
+ __is_function src_${phase} || continue
+ # to reach here means that (for example), we're doing src_install, and src_compile was defined
+ # but S doesn't exist.
+ die "source directory '${S}' doesn't exist, \${A} is defined, and there was a defined " \
+ "phase function '${phase}' prior to '${EBUILD_PHASE}'; please see S-WORKDIR-FALLBACK " \
+ "in pms for the details of what is allowed for eapi4 and later"
+ done
+ cd "${WORKDIR}"
+ fi
+}
+
+__phase_pre_src_unpack() { cd "${WORKDIR}"; }
+__phase_pre_src_prepare() { __phase_pre_phase; }
+__phase_pre_src_test() { __phase_pre_phase; }
+
+__phase_pre_src_configure() {
+ local var
+ for var in C{BUILD,HOST,TARGET,C,XX} {AS,LD,{,LIB}C{,XX}}FLAGS CCACHE_DIR; do
+ [[ -n ${!var+set} ]] && export ${var}="${!var}"
+ done
+ __phase_pre_phase
+}
+
+__phase_pre_src_compile() {
+ # just reuse the default_pre_src_configure; this means we don't have to care
+ # if the eapi has configure or not.
+ __phase_pre_src_configure
+
+ if __feature_is_enabled distcc; then
+ [[ -n ${DISTCC_DIR} ]] && addwrite "${DISTCC_DIR}"
+ if __feature_is_enabled distcc-pump; then
+ eval $(pump --startup) || echo "Warning: Failed starting pump" >&2
+ trap 'pump --shutdown' EXIT
+ fi
+ fi
+}
+
+__phase_post_src_compile() {
+ if __feature_is_enabled distcc && __feature_is_enabled distcc-pump; then
+ pump --shutdown
+ trap - EXIT
+ fi
+}
+
+__phase_pre_src_install() {
+ export PKGCORE_DESTTREE=/usr PKGCORE_INSDESTTREE='' \
+ PKGCORE_EXEDESTTREE='' PKGCORE_DOCDESTTREE=''
+ if ${PKGCORE_HAS_DESTTREE}; then
+ export DESTTREE=${PKGCORE_DESTTREE}
+ export INSDESTTREE=${PKGCORE_INSDESTTREE}
+ fi
+ export INSOPTIONS="-m0644" EXEOPTIONS="-m0755"
+ export LIBOPTIONS="-m0644" DIROPTIONS="-m0755"
+ export PORTAGE_COMPRESS=${PORTAGE_COMPRESS:-bzip2}
+ export PORTAGE_COMPRESS_FLAGS=${PORTAGE_COMPRESS_FLAGS:--9}
+ export D
+ rm -rf "${D}"
+ if ${PKGCORE_PREFIX_SUPPORT}; then
+ [[ -n ${ED+set} ]] || \
+ die "variable ED is unset, but prefix mode is enabled, internal error?"
+ export ED=${ED}
+ mkdir -p "${ED}"
+ else
+ mkdir "${D}"
+ fi
+ __phase_pre_phase
+}
+
+# Iterate over the inherited EAPI stack running all EAPI specific functions
+# starting with a defined prefix. Defaults to running in inherited order from
+# the current package's EAPI to the oldest inherited EAPI. To run in overriding
+# order (the reverse direction), pass '--override' as the first argument.
+__run_eapi_funcs() {
+ local eapis=( ${PKGCORE_EAPI_INHERITS} )
+ if [[ $1 == --override ]]; then
+ eapis=( $(__reverse_array eapis) )
+ shift
+ fi
+ local func_prefix=$1
+ shift
+
+ local eapi
+ for eapi in "${eapis[@]}"; do
+ __qa_run_function_if_exists ${func_prefix}_eapi${eapi} "$@"
+ done
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/eapi/depend.bash b/data/lib/pkgcore/ebd/eapi/depend.bash
new file mode 100644
index 000000000..286bb5b95
--- /dev/null
+++ b/data/lib/pkgcore/ebd/eapi/depend.bash
@@ -0,0 +1,116 @@
+# Common EAPI functions
+
+has() {
+ local needle=$1
+ shift
+
+ local IFS=$'\001'
+
+ # try fast mode first; no IFS match is guaranteed that the needle isn't there.
+ [[ "${IFS}${*}${IFS}" != *"${IFS}${needle}${IFS}"* ]] && return 1
+
+ # If we have a match, ensure it's not due to $@ already having \001 in it.
+ # unlikely, but better safe than sorry.
+ IFS=' '
+ [[ *$'\001'* != $* ]] && return 0
+
+ # \001 for some insane reason was in $@; fallback to the slow for loop.
+ # Suppress debug output for this part however.
+ __shopt_push +x
+ local x
+ for x in "$@"; do
+ if [[ ${x} == ${needle} ]]; then
+ __shopt_pop
+ return 0
+ fi
+ done
+ __shopt_pop
+ return 1
+}
+
+hasq() {
+ has ${EBUILD_PHASE} prerm postrm || eqawarn \
+ "QA Notice: The 'hasq' function is deprecated (replaced by 'has')"
+ has "$@"
+}
+
+hasv() {
+ has "$@" && echo "$1"
+}
+
+# stubbed debug commands to avoid debug output during metadata generation
+debug-print() { :; }
+debug-print-function() { :; }
+debug-print-section() { :; }
+
+# output commands
+eqawarn() {
+ __elog_base QA "$*"
+ printf " ${PKGCORE_RC_WARN}*${PKGCORE_RC_NORMAL} %b\n" "${*}" >&2
+ PKGCORE_RC_LAST_CMD="eqawarn"
+ return 0
+}
+
+elog() {
+ __elog_base LOG "$*"
+ printf " ${PKGCORE_RC_GOOD}*${PKGCORE_RC_NORMAL} %b\n" "${*}" >&2
+ PKGCORE_RC_LAST_CMD="elog"
+ return 0
+}
+
+einfo() {
+ printf " ${PKGCORE_RC_GOOD}*${PKGCORE_RC_NORMAL} %b\n" "${*}" >&2
+ PKGCORE_RC_LAST_CMD="einfo"
+ return 0
+}
+
+einfon() {
+ __elog_base INFO "$*"
+ printf " ${PKGCORE_RC_GOOD}*${PKGCORE_RC_NORMAL} %b" "${*}" >&2
+ PKGCORE_RC_LAST_CMD="einfon"
+ return 0
+}
+
+ewarn() {
+ __elog_base WARN "$*"
+ printf " ${PKGCORE_RC_WARN}*${PKGCORE_RC_NORMAL} %b\n" "${*}" >&2
+ PKGCORE_RC_LAST_CMD="ewarn"
+ return 0
+}
+
+eerror() {
+ __elog_base ERROR "$*"
+ printf " ${PKGCORE_RC_BAD}*${PKGCORE_RC_NORMAL} %b\n" "${*}" >&2
+ PKGCORE_RC_LAST_CMD="eerror"
+ return 0
+}
+
+ebegin() {
+ local msg="$* ..."
+ einfon "${msg}"
+ echo
+ PKGCORE_RC_LAST_CMD="ebegin"
+ return 0
+}
+
+eend() {
+ local retval=${1:-0}
+ shift
+
+ local msg
+
+ if [[ ${retval} == 0 ]]; then
+ msg="${PKGCORE_RC_BRACKET}[ ${PKGCORE_RC_GOOD}ok${PKGCORE_RC_BRACKET} ]${PKGCORE_RC_NORMAL}"
+ else
+ if [[ $# -ne 0 ]]; then
+ eerror "$*"
+ fi
+ msg="${PKGCORE_RC_BRACKET}[ ${PKGCORE_RC_BAD}!!${PKGCORE_RC_BRACKET} ]${PKGCORE_RC_NORMAL}"
+ fi
+
+ echo -e "${PKGCORE_RC_ENDCOL} ${msg}" >&2
+
+ return ${retval}
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/ebuild-daemon-lib.bash b/data/lib/pkgcore/ebd/ebuild-daemon-lib.bash
new file mode 100644
index 000000000..77819947f
--- /dev/null
+++ b/data/lib/pkgcore/ebd/ebuild-daemon-lib.bash
@@ -0,0 +1,148 @@
+# ebuild daemon lib code
+
+PKGCORE_EBD_PID=${BASHPID}
+# Use ebd_read/ebd_write for talking to the running pkgcore instance instead of
+# echo'ing to the fd yourself. This allows us to move the open fd's w/out
+# issues down the line.
+__ebd_read_line_nonfatal() {
+ read -u ${PKGCORE_EBD_READ_FD} $1
+}
+
+__ebd_read_line() {
+ __ebd_read_line_nonfatal "$@"
+ local ret=$?
+ [[ ${ret} -ne 0 ]] && \
+ die "coms error in ${PKGCORE_EBD_PID}, read_line $@ failed w/ ${ret}"
+}
+
+# Read a line into an array using a bell char as a delimiter since the null char
+# can't be assigned to variables.
+__ebd_read_array() {
+ IFS=$'\07' read -u ${PKGCORE_EBD_READ_FD} -a $1
+ [[ $? -ne 0 ]] && \
+ die "coms error in ${PKGCORE_EBD_PID}, read_array $@ failed"
+}
+
+# read -N usage requires bash-4.1 or so (EAPI 6 requires >= 4.2)
+__ebd_read_size() {
+ read -u ${PKGCORE_EBD_READ_FD} -r -N $1 $2
+ local ret=$?
+ [[ ${ret} -ne 0 ]] && \
+ die "coms error in ${PKGCORE_EBD_PID}, read_size $@ failed w/ ${ret}"
+}
+
+__ebd_read_cat_size() {
+ dd bs=$1 count=1 <&${PKGCORE_EBD_READ_FD}
+}
+
+# Write arg list as a single string using a null char delimiter terminated by a newline.
+# Note that this requires printf as echo doesn't appear to respect IFS=$'\0'.
+__ebd_write_array() {
+ printf "%s\0" "$@" >&${PKGCORE_EBD_WRITE_FD}
+ __ebd_write_line
+}
+
+__ebd_write_line() {
+ echo "$*" >&${PKGCORE_EBD_WRITE_FD}
+ local ret=$?
+ [[ ${ret} -ne 0 ]] && \
+ die "coms error, write failed w/ ${ret}"
+}
+
+__ebd_write_raw() {
+ echo -n "$*" >&${PKGCORE_EBD_WRITE_FD} || die "coms error, __ebd_write_raw failed"
+}
+
+__ipc_exit() {
+ # exit in a helper compatible way when running IPC command from a helper
+ [[ -n ${HELPER_ERROR_PREFIX} ]] && __helper_exit "$@"
+
+ local ret=$1
+ shift
+ if [[ ${ret} == 0 ]]; then
+ [[ -n $@ ]] && echo "$@"
+ return 0
+ fi
+
+ local error_msg="${IPC_CMD}: exitcode ${ret}"
+ [[ -n $@ ]] && error_msg+=": $@"
+
+ if ${PKGCORE_NONFATAL}; then
+ eerror "${error_msg}"
+ return ${ret}
+ fi
+
+ die "${error_msg}"
+}
+
+# run an ebuild command on the python side and return its status
+__ebd_ipc_cmd() {
+ local IPC_CMD=$1 opts=$2 ret_str
+ local -a ret
+ shift 2
+
+ __ebd_write_line ${IPC_CMD}
+ __ebd_write_line ${PKGCORE_NONFATAL:-false}
+ __ebd_write_line ${PWD}
+ __ebd_write_line ${EBUILD_PHASE}
+ __ebd_write_line ${opts}
+ __ebd_write_array "$@"
+ __ebd_read_array ret
+ __ipc_exit "${ret[@]}"
+}
+
+# ask the python side to display sandbox complaints
+__request_sandbox_summary() {
+ local line
+ __ebd_write_line "__request_sandbox_summary ${SANDBOX_LOG}"
+ __ebd_read_line line
+ while [[ ${line} != "end_sandbox_summary" ]]; do
+ echo "${line}"
+ __ebd_read_line line
+ done
+}
+
+__internal_inherit() {
+ local line
+ if [[ $# -ne 1 ]]; then
+ die "internal_inherit accepts an eclass name arg, got $*"
+ fi
+ if [[ -n ${PKGCORE_PRELOADED_ECLASSES[$1]} ]]; then
+ __qa_invoke "${PKGCORE_PRELOADED_ECLASSES[$1]}"
+ return
+ fi
+ __ebd_write_line "request_inherit $1"
+ __ebd_read_line line
+ if [[ ${line} == "path" ]]; then
+ __ebd_read_line line
+ __qa_invoke source "${line}" >&2 || die "failed eclass inherit: $1"
+ elif [[ ${line} == "transfer" ]]; then
+ __ebd_read_line line
+ __qa_invoke eval "${line}" || die "failed evaluating eclass $1 on transfer"
+ else
+ die "unknown inherit command from python for eclass $1: '${line}'"
+ fi
+}
+
+__source_bashrcs() {
+ ${PKGCORE_SUPPRESS_BASHRCS:-false} && return
+ local line
+ __ebd_write_line "request_bashrcs"
+ __ebd_read_line line
+ while [[ ${line} != "end_request" ]]; do
+ if [[ ${line} == "path" ]]; then
+ __ebd_read_line line
+ source "${line}" >&2
+ elif [[ ${line} == "transfer" ]]; then
+ __ebd_read_line line
+ eval "${line}" || die "failed evaluating profile bashrc: ${line}"
+ else
+ __ebd_write_line "failed"
+ die "unknown profile bashrc transfer mode from python: '${line}'"
+ fi
+ __ebd_write_line "next"
+ __ebd_read_line line
+ done
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/ebuild-daemon.bash b/data/lib/pkgcore/ebd/ebuild-daemon.bash
new file mode 100644
index 000000000..354f7ff0c
--- /dev/null
+++ b/data/lib/pkgcore/ebd/ebuild-daemon.bash
@@ -0,0 +1,405 @@
+# core ebuild processor handling code
+
+# These are functions that shouldn't be marked readonly, since they're runtime
+# switchable.
+PKGCORE_RUNTIME_FUNCS=( '__timed_call' )
+
+PKGCORE_EBD_PATH=${BASH_SOURCE[0]%/*}
+
+__set_perf_debug() {
+ if [[ ${PKGCORE_DEBUG} -ge 4 || -n ${PKGCORE_PERF_DEBUG} ]]; then
+ __timed_call() {
+ echo "timing $*" >&2
+ time "$@"
+ local __ret=$?
+ echo "timed $*" >&2
+ return ${__ret}
+ }
+ else
+ __timed_call() {
+ "$@"
+ }
+ fi
+}
+
+__set_perf_debug
+
+# Temporary function used by the daemon, till proper die implementation is loaded.
+die() {
+ echo "$@" >&2
+ exit 1
+}
+
+declare -rf __set_perf_debug
+declare -r PKGCORE_EBD_WRITE_FD PKGCORE_EBD_READ_FD
+
+__ebd_sigint_handler() {
+ EBD_DISABLE_DIEFUNC="yes"
+ # silence ourselves as everything shuts down.
+ exec 2>/dev/null
+ exec 1>/dev/null
+ # suppress sigpipe; if we can't tell the parent to die,
+ # it's already shutting us down.
+ trap "exit 2" SIGPIPE
+ __ebd_write_line "SIGINT"
+ trap - SIGINT
+ # this relies on the python side to *not* discard the killed
+ exit 2
+}
+
+__ebd_sigterm_handler() {
+ EBD_DISABLE_DIEFUNC="yes"
+ # silence ourselves as everything shuts down.
+ exec 2>/dev/null
+ exec 1>/dev/null
+ # suppress sigpipe; if we can't tell the parent to die,
+ # it's already shutting us down.
+ trap "exit 15" SIGPIPE
+ __ebd_write_line "SIGTERM"
+ trap - SIGTERM
+ exit 15
+}
+
+__ebd_exec_main() {
+ if ! source "${PKGCORE_EBD_PATH}"/ebuild-daemon-lib.bash; then
+ die "failed sourcing ${PKGCORE_EBD_PATH}/ebuild-daemon-lib.bash"
+ fi
+
+ # Ensure the other side is still there, well, this moreso is for the python
+ # side to ensure loading up the intermediate funcs succeeded.
+ local com
+ __ebd_read_line com
+ if [[ ${com} != "ebd?" ]]; then
+ die "serv init coms failed, received '${com}' when expecting 'ebd?'"
+ fi
+ __ebd_write_line "ebd!"
+
+ # get our die functionality now.
+ if ! source "${PKGCORE_EBD_PATH}"/exit-handling.bash; then
+ __ebd_write_line "failed sourcing exit handling functionality"
+ exit 2
+ fi
+
+ if ! source "${PKGCORE_EBD_PATH}"/isolated-functions.bash; then
+ __ebd_write_line "failed sourcing isolated-functions.bash"
+ exit 2
+ fi
+
+ # enable colored support as early as possible for early die() usage
+ [[ -z ${NO_COLOR} ]] && __colored_output_enable
+
+ if ! source "${PKGCORE_EBD_PATH}"/ebuild.bash; then
+ __ebd_write_line "failed"
+ die "failed sourcing ${PKGCORE_EBD_PATH}/ebuild.bash"
+ fi
+
+ __ebd_read_line com
+ case ${com} in
+ "sandbox_log?")
+ if [[ ! ${SANDBOX_LOG} ]]; then
+ die "sandbox enabled but no SANDBOX_LOG?!"
+ fi
+ __ebd_write_line "${SANDBOX_LOG}"
+ declare -rx SANDBOX_LOG=${SANDBOX_LOG}
+ addwrite "${SANDBOX_LOG}"
+ ;;
+ no_sandbox)
+ ;;
+ *)
+ die "unknown sandbox com: '${com}'"
+ ;;
+ esac
+
+ __IFS_push $'\n'
+ readonly_vars=( $(readonly) )
+ __IFS_pop
+ # extract variable names from declarations
+ readonly_vars=( "${readonly_vars[@]/%=*/}" )
+ readonly_vars=( "${readonly_vars[@]/#* * /}" )
+
+ for x in "${readonly_vars[@]}"; do
+ if ! __safe_has "${x}" "${PKGCORE_BLACKLIST_VARS[@]}"; then
+ PKGCORE_BLACKLIST_VARS+=( ${x} )
+ fi
+ done
+ __ebd_write_line ${readonly_vars[@]}
+ unset -v x readonly_vars
+
+ # protect ourselves
+ declare -rx PKGCORE_EBD_PATH=${PKGCORE_EBD_PATH}
+
+ declare -A PKGCORE_PRELOADED_ECLASSES
+
+ trap __ebd_sigint_handler SIGINT
+ trap __ebd_sigterm_handler SIGTERM
+
+ # finally, load the master list of pkgcore funcs. fallback to
+ # regenerating it if needed.
+ if [[ -f ${PKGCORE_EBD_PATH}/generated/funcs/global ]]; then
+ PKGCORE_BLACKLIST_FUNCS+=( $(<"${PKGCORE_EBD_PATH}"/generated/funcs/global) )
+ else
+ PKGCORE_BLACKLIST_FUNCS+=( $("${PKGCORE_EBD_PATH}"/generate_global_func_list 2> /dev/null) )
+ fi
+ [[ $? -eq 0 ]] || die "failed reading the global function skip list"
+
+ for x in "${PKGCORE_BLACKLIST_FUNCS[@]}"; do
+ __is_function "${x}" || continue
+ if ! __safe_has "${x}" "${PKGCORE_RUNTIME_FUNCS[@]}"; then
+ declare -fr ${x} &> /dev/null
+ fi
+ done
+ unset -v x
+
+ source "${PKGCORE_EBD_PATH}"/eapi/depend.bash || die "failed sourcing eapi/depend.bash"
+ __ebd_main_loop
+ exit 0
+}
+
+__ebd_process_sandbox_results() {
+ if [[ -z ${SANDBOX_LOG} || ! -e ${SANDBOX_LOG} ]]; then
+ return 0;
+ fi
+ echo "sandbox exists- ${SANDBOX_LOG}" >&2
+ __request_sandbox_summary >&2
+ echo "SANDBOX_ON:=${SANDBOX_ON:-unset}" >&2
+ echo "SANDBOX_DISABLED:=${SANDBOX_DISABLED:-unset}" >&2
+ echo "SANDBOX_READ:=${SANDBOX_READ:-unset}" >&2
+ echo "SANDBOX_WRITE:=${SANDBOX_WRITE:-unset}" >&2
+ echo "SANDBOX_PREDICT:=${SANDBOX_PREDICT:-unset}" >&2
+ echo "SANDBOX_DEBUG:=${SANDBOX_DEBUG:-unset}" >&2
+ echo "SANDBOX_DEBUG_LOG:=${SANDBOX_DEBUG_LOG:-unset}" >&2
+ echo "SANDBOX_LOG:=${SANDBOX_LOG:-unset}" >&2
+ echo "SANDBOX_ARMED:=${SANDBOX_ARMED:-unset}" >&2
+ return 1
+}
+
+__ebd_process_ebuild_phases() {
+ # note that this is entirely subshelled; as such exit is used rather than returns
+ (
+ declare -r PKGCORE_QA_SUPPRESSED=false
+ local phases=$@
+ local is_depends=true
+ if [[ ${phases/depend} == ${phases} ]]; then
+ is_depends=false
+ fi
+ local cont=0
+
+ while [[ ${cont} == 0 ]]; do
+ local line=''
+ __ebd_read_line line
+ case ${line} in
+ start_receiving_env*)
+ line=${line#start_receiving_env }
+ case ${line} in
+ file*)
+ line=${line#file }
+ source "${line}"
+ cont=$?
+ ;;
+ bytes*)
+ line=${line#bytes }
+ __ebd_read_size "${line}" line
+ __IFS_push $'\0'
+ eval "${line}"
+ cont=$?
+ __IFS_pop
+ ;;
+ lines|*)
+ while __ebd_read_line line && [[ ${line} != "end_receiving_env" ]]; do
+ __IFS_push $'\0'
+ eval "${line}"
+ cont=$?
+ __IFS_pop
+ if [[ ${cont} != 0 ]]; then
+ echo "err, env receiving threw an error for '${line}': $?" >&2
+ break
+ fi
+ done
+ ;;
+ esac
+ if [[ ${cont} != 0 ]]; then
+ __ebd_write_line "env_receiving_failed"
+ exit 1
+ fi
+ __set_perf_debug
+ __ebd_write_line "env_received"
+ ;;
+ logging*)
+ PORTAGE_LOGFILE=${line#logging }
+ __ebd_write_line "logging_ack"
+ ;;
+ set_sandbox_state*)
+ if [[ $(( ${line:18} )) -eq 0 ]]; then
+ export SANDBOX_DISABLED=1
+ else
+ export SANDBOX_DISABLED=0
+ export SANDBOX_VERBOSE="no"
+ fi
+ ;;
+ start_processing)
+ if ${is_depends} && [[ -n ${PKGCORE_METADATA_PATH} ]]; then
+ export PATH=${PKGCORE_METADATA_PATH}
+ fi
+ cont=2
+ ;;
+ shutdown_daemon)
+ break
+ ;;
+ alive)
+ __ebd_write_line "yep!"
+ ;;
+ *)
+ die "unknown phase processing com: '${line}'"
+ ;;
+ esac
+ done
+ if [[ ${cont} != 2 ]]; then
+ exit ${cont}
+ fi
+
+ [[ -n ${PORTAGE_LOGFILE} ]] && addwrite "$(readlink -f "${PORTAGE_LOGFILE}")"
+
+ [[ -n ${PORTAGE_TMPDIR} ]] && {
+ addpredict "${PORTAGE_TMPDIR}"
+ addwrite "${PORTAGE_TMPDIR}"
+ addread "${PORTAGE_TMPDIR}"
+ }
+
+ local ret
+ umask 0022
+
+ if [[ -z ${PORTAGE_LOGFILE} ]]; then
+ __execute_phases ${phases}
+ ret=$?
+ else
+ __execute_phases ${phases} &> >(umask 0002; tee -i -a "${PORTAGE_LOGFILE}")
+ ret=$?
+ fi
+
+ if [[ ${ret} -ne 0 ]]; then
+ __ebd_process_sandbox_results
+ exit ${ret}
+ fi
+ exit 0
+ )
+}
+
+__ebd_process_metadata() {
+ # protect the env.
+ # note the local usage is redundant in light of it, but prefer to write it this
+ # way so that if someone ever drops the (), it'll still not bleed out.
+ (
+ # Heavy QA checks (IFS, shopt, etc) are suppressed for speed
+ declare -r PKGCORE_QA_SUPPRESSED=false
+ # Wipe __mode; it bleeds from our parent.
+ unset -v __mode
+ local __data
+ local __ret
+ __ebd_read_size "$1" __data
+ local IFS=$'\0'
+ eval "$__data"
+ __ret=$?
+ unset -v __data
+ [[ ${__ret} -ne 0 ]] && exit 1
+ unset -v __ret
+ local IFS=$' \t\n'
+
+ if [[ -n ${PKGCORE_METADATA_PATH} ]]; then
+ export PATH=${PKGCORE_METADATA_PATH}
+ fi
+
+ # invoked internally by bash on PATH search failure, see the bash man
+ # page section on command execution for details
+ command_not_found_handle() {
+ die "external commands disallowed during metadata regen: '${*}'"
+ }
+
+ __execute_phases "${2:-depend}" && exit 0
+ __ebd_process_sandbox_results
+ exit 1
+ )
+}
+
+__make_preloaded_eclass_func() {
+ eval "__preloaded_eclass_$1() {
+ $2
+ }"
+ PKGCORE_PRELOADED_ECLASSES[$1]=__preloaded_eclass_$1
+}
+
+__ebd_main_loop() {
+ PKGCORE_BLACKLIST_VARS+=( __mode com is_depends phases line cont )
+ SANDBOX_ON=1
+ while :; do
+ local com=''
+ # If we don't manage to read, this means that the other end hung up.
+ # exit.
+ __ebd_read_line_nonfatal com || com="shutdown_daemon"
+ case ${com} in
+ process_ebuild*)
+ # cleanse whitespace.
+ local phases=$(echo ${com#process_ebuild})
+ __ebd_process_ebuild_phases ${phases}
+ if [[ $? -eq 0 ]]; then
+ __ebd_write_line "phases succeeded"
+ else
+ __ebd_write_line "phases failed ebd::${com% *} failed"
+ fi
+ ;;
+ shutdown_daemon)
+ break
+ ;;
+ preload_eclass\ *)
+ success="succeeded"
+ com=${com#preload_eclass }
+ for e in ${com}; do
+ x=${e##*/}
+ x=${x%.eclass}
+ if ! $(type -P bash) -n "${e}"; then
+ echo "errors detected in '${e}'" >&2
+ success='failed'
+ break
+ fi
+ __make_preloaded_eclass_func "${x}" "$(< "${e}")"
+ done
+ __ebd_write_line "preload_eclass ${success}"
+ unset -v e x success
+ ;;
+ clear_preloaded_eclasses)
+ unset -v PKGCORE_PRELOADED_ECLASSES
+ declare -A PKGCORE_PRELOADED_ECLASSES
+ __ebd_write_line "clear_preloaded_eclasses succeeded"
+ ;;
+ set_metadata_path\ *)
+ line=${com#set_metadata_path }
+ __ebd_read_size "${line}" PKGCORE_METADATA_PATH
+ __ebd_write_line "metadata_path_received"
+ ;;
+ gen_metadata\ *|gen_ebuild_env\ *)
+ local __mode="depend"
+ local error_output
+ [[ ${com} == gen_ebuild_env* ]] && __mode="generate_env"
+ line=${com#* }
+ # capture sourcing stderr output
+ error_output=$(__ebd_process_metadata "${line}" "${__mode}" 2>&1 1>/dev/null)
+ if [[ $? -eq 0 ]]; then
+ __ebd_write_line "phases succeeded"
+ else
+ [[ -n ${error_output} ]] || error_output="ebd::${com% *} failed"
+ __ebd_write_line "phases failed ${error_output}"
+ fi
+ ;;
+ alive)
+ __ebd_write_line "yep!"
+ ;;
+ *)
+ die "unknown ebd com: '${com}'"
+ ;;
+ esac
+ done
+}
+
+# start the daemon if requested
+[[ $1 == "daemonize" ]] && __ebd_exec_main
+
+:
diff --git a/data/lib/pkgcore/ebd/ebuild-default-functions.bash b/data/lib/pkgcore/ebd/ebuild-default-functions.bash
new file mode 100644
index 000000000..48bad0c10
--- /dev/null
+++ b/data/lib/pkgcore/ebd/ebuild-default-functions.bash
@@ -0,0 +1,247 @@
+# default functions for ebuild env that aren't saved- specific to the portage instance.
+
+# sandbox support functions
+addread() {
+ export SANDBOX_READ=${SANDBOX_READ}:$1
+}
+
+addwrite() {
+ export SANDBOX_WRITE=${SANDBOX_WRITE}:$1
+}
+
+adddeny() {
+ export SANDBOX_DENY=${SANDBOX_DENY}:$1
+}
+
+addpredict() {
+ export SANDBOX_PREDICT=${SANDBOX_PREDICT}:$1
+}
+
+__dyn_src_install() {
+ if __is_function src_install; then
+ __qa_invoke src_install
+ else
+ __qa_run_function_if_exists __phase_src_install
+ fi
+
+ "${PKGCORE_EBD_PATH}"/helpers/internals/prepall
+ ${PKGCORE_PREFIX_SUPPORT} || local ED=${D}
+ cd "${ED}"
+
+ if type -p scanelf > /dev/null; then
+ # Make sure we disallow insecure RUNPATH/RPATH's
+ # Don't want paths that point to the tree where the package was built
+ # (older, broken libtools would do this). Also check for null paths
+ # because the loader will search $PWD when it finds null paths.
+ local f=$(scanelf -qyRF '%r %p' "${ED}" | grep -E "(${WORKDIR}|${ED}|: |::|^ )")
+ if [[ -n ${f} ]]; then
+ echo -ne '\a\n'
+ echo "QA Notice: the following files contain insecure RUNPATH's"
+ echo " Please file a bug about this at http://bugs.gentoo.org/"
+ echo " For more information on this issue, kindly review:"
+ echo " http://bugs.gentoo.org/81745"
+ echo "${f}"
+ echo -ne '\a\n'
+ __feature_is_enabled stricter && die "Insecure binaries detected"
+ echo "autofixing rpath..."
+ TMPDIR=${WORKDIR} scanelf -BXr ${f} -o /dev/null
+ fi
+
+ # Check for setid binaries but are not built with BIND_NOW
+ f=$(scanelf -qyRF '%b %p' "${ED}")
+ if [[ -n ${f} ]]; then
+ echo -ne '\a\n'
+ echo "QA Notice: the following files are setXid, dyn linked, and using lazy bindings"
+ echo " This combination is generally discouraged. Try forcing via bashrc"
+ echo " LDFLAGS='-Wl,-z,now' for the pkg, or disable FEATURES=stricter"
+ echo "${f}"
+ echo -ne '\a\n'
+ __feature_is_enabled stricter && die "Aborting due to lazy bindings"
+ sleep 1
+ fi
+
+ # TEXTREL's are baaaaaaaad
+ f=$(scanelf -qyRF '%t %p' "${ED}")
+ if [[ -n ${f} ]]; then
+ echo -ne '\a\n'
+ echo "QA Notice: the following files contain runtime text relocations"
+ echo " Text relocations require a lot of extra work to be preformed by the"
+ echo " dynamic linker which will cause serious performance impact on IA-32"
+ echo " and might not function properly on other architectures hppa for example."
+ echo " If you are a programmer please take a closer look at this package and"
+ echo " consider writing a patch which addresses this problem."
+ echo "${f}"
+ echo -ne '\a\n'
+ __feature_is_enabled stricter && die "Aborting due to textrels"
+ sleep 1
+ fi
+
+ # Check for files with executable stacks
+ f=$(scanelf -qyRF '%e %p' "${ED}")
+ if [[ -n ${f} ]]; then
+ echo -ne '\a\n'
+ echo "QA Notice: the following files contain executable stacks"
+ echo " Files with executable stacks will not work properly (or at all!)"
+ echo " on some architectures/operating systems. A bug should be filed"
+ echo " at http://bugs.gentoo.org/ to make sure the file is fixed."
+ echo "${f}"
+ echo -ne '\a\n'
+ __feature_is_enabled stricter && die "Aborting due to +x stack"
+ sleep 1
+ fi
+
+ # Create NEEDED and NEEDED.ELF.2 files required for things like preserve-libs
+ # TODO: someday find a way to move this to the triggers implementation to allow
+ # for parallelization of the scanning- if useful.
+ scanelf -qyRF '%a;%p;%S;%r;%n' "${ED}" | { while IFS= read -r l; do
+ arch=${l%%;*}; l=${l#*;}
+ obj="/${l%%;*}"; l=${l#*;}
+ soname=${l%%;*}; l=${l#*;}
+ rpath=${l%%;*}; l=${l#*;}; [[ ${rpath} == " - " ]] && rpath=""
+ needed=${l%%;*}; l=${l#*;}
+ echo "${obj} ${needed}" >> "${T}"/NEEDED
+ echo "${arch:3};${obj};${soname};${rpath};${needed}" >> "${T}"/NEEDED.ELF.2
+ done }
+ fi
+}
+
+__dyn_pkg_preinst() {
+ if __is_function pkg_preinst; then
+ __qa_invoke pkg_preinst
+ else
+ __qa_run_function_if_exists __phase_pkg_preinst
+ fi
+
+ ${PKGCORE_PREFIX_SUPPORT} || local ED=${D}
+
+ # total suid control.
+ if __feature_is_enabled suidctl > /dev/null; then
+ sfconf=/etc/portage/suidctl.conf
+ echo ">>> Performing suid scan in ${ED}"
+ local i
+ for i in $(find "${ED}" -type f \( -perm -4000 -o -perm -2000 \) ); do
+ if [[ -s ${sfconf} ]]; then
+ suid=$(grep ^${i/${ED}/}$ "${sfconf}")
+ if [[ ${suid} == ${i/${ED}/} ]]; then
+ echo "- ${i/${ED}/} is an approved suid file"
+ else
+ echo ">>> Removing sbit on non registered ${i/${ED}/}"
+ chmod ugo-s "${i}"
+ grep ^#${i/${ED}/}$ ${sfconf} > /dev/null || {
+ # sandbox prevents us from writing directly
+ # to files outside of the sandbox, but this
+ # can easly be bypassed using the addwrite() function
+ addwrite "${sfconf}"
+ echo ">>> Appending commented out entry to ${sfconf} for ${PF}"
+ ls_ret=$(ls -ldh "${i}")
+ echo "## ${ls_ret%${ED}*}${ls_ret#*${ED}}" >> "${sfconf}"
+ echo "#${i/${ED}/}" >> "${sfconf}"
+ # no delwrite() eh?
+ # delwrite ${sconf}
+ }
+ fi
+ else
+ echo "suidctl feature set but you are lacking a ${sfconf}"
+ fi
+ done
+ fi
+
+ # SELinux file labeling (needs to always be last in dyn_preinst)
+ if __feature_is_enabled selinux; then
+ # only attempt to label if setfiles is executable
+ # and 'context' is available on selinuxfs.
+ if [[ -f /selinux/context && -x /usr/sbin/setfiles ]]; then
+ echo ">>> Setting SELinux security labels"
+ if [[ -f ${POLICYDIR}/file_contexts/file_contexts ]]; then
+ cp -f "${POLICYDIR}"/file_contexts/file_contexts "${T}"
+ else
+ make -C "${POLICYDIR}" FC=${T}/file_contexts "${T}"/file_contexts
+ fi
+
+ addwrite /selinux/context
+ /usr/sbin/setfiles -r "${ED}" "${T}"/file_contexts "${ED}" \
+ || die "failed to set SELinux security labels"
+ else
+ # nonfatal, since merging can happen outside a SE kernel
+ # like during a recovery situation
+ echo "!!! Unable to set SELinux security labels"
+ fi
+ fi
+}
+
+inherit() {
+ [[ -z $@ ]] && die "${FUNCNAME}: missing eclass argument"
+ local INHERIT_DEPTH=$(( ${INHERIT_DEPTH-0} + 1 ))
+
+ if [[ ${INHERIT_DEPTH} -gt 1 ]]; then
+ debug-print "*** Multiple Inheritance (level: ${INHERIT_DEPTH})"
+ fi
+
+ local location olocation
+ local ECLASS
+
+ # note that this ensures any later unsets/mangling, the ebuilds original
+ # setting is protected.
+ local IUSE REQUIRED_USE DEPEND RDEPEND PDEPEND BDEPEND IDEPEND
+ if ${PKGCORE_ACCUMULATE_PROPERTIES_RESTRICT}; then
+ local PROPERTIES RESTRICT
+ fi
+
+ # keep track of direct ebuild inherits
+ [[ ${INHERIT_DEPTH} -eq 1 ]] && INHERIT+=" $@"
+
+ for ECLASS in "$@"; do
+ if [[ ${EBUILD_PHASE} != "depend" ]]; then
+ if ! __safe_has "${ECLASS}" ${INHERITED}; then
+ echo
+ echo "QA Notice: ECLASS '${ECLASS}' illegal conditional inherit in ${CATEGORY}/${PF}" >&2
+ echo
+ fi
+ fi
+
+ unset -v IUSE REQUIRED_USE DEPEND RDEPEND PDEPEND BDEPEND IDEPEND
+ if ${PKGCORE_ACCUMULATE_PROPERTIES_RESTRICT}; then
+ unset -v PROPERTIES RESTRICT
+ fi
+
+ __internal_inherit "$1" || die "${FUNCNAME}: failed sourcing $1"
+
+ # If each var has a value, append it to the global variable E_* to
+ # be applied after everything is finished. New incremental behavior.
+ [[ -n ${IUSE} ]] && E_IUSE+=${E_IUSE:+ }${IUSE}
+ [[ -n ${REQUIRED_USE} ]] && E_REQUIRED_USE+=${E_REQUIRED_USE:+ }${REQUIRED_USE}
+ [[ -n ${DEPEND} ]] && E_DEPEND+=${E_DEPEND:+ }${DEPEND}
+ [[ -n ${RDEPEND} ]] && E_RDEPEND+=${E_RDEPEND:+ }${RDEPEND}
+ [[ -n ${PDEPEND} ]] && E_PDEPEND+=${E_PDEPEND:+ }${PDEPEND}
+ [[ -n ${BDEPEND} ]] && E_BDEPEND+=${E_BDEPEND:+ }${BDEPEND}
+ [[ -n ${IDEPEND} ]] && E_IDEPEND+=${E_IDEPEND:+ }${IDEPEND}
+ if ${PKGCORE_ACCUMULATE_PROPERTIES_RESTRICT}; then
+ [[ -n ${PROPERTIES} ]] && E_PROPERTIES+=${E_PROPERTIES:+ }${PROPERTIES}
+ [[ -n ${RESTRICT} ]] && E_RESTRICT+=${E_RESTRICT:+ }${RESTRICT}
+ fi
+
+ # while other PMs have checks to keep this unique, we don't; no need,
+ # further up the stack (python side) we uniquify this.
+ # if you try to do it in bash rather than python, it's ~10% slower regen
+ INHERITED+=" ${ECLASS}"
+
+ shift
+ done
+}
+
+# Exports stub functions that call the eclass's functions, thereby making them default.
+# For example, if ECLASS="base" and you call "EXPORT_FUNCTIONS src_unpack", the following
+# code will be eval'd:
+# src_unpack() { base_src_unpack; }
+EXPORT_FUNCTIONS() {
+ if [[ -z ${ECLASS} ]]; then
+ die "EXPORT_FUNCTIONS without a defined ECLASS"
+ fi
+ local phase_func
+ for phase_func in $*; do
+ debug-print "EXPORT_FUNCTIONS: ${phase_func} -> ${ECLASS}_${phase_func}"
+ eval "${phase_func}() { ${ECLASS}_${phase_func} "\$@" ; }" > /dev/null
+ done
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/ebuild-env-utils.bash b/data/lib/pkgcore/ebd/ebuild-env-utils.bash
new file mode 100644
index 000000000..04e99c3c3
--- /dev/null
+++ b/data/lib/pkgcore/ebd/ebuild-env-utils.bash
@@ -0,0 +1,136 @@
+# this functionality is all related to saving/loading environmental dumps for ebuilds
+
+__regex_filter_input() {
+ # We don't need to reset IFS in this context, thus skip the pop.
+ local IFS='|'
+ local regex="^(${*})$"
+ # use egrep if possible... tis faster.
+ local l ret=0
+ if l=$(type -P gsed || type -P sed); then
+ "${l}" -re "/${regex}/d"
+ ret=$?
+ [[ ${ret} != 0 ]] && die "got failing return code (${ret}) invoking ${l} -e '/${regex}/d'"
+ elif l=$(type -P egrep); then
+ # use type -p; qa_interceptors may be active.
+ "${l}" -v "${regex}"
+ ret=$?
+ # return status is 1 for no matches and 2 for errors
+ [[ ${ret} -gt 1 ]] && die "got failing return code (${ret}) ${l} -v '${regex}'"
+ ret=0 # reset the return status if there are no matches, it isn't an error
+ else
+ while read l; do
+ [[ ${l} =~ ${regex} ]] || echo "${l}"
+ done
+ fi
+ return ${ret}
+}
+
+__escape_regex_array() {
+ local __tmp_array
+ # Need to get the content of the original array...
+ eval "__tmp_array=( \"\${$1[@]}\" )"
+ __tmp_array=( "${__tmp_array[@]//\+/\\+}" )
+ __tmp_array=( "${__tmp_array[@]//\./\\.}" )
+ __tmp_array=( "${__tmp_array[@]//\*/\\*}" )
+ # Now transfer the content back.
+ eval $1='( "${__tmp_array[@]}" )'
+} &> /dev/null
+
+__filter_env() {
+ local opts
+ [[ ${PKGCORE_DEBUG} -ge 1 ]] && opts="--debug"
+ __ebd_ipc_cmd "filter_env" "${opts}" "$@"
+}
+
+# selectively saves the environ- specifically removes things that have been marked to not be exported.
+# dump the environ to stdout.
+__environ_dump() {
+ __shopt_push -f
+
+ # dump variables first so no local variables get picked up
+ local exported_vars=( $(compgen -v | __regex_filter_input ${PKGCORE_BLACKLIST_VARS[@]}) )
+ if [[ ${#exported_vars[@]} -ne 0 ]]; then
+ declare -p "${exported_vars[@]}" || die "failed outputting env vars ${exported_vars[@]}"
+ fi
+
+ local func_filters=( "${PKGCORE_BLACKLIST_FUNCS[@]}" ${PKGCORE_EAPI_FUNCS} "${PKGCORE_PRELOADED_ECLASSES[@]}" )
+
+ # Punt any regex chars...
+ __escape_regex_array func_filters
+ local exported_funcs=( $(compgen -A function | __regex_filter_input "${func_filters[@]}" ) )
+ if [[ ${#exported_funcs[@]} -ne 0 ]]; then
+ declare -f "${exported_funcs[@]}" || die "failed outputting funcs ${exported_funcs[@]}"
+ fi
+
+ __shopt_pop
+}
+
+# dump environ to $1, optionally piping it through $2 and redirecting $2's output to $1.
+__environ_save_to_file() {
+ if [[ $# -ne 1 && $# -ne 2 ]]; then
+ die "${FUNCNAME}: requires at least one argument, two max; got $@"
+ fi
+
+ if [[ $# -eq 1 ]]; then
+ __environ_dump > "$1"
+ else
+ __environ_dump | $2 > "$1"
+ fi
+ chown portage:portage "$1" &> /dev/null
+ chmod 0664 "$1" &> /dev/null
+}
+
+# reload a saved env, applying usual filters to the env prior to eval'ing it.
+__environ_sanitize_saved_env() {
+ if [[ $# -ne 1 ]]; then
+ die "scrub_environ called with wrong args, only one can be given: $@"
+ fi
+
+ [[ ! -f $1 ]] && die "${FUNCNAME}: called with a nonexist env: $1"
+
+ # here's how this goes; we do an eval'd loadup of the target env w/in a subshell..
+ # declares and such will slide past filter-env (so it goes). we then use our own
+ # __environ_dump from within to get a clean dump from that env, and load it into
+ # the parent eval.
+ (
+ # protect the core vars and functions needed to do a __environ_dump
+ # some of these are already readonly- we still are forcing it to be safe.
+ readonly PKGCORE_EXISTING_PATH SANDBOX_ON T
+ readonly -a PKGCORE_BLACKLIST_VARS PKGCORE_BLACKLIST_FUNCS
+ readonly -f __filter_env __environ_dump __regex_filter_input
+
+ __shopt_push -f
+ IFS=$' \t\n'
+ declare -a PKGCORE_FUNC_ARRAY=( "${PKGCORE_BLACKLIST_FUNCS[@]}" )
+ declare -a PKGCORE_VAR_ARRAY=( "${PKGCORE_BLACKLIST_VARS[@]}" )
+ IFS=,
+ PKGCORE_FUNC_ARRAY=${PKGCORE_FUNC_ARRAY[*]}
+ PKGCORE_VAR_ARRAY=${PKGCORE_VAR_ARRAY[*]}
+ IFS=$' \t\n'
+ __shopt_pop
+
+ rm -f "${T}"/.pre-scrubbed-env || die "failed rm'ing"
+ # run the filtered env.
+ __filter_env \
+ --funcs "${PKGCORE_FUNC_ARRAY}" \
+ --vars "${PKGCORE_VAR_ARRAY}" \
+ "$1" "${T}"/.pre-scrubbed-env \
+ || die "failed first step of scrubbing the env to load"
+
+ [[ -s ${T}/.pre-scrubbed-env ]] || die "empty pre-scrubbed-env file, pkgcore bug?"
+ source "${T}"/.pre-scrubbed-env >&2 || die "failed sourcing scrubbed env"
+
+ # ok. it's loaded into this subshell... now we use our dump mechanism (which we trust)
+ # to output it- this mechanism is far more bulletproof then the load filtering (since
+ # declare and friends can set vars via many, many different ways), thus we use it
+ # as the final filtering.
+ rm -f "${T}"/.scrubbed-env
+ __environ_dump > "${T}"/.scrubbed-env || die "dumping environment failed"
+ ) && return
+
+ echo "die 'failed parsing the env dump'" # yep, we're injecting code into the eval.
+ exit 1
+ # note no die usage here... exit instead, since we don't want another tb thrown
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/ebuild.bash b/data/lib/pkgcore/ebd/ebuild.bash
new file mode 100644
index 000000000..9bcabd48d
--- /dev/null
+++ b/data/lib/pkgcore/ebd/ebuild.bash
@@ -0,0 +1,531 @@
+# ebuild phase processing, env handling
+
+# general phase execution path- __execute_phases is called, which sets EBUILD_PHASE, and then
+# depending on the phase, loads or initializes. Env is init'd for non src based stages if the env
+# isn't found- otherwise it loads the environ via __load_environ call. In cases where env isn't
+# found for phases setup -> merge, it bails (theres no way the env should be missing- exemption is
+# setup phase).
+#
+# for env filtering for restoration and reloading, note the updates to PKGCORE_BLACKLIST_(VARS|FUNCS).
+# those vars are basically used to track what shouldn't be saved/restored. Whitespace separated,
+# those vars can support posix (think egrep) regex. They should hold all vars/funcs that are
+# internal ebd vars. Basically, filter all vars/funcs that are specific to ebd, not the ebuild.
+#
+# after loading the env, user defined pre hooks are executed, __dyn_${EBUILD_PHASE} is executed, and
+# the post hooks are executed. If the env needs to be flushed to disk, PKGCORE_MUST_EXPORT_ENV is
+# set to "yes", and __execute_phases will dump it to ${T}/environment.
+#
+# few notes on general env stuff- if it's not ebuild specific or a user option, it's typically
+# marked readonly. This limits users, but also helps to ensure that reloaded envs from older
+# portages don't overwrite an internal ebd.sh function that has since changed.
+
+PKGCORE_BLACKLIST_VARS=(
+ # bash-related
+ $(compgen -v) "BASH_.*" COLUMNS OLDPWD
+
+ # external programs
+ "SANDBOX_.*" "CCACHE.*" "DISTCC.*" "SUDO_.*"
+
+ # internals
+ "___.*" "PKGCORE_.*" ret
+
+ # portage-compat
+ "PORTAGE_.*" "EMERGE_.*" FEATURES EMERGE_FROM
+ "RSYNC_.*" GENTOO_MIRRORS
+ "(DIST|FILES|RPM|ECLASS)DIR"
+ "ACCEPT_(PROPERTIES|RESTRICT)"
+ "(RESUME|FETCH)COMMAND(_.*)?" XARGS SYNC DIR
+ "ACCEPT_(KEYWORDS|LICENSE)"
+ "PORT(_LOGDIR|DIR(_OVERLAY)?)" "PROFILE_.*" ECLASS TMP
+
+ # PMS
+ CATEGORY PF P PN PV PR PVR EBUILD A EBUILD_PHASE
+ T WORKDIR D ED ROOT EROOT EPREFIX HOME "USE_EXPAND_.*"
+ MERGE_TYPE REPLACING_VERSIONS REPLACED_BY_VERSION
+)
+
+if [[ -z ${PKGCORE_EBD_PATH} ]]; then
+ echo "PKGCORE_EBD_PATH is unset!"
+ exit 1
+fi
+
+# knock the sandbox vars back to the pkgs defaults.
+__reset_sandbox() {
+ export SANDBOX_ON=1
+ export SANDBOX_PREDICT=${SANDBOX_PREDICT:+${SANDBOX_PREDICT}:}/proc/self/maps:/dev/console:/dev/random:${PORTAGE_TMPDIR}
+ export SANDBOX_WRITE=${SANDBOX_WRITE:+${SANDBOX_WRITE}:}/dev/shm:${PORTAGE_TMPDIR}
+ export SANDBOX_READ=${SANDBOX_READ:+${SANDBOX_READ}:}/dev/shm:${PORTAGE_TMPDIR}
+ local var
+ for var in CCACHE_DIR DISTCC_DIR D WORKDIR T; do
+ if [[ -n ${!var} ]]; then
+ addread "${!var}"
+ addwrite "${!var}"
+ fi
+ done
+}
+
+# Prevent aliases from causing portage to act inappropriately.
+# Make sure it's before everything so we don't mess aliases that follow.
+unalias -a
+
+# This is needed for calling __load_environ, __load_safe_environ, and
+# __init_environ. If those can ever be moved into functions this can be
+# dropped.
+shopt -s expand_aliases
+
+# Unset some variables that break things.
+unset -v GZIP BZIP BZIP2 CDPATH GREP_OPTIONS GREP_COLOR GLOB_IGNORE
+
+# gentoo bug 309369; nasty alias, but it exists due to portage using declare's
+# in env dumping. declare statements are implicitly local. as such, the
+# sourcing statement has to be in the same scope as the invoker of
+# __load_environ for that scope to get the changes
+alias __load_environ='{
+ [[ -z ${PKGCORE_TARGET_ENV} ]] && die "__load_environ was invoked w/out PKGCORE_TARGET_ENV set";
+ [[ -z ${T} ]] && die "__load_environ requires \$T to be set";
+ PKGCORE_EXISTING_PATH=${PATH};
+ __timed_call __environ_sanitize_saved_env "${PKGCORE_TARGET_ENV}"
+ if [[ -n ${PKGCORE_PERF_DEBUG} ]]; then
+ echo "timing source ${PKGCORE_TARGET_ENV}" >&2
+ time source "${PKGCORE_TARGET_ENV}" >&2
+ echo "timed source ${PKGCORE_TARGET_ENV}" >&2
+ else
+ source "${PKGCORE_TARGET_ENV}" >&2
+ fi
+ [[ $? == 0 ]] || die "sourcing saved env failed";
+ __ensure_PATH "${PKGCORE_EXISTING_PATH}";
+ __timed_call __load_eapi_libs
+ __timed_call __source_bashrcs
+ unset -v PKGCORE_EXISTING_PATH;
+}'
+
+# Invoke this when we know that this version of pkgcore generated the env dump;
+# this bypasses the safeties in loading.
+alias __load_safe_environ='{
+ [[ -z ${PKGCORE_TARGET_ENV} ]] && die "__load_safe_environ was invoked w/out PKGCORE_TARGET_ENV set";
+ [[ -z ${T} ]] && die "__load_safe_environ requires \$T to be set";
+ PKGCORE_EXISTING_PATH=${PATH};
+ if [[ -n ${PKGCORE_PERF_DEBUG} ]]; then
+ echo "timing source ${PKGCORE_TARGET_ENV}" >&2
+ time source "${PKGCORE_TARGET_ENV}" >&2
+ echo "timed source ${PKGCORE_TARGET_ENV}" >&2
+ else
+ source "${PKGCORE_TARGET_ENV}" >&2
+ fi
+ [[ $? == 0 ]] || die "sourcing saved env failed";
+ __ensure_PATH "${PKGCORE_EXISTING_PATH}";
+ __timed_call __load_eapi_libs
+ __timed_call __source_bashrcs
+ unset -v PKGCORE_EXISTING_PATH;
+}'
+
+alias __init_environ='{
+ PKGCORE_EXISTING_PATH=${PATH};
+ __timed_call __load_eapi_libs
+ if [[ -n ${PKGCORE_PERF_DEBUG} ]]; then
+ echo "timing eval \$(__generate_initial_ebuild_environ)" >&2
+ time eval "$(__timed_call __generate_initial_ebuild_environ)" >&2
+ echo "timed eval \$(__generate_initial_ebuild_environ)" >&2
+ else
+ eval "$(__generate_initial_ebuild_environ)"
+ fi
+ [[ $? == 0 ]] || die "failed loading initialized environment";
+ __ensure_PATH "${PKGCORE_EXISTING_PATH}";
+ __timed_call __source_bashrcs
+ unset -v PKGCORE_EXISTING_PATH;
+}'
+
+shopt -s extdebug &> /dev/null
+
+# if no perms are specified, dirs/files will have decent defaults
+# (not secretive, but not stupid)
+umask 022
+
+# the sandbox is disabled by default except when overridden in the relevant stages
+export SANDBOX_ON=0
+
+# Used to track if we're subshelled w/in the main ebd instance, or if we're in
+# a literal child process.
+PKGCORE_IS_NOT_HELPER=1
+
+# ensure the passed in PATH has its components in $PATH and that they aren't
+# overridden by new entries
+__ensure_PATH() {
+ local existing_path=$1
+ local adds
+ # note this isolates the adds in the same order they appear in
+ # the passed in path, maintaining that order.
+ if [[ ${existing_path} != ${PATH} ]]; then
+ local IFS=:
+ local p
+ for p in ${existing_path}; do
+ # keep in mind PATH=":foon" is a valid way to say "cwd"
+ [[ -z ${p} ]] && continue
+ if ! __safe_has "${p}" ${PATH} && ! __safe_has "${p}" ${adds}; then
+ adds=${adds:+${adds}:}${p}
+ fi
+ done
+ [[ -n ${adds} ]] && PATH=${adds}${PATH:+:${PATH}}
+ fi
+ export PATH
+}
+
+__load_eapi_libs() {
+ # reload depend; while it may've been loaded already, reload it so that callers can
+ # rely on this setting the env up as necessary
+ # finally, update the filters with functionality loaded from here-
+ # always, always, *always* use our own functionality
+ source "${PKGCORE_EBD_PATH}"/eapi/common.bash \
+ || die "failed sourcing eapi/common.bash"
+
+ # load global scope EAPI functions
+ source "${PKGCORE_EBD_PATH}"/.generated/libs/${EAPI}/global \
+ || die "failed sourcing EAPI ${EAPI} global scope lib"
+}
+
+# do all profile, bashrc's, and ebuild sourcing. Should only be called in setup phase, unless the
+# env is *completely* missing, as it is occasionally for ebuilds during prerm/postrm.
+__generate_initial_ebuild_environ() {
+ local ORIG_CC=${CC}
+ local ORIG_CXX=${CXX}
+ local PKGCORE_EXISTING_PATH=${PATH}
+ local T=${T}
+
+ if [[ ${EBUILD_PHASE} == "setup" ]]; then
+ # we specifically save the env so it's not stomped on by sourcing.
+ # bug 51552
+ __timed_call __environ_save_to_file "${T}"/.temp_env
+
+ # restore the saved env vars.
+ PKGCORE_SUPPRESS_BASHRCS=true
+ PKGCORE_TARGET_ENV=${T}/.temp_env
+ if ! __load_environ; then
+ # this shouldn't happen.
+ die "failed to load '${T}/.temp_env' -- fs is readonly?"
+ fi
+ unset -v PKGCORE_SUPPRESS_BASHRCS
+
+ rm "${T}"/.temp_env
+ fi
+
+ [[ -n ${EBUILD} ]] && __timed_call __load_ebuild "${EBUILD}"
+
+ if [[ ${EBUILD_PHASE} != "depend" ]]; then
+ RESTRICT=${PKGCORE_FINALIZED_RESTRICT}
+ unset -v PKGCORE_FINALIZED_RESTRICT
+ unset -v CC CXX
+ [[ -n ${ORIG_CC} ]] && export CC=${ORIG_CC}
+ [[ -n ${ORIG_CXX} ]] && export CXX=${ORIG_CXX}
+ unset -v ORIG_CC ORIG_CXX
+ fi
+
+ __ensure_PATH "${PKGCORE_EXISTING_PATH}"
+ if [[ -n ${T} && ${EBUILD_PHASE} != "pretend" ]]; then
+ # Use a file if possible; faster since bash does this lovely byte by
+ # byte reading if it's a pipe. Having the file around is useful for
+ # debugging also.
+ __timed_call __environ_save_to_file "${T}"/.initial_environ || die "failed dumping env to '${T}/.initial_environ'"
+ echo "source \"${T}\"/.initial_environ"
+ else
+ __timed_call __environ_dump || die "failed dumping env"
+ fi
+}
+
+# Set up the bash version compatibility level. This does not disable features
+# when running with a newer version, but makes it so that when bash changes
+# behavior in an incompatible way, the older behavior is used instead.
+__export_bash_compat() {
+ [[ -z ${PKGCORE_BASH_COMPAT} ]] && die "PKGCORE_BASH_COMPAT isn't set!"
+
+ # Set compat level only for the ebuild environment, this won't affect
+ # external shell scripts.
+ __var_push -n BASH_COMPAT=${PKGCORE_BASH_COMPAT}
+
+ # BASH_COMPAT was introduced in bash-4.3, for older versions a compat
+ # option must be used.
+ if [[ ${PKGCORE_BASH_COMPAT} == "3.2" && ${BASH_VERSINFO[0]} -gt 3 ]]; then
+ __shopt_push -s compat32
+ fi
+
+ # Explicitly set shell option (it's automatically enabled by setting
+ # BASH_COMPAT) so it gets properly disabled once leaving scope. Otherwise,
+ # __qa_invoke() can throw warnings when the compat42 option enabled
+ # internally by bash bleeds out of scope which seems to be caused when
+ # ebuilds or eclasses alter shopt options.
+ [[ ${PKGCORE_BASH_COMPAT} == "4.2" ]] && __shopt_push -s compat42
+}
+
+__load_ebuild() {
+ local EBUILD=$1
+ [[ -f ${EBUILD} ]] || die "nonexistent ebuild: '${EBUILD}'"
+ shift
+
+ SANDBOX_ON=1
+ export S=${WORKDIR}/${P}
+
+ unset -v IUSE REQUIRED_USE DEPEND RDEPEND PDEPEND BDEPEND IDEPEND
+ local E_IUSE E_REQUIRED_USE E_DEPEND E_RDEPEND E_PDEPEND E_BDEPEND E_IDEPEND
+ if ${PKGCORE_ACCUMULATE_PROPERTIES_RESTRICT}; then
+ unset -v PROPERTIES RESTRICT
+ local E_PROPERTIES E_RESTRICT
+ fi
+
+ __env_push
+ __export_bash_compat
+
+ # EAPI 6 and up raise expansion errors on failed globbing in global scope.
+ ${PKGCORE_GLOBAL_FAILGLOB} && __shopt_push -s failglob
+
+ __qa_invoke source "${EBUILD}"
+ if [[ $? != 0 ]]; then
+ # rerun source in a subshell to capture stderr
+ local error_msg="error sourcing ebuild"
+ local source_err=$(__qa_invoke source "${EBUILD}" 2>&1)
+ [[ -n ${source_err} ]] && error_msg+="\n\n${source_err}"
+ die "${error_msg}"
+ fi
+
+ __env_pop
+
+ # a reasonable default for $S
+ if [[ -z ${S} ]]; then
+ export S=${WORKDIR}/${P}
+ fi
+
+ # Note that this is not the same as `export RDEPEND=${RDEPEND:-${DEPEND}}`
+ # That will test for unset *or* NULL (""), we want just to set if unset.
+ if __safe_has "${EAPI}" 0 1 2 3; then
+ if [[ ${RDEPEND-unset} == "unset" ]]; then
+ export RDEPEND=${DEPEND}
+ fi
+ fi
+
+ # add in dependency info from eclasses
+ IUSE+=${IUSE:+ }${E_IUSE}
+ REQUIRED_USE+=${REQUIRED_USE:+ }${E_REQUIRED_USE}
+ DEPEND+=${DEPEND:+ }${E_DEPEND}
+ RDEPEND+=${RDEPEND:+ }${E_RDEPEND}
+ PDEPEND+=${PDEPEND:+ }${E_PDEPEND}
+ BDEPEND+=${BDEPEND:+ }${E_BDEPEND}
+ IDEPEND+=${IDEPEND:+ }${E_IDEPEND}
+ if ${PKGCORE_ACCUMULATE_PROPERTIES_RESTRICT}; then
+ PROPERTIES+=${PROPERTIES:+ }${E_PROPERTIES}
+ RESTRICT+=${RESTRICT:+ }${E_RESTRICT}
+ fi
+}
+
+# short version. think these should be sourced via at the daemon's choice, rather then defacto.
+# note that exit-handling loads the die functions, thus the custom failure there.
+source "${PKGCORE_EBD_PATH}"/exit-handling.bash >&2 || { echo "ERROR: failed sourcing exit-handling.bash"; exit -1; }
+source "${PKGCORE_EBD_PATH}"/ebuild-default-functions.bash >&2 || die "failed sourcing ebuild-default-functions.bash"
+source "${PKGCORE_EBD_PATH}"/ebuild-env-utils.bash >&2 || die "failed sourcing ebuild-env-utils.bash"
+
+__run_ebuild_phase() {
+ [[ ${PKGCORE_DEBUG} -ge 2 ]] && set -x
+
+ # some users have $TMP/$TMPDIR to a custom dir in their home ...
+ # this will cause sandbox errors with some ./configure
+ # scripts, so set it to $T.
+ local -x TMP=${T}
+ local -x TMPDIR=${T}
+
+ __env_push
+ __export_bash_compat
+ ${PKGCORE_EBUILD_PHASE_FUNC} && __var_push -n EBUILD_PHASE_FUNC=$1
+
+ # die when encountering unknown commands
+ command_not_found_handle() {
+ local msg="${EBUILD_PHASE_FUNC}(): unknown command '$1'"
+ [[ $# -gt 1 ]] && msg+=" when executing: '$*'"
+ if ${PKGCORE_NONFATAL}; then
+ eerror "${msg}"
+ return 1
+ fi
+ die "${msg}"
+ }
+
+ # load phase scope EAPI functions
+ source "${PKGCORE_EBD_PATH}"/.generated/libs/${EAPI}/$1 \
+ || die "failed sourcing EAPI ${EAPI} $1 phase scope lib"
+
+ cd "${PKGCORE_EMPTYDIR}" || die "unable to cd into ${PKGCORE_EMPTYDIR}"
+ __qa_run_function_if_exists __phase_pre_$1
+ __qa_run_function_if_exists pre_$1
+
+ if __is_function __dyn_$1; then
+ __dyn_$1
+ elif __is_function $1; then
+ __qa_invoke $1
+ else
+ __qa_run_function_if_exists __phase_$1
+ fi
+
+ __qa_run_function_if_exists post_$1
+ __qa_run_function_if_exists __phase_post_$1
+
+ __env_pop
+
+ # don't leak func to exported env
+ unset -f command_not_found_handle
+
+ [[ ${PKGCORE_DEBUG} -lt 4 ]] && set +x
+}
+
+# general func to call for phase execution. this handles necessary env
+# loading/dumping, and executing pre/post/dyn calls.
+__execute_phases() {
+ local PKGCORE_DIE_OUTPUT_DETAILS PKGCORE_SUPPRESS_BASHRCS
+ local PKGCORE_SAVE_ENV PKGCORE_TARGET_ENV PKGCORE_MUST_EXPORT_ENV=false
+
+ # give us pretty tracebacks.
+ shopt -s extdebug
+
+ trap "exit 2" SIGINT
+ trap "exit 9" SIGQUIT
+ trap "exit 1" SIGTERM
+ declare -rx PKGCORE_EBUILD_PROCESS_PID=${BASHPID}
+
+ local ret
+ for EBUILD_PHASE in $*; do
+ PKGCORE_SAVE_ENV=true
+ PKGCORE_DIE_OUTPUT_DETAILS=true
+ PKGCORE_SUPPRESS_BASHRCS=false
+
+ case ${EBUILD_PHASE} in
+ nofetch|pretend)
+ PKGCORE_SUPPRESS_BASHRCS=true
+ __init_environ
+
+ PKGCORE_DIE_OUTPUT_DETAILS=false
+ __run_ebuild_phase pkg_${EBUILD_PHASE}
+ PKGCORE_SAVE_ENV=false
+ ret=0
+ ;;
+ prerm|postrm|preinst|postinst|config)
+ [[ ${EBUILD_PHASE} == postrm ]] && PKGCORE_SAVE_ENV=false
+ export SANDBOX_ON=0
+
+ PKGCORE_TARGET_ENV=${T}/environment
+ __load_environ || die "failed loading env during ${EBUILD_PHASE} phase"
+
+ __run_ebuild_phase pkg_${EBUILD_PHASE}
+ ret=0
+ ;;
+ unpack|prepare|configure|compile|test|install)
+ if [[ ${SANDBOX_DISABLED=0} == 0 ]]; then
+ export SANDBOX_ON=1
+ else
+ export SANDBOX_ON=0
+ fi
+
+ [[ ${PKGCORE_DEBUG} -ge 3 ]] && set -x
+ PKGCORE_TARGET_ENV=${T}/environment
+ __load_safe_environ || die "failed loading env during ${EBUILD_PHASE} phase"
+ [[ -z ${S} ]] && die "\$S was null, path=${PATH}"
+
+ __run_ebuild_phase src_${EBUILD_PHASE}
+ ret=0
+ ;;
+ setup|setup-binpkg)
+ EBUILD_PHASE="setup"
+
+ # binpkgs don't need to reinitialize the env.
+ if [[ ${EBUILD_PHASE} == "setup" ]]; then
+ [[ -n ${DISTCC_LOG} ]] && addwrite "$(dirname ${DISTCC_LOG})"
+
+ if __feature_is_enabled ccache; then
+ export CCACHE_DIR
+ [[ -n ${CCACHE_SIZE} ]] && ccache -M ${CCACHE_SIZE} &> /dev/null
+ fi
+
+ [[ ${PKGCORE_DEBUG} -ge 2 ]] && set -x
+ __init_environ
+ else
+ PKGCORE_TARGET_ENV=${T}/environment
+ __load_environ || die "failed loading env during ${EBUILD_PHASE} phase"
+ fi
+
+ # pkg_setup needs to be run outside the sandbox for tmp file
+ # creation; for example, awking and piping a file in /tmp
+ # requires a temp file to be created in /etc. If pkg_setup is
+ # in the sandbox, both our lilo and apache ebuilds break.
+ export SANDBOX_ON=0
+
+ __run_ebuild_phase pkg_${EBUILD_PHASE}
+ ret=0;
+ ;;
+ depend|generate_env)
+ SANDBOX_ON=1
+ PKGCORE_SAVE_ENV=false
+
+ PKGCORE_DIE_OUTPUT_DETAILS=false
+
+ __timed_call __load_eapi_libs
+ __load_ebuild "${EBUILD}"
+
+ if [[ ${EBUILD_PHASE} == depend ]]; then
+ __dump_metadata_keys
+ else
+ # Use gawk if at possible; it's a fair bit faster since
+ # bash likes to do byte by byte reading.
+ local __path
+ __path=$(PATH=/usr/bin:/bin type -P gawk)
+ if [[ $? == 0 ]]; then
+ { unset -v __path; __environ_dump; } | \
+ LC_ALL=C "${__path}" -F $'\0' 'BEGIN { content="";chars=0;RS="\0";ORS=""} {chars += length($0);content = content $0} END {printf("receive_env %i\n%s",chars, content)}' >&${PKGCORE_EBD_WRITE_FD}
+ else
+ local my_env=$(__environ_dump)
+ __ebd_write_line "receive_env ${#my_env}"
+ __ebd_write_raw "${my_env}"
+ unset -v my_env __path
+ fi
+ fi
+ ;;
+ *)
+ die "invalid command: ${EBUILD_PHASE}"
+ ;;
+ esac
+
+ ${PKGCORE_SAVE_ENV} && PKGCORE_MUST_EXPORT_ENV=true
+ [[ ${PKGCORE_DEBUG} -lt 4 ]] && set +x
+ done
+
+ if ${PKGCORE_MUST_EXPORT_ENV}; then
+ __timed_call __environ_save_to_file "${T}"/environment
+ fi
+ return ${ret:-0}
+}
+
+__dump_metadata_keys() {
+ # note this function does /not/ use shopt pushing/popping; it should only
+ # be invoked after ebuild code has done it's thing, as such we no longer care,
+ # and directly screw w/ it for speed reasons- about 5% speedup in metadata regen.
+ set -f
+ local key phases phase
+ for key in "${PKGCORE_METADATA_KEYS[@]}"; do
+ if [[ ${key} == DEFINED_PHASES ]]; then
+ for phase in "${PKGCORE_EBUILD_PHASES[@]}"; do
+ __is_function "${phase}" && phases+=( ${phase} )
+ done
+ __ebd_write_line "key DEFINED_PHASES=${phases[@]:--}"
+ else
+ # deref the val, if it's not empty/unset, then spit a key command to EBD
+ # after using echo to normalize whitespace (specifically removal of newlines)
+ if [[ ${!key:-unset} != "unset" ]]; then
+ # note that we explicitly bypass the normal functions, and directly
+ # write to the FD. This is done since it's about 25% faster for our usage;
+ # if we used the functions, we'd have to subshell the 'echo ${!key}', which
+ # because of bash behaviour, means the content would be read byte by byte.
+ echo -n "key ${key}=" >&${PKGCORE_EBD_WRITE_FD}
+ echo ${!key} >&${PKGCORE_EBD_WRITE_FD}
+ fi
+ fi
+ done
+ set +f
+}
+
+set +f
+
+export XARGS
+set +H -h
+:
diff --git a/data/lib/pkgcore/ebd/exit-handling.bash b/data/lib/pkgcore/ebd/exit-handling.bash
new file mode 100644
index 000000000..cecbbab49
--- /dev/null
+++ b/data/lib/pkgcore/ebd/exit-handling.bash
@@ -0,0 +1,122 @@
+# Exit handling functions for the ebuild environment
+
+# Check whether any command in the most recently executed foreground pipe
+# returned non-zero and if so calls die passing along any given parameters.
+assert() {
+ local pipestatus=${PIPESTATUS[*]}
+ [[ -z ${pipestatus//[ 0]*/} ]] || die "$@ (pipestatus: ${pipestatus})"
+}
+
+# Abort the current build process (see PMS for details).
+die() {
+ set +x
+ # if we were signaled to die...
+ if [[ -n ${EBD_DISABLE_DIEFUNC} ]]; then
+ return
+ fi
+
+ if [[ ${PKGCORE_NONFATAL_DIE} && $1 == "-n" ]]; then
+ shift
+ if ${PKGCORE_NONFATAL}; then
+ [[ $# -gt 0 ]] && eerror "$*"
+ return 1
+ fi
+ fi
+
+ # Notify the python side we're dying so it should handle cleanup,
+ # this forces die() to work in subshell environments.
+ __ebd_write_line "dying ${PORTAGE_LOGFILE}"
+
+ # Send any error messages back to python for output.
+ exec 2>&${PKGCORE_EBD_WRITE_FD}
+
+ local n filespacing=0 linespacing=0 sourcefile lineno
+ # setup spacing to make output easier to read
+ for (( n = ${#FUNCNAME[@]} - 1 ; n >= 0 ; --n )); do
+ sourcefile=${BASH_SOURCE[${n}]} sourcefile=${sourcefile##*/}
+ lineno=${BASH_LINENO[${n}]}
+ (( filespacing < ${#sourcefile} )) && filespacing=${#sourcefile}
+ (( linespacing < ${#lineno} )) && linespacing=${#lineno}
+ done
+
+ local phase_str=
+ [[ -n ${EBUILD_PHASE} ]] && phase_str=" (${EBUILD_PHASE} phase)"
+ eerror "ERROR: ${CATEGORY}/${PF}::${PKGCORE_PKG_REPO} failed${phase_str}:"
+
+ # split error message by newline so every line gets prefixed properly
+ local line
+ echo -e "${@:-(no error message)}" | while IFS= read -r line; do
+ eerror " ${line}"
+ done
+
+ if [[ -n ${PKGCORE_IS_NOT_HELPER} ]]; then
+ eerror
+ __dump_trace 2 ${filespacing} ${linespacing} >&2
+ eerror " $(printf "%${filespacing}s" "${BASH_SOURCE[1]##*/}"), line $(printf "%${linespacing}s" "${BASH_LINENO[0]}"): called die"
+ fi
+ if ${PKGCORE_DIE_OUTPUT_DETAILS-true}; then
+ if [[ -n ${PKGCORE_IS_NOT_HELPER} ]]; then
+ eerror
+ eerror "If you need support, post the topmost build error, and the call stack if relevant."
+ fi
+ local hook
+ for hook in ${EBUILD_DEATH_HOOKS}; do
+ ${hook} >&2 1>&2
+ done
+ fi
+
+ local working_dir=$(pwd)
+ if [[ ${PKGCORE_EBD_PATH} != ${working_dir} ]]; then
+ eerror
+ eerror "Working directory: '${working_dir}'"
+ fi
+
+ __ebd_write_line "dead"
+ exit 1
+}
+
+# usage- first arg is the number of funcs on the stack to ignore.
+# defaults to 1 (ignoring __dump_trace)
+# whitespacing for filenames
+# whitespacing for line numbers
+__dump_trace() {
+ declare -i strip=${1:-1}
+ local filespacing=$2 linespacing=$3
+ local n p
+
+ (( n = ${#FUNCNAME[@]} - 1 ))
+ (( p = ${#BASH_ARGV[@]} ))
+ # Drop internals up to the __qa_invoke() call when debugging isn't enabled.
+ if [[ -z ${PKGCORE_DEBUG} ]]; then
+ while (( n > 0 )); do
+ [[ ${FUNCNAME[${n}]} == __qa_invoke ]] && break
+ (( p -= ${BASH_ARGC[${n} - 1]} ))
+ (( n-- ))
+ done
+ if (( n == 0 )); then
+ (( n = ${#FUNCNAME[@]} - 1 ))
+ (( p = ${#BASH_ARGV[@]} ))
+ fi
+ fi
+
+ eerror "Call stack:"
+ local funcname= sourcefile= lineno=
+ for (( n; n > ${strip}; n-- )); do
+ funcname=${FUNCNAME[${n} - 1]}
+ sourcefile=${BASH_SOURCE[${n}]##*/}
+ lineno=${BASH_LINENO[${n} - 1]}
+ # Display function arguments
+ local args= newargs=
+ local j
+ if [[ ${#BASH_ARGV[@]} -gt 0 ]]; then
+ for (( j = 0 ; j < ${BASH_ARGC[${n} - 1]} ; ++j )); do
+ newargs=${BASH_ARGV[$(( p - j - 1 ))]}
+ args="${args:+${args} }'${newargs}'"
+ done
+ (( p -= ${BASH_ARGC[${n} - 1]} ))
+ fi
+ eerror " $(printf "%${filespacing}s" "${sourcefile}"), line $(printf "%${linespacing}s" "${lineno}"): called ${funcname}${args:+ ${args}}"
+ done
+}
+
+:
diff --git a/data/lib/pkgcore/ebd/generate_eapi_cmd_list b/data/lib/pkgcore/ebd/generate_eapi_cmd_list
new file mode 100755
index 000000000..f8e49404c
--- /dev/null
+++ b/data/lib/pkgcore/ebd/generate_eapi_cmd_list
@@ -0,0 +1,79 @@
+#!/usr/bin/env bash
+#
+# Generate the list of banned or deprecated commands specific to an EAPI version.
+#
+# Outputs the list of banned commands for a given EAPI by default. The -b and
+# -d options can be used to output only the banned or deprecated commands,
+# respectively. The -o option limits command scanning to the single, specified
+# EAPI instead of cumulatively building up the command list from inherited
+# EAPIs.
+
+ONLY=false
+BANNED=false
+DEPRECATED=false
+INTERNAL=false
+
+while getopts "bdio" opt; do
+ case ${opt} in
+ b) BANNED=true ;;
+ d) DEPRECATED=true ;;
+ i) INTERNAL=true ;;
+ o) ONLY=true ;;
+ *) ;;
+ esac
+done
+
+# default to outputting banned list
+if ! ${BANNED} && ! ${DEPRECATED} && ! ${INTERNAL}; then
+ BANNED=true
+fi
+
+shift $((OPTIND-1))
+EAPI=${1:-0}
+${ONLY} && INITIAL_EAPI=${EAPI} || INITIAL_EAPI=0
+export PKGCORE_EBD_PATH=${BASH_SOURCE[0]%/*}
+
+BANNED_CMDS=()
+DEPRECATED_CMDS=()
+INTERNAL_CMDS=()
+BANNED_HELPER=${PKGCORE_EBD_PATH}/helpers/internals/banned
+DEPRECATED_HELPER=${PKGCORE_EBD_PATH}/helpers/internals/deprecated
+
+shopt -s nullglob
+for (( eapi=${INITIAL_EAPI} ; eapi<=${EAPI} ; eapi++ )) ; do
+ # scan for banned/deprecated shell functions
+ for file in "${PKGCORE_EBD_PATH}/eapi/${eapi}"/*.bash; do
+ source "${file}" || { echo "failed loading ${file}" >&2; exit 1; }
+ BANNED_CMDS+=( "${PKGCORE_BANNED_FUNCS[@]}" )
+ unset PKGCORE_BANNED_FUNCS
+ DEPRECATED_CMDS+=( "${PKGCORE_DEPRECATED_FUNCS[@]}" )
+ unset PKGCORE_DEPRECATED_FUNCS
+ done
+ # scan for banned/deprecated helpers
+ if [[ -d "${PKGCORE_EBD_PATH}/helpers/${eapi}" ]]; then
+ for file in $(find "${PKGCORE_EBD_PATH}/helpers/${eapi}" ! -type d); do
+ cmd=${file##*/}
+ if $(cmp -s "${file}" "${BANNED_HELPER}"); then
+ BANNED_CMDS+=( "${cmd}" )
+ # remove deprecated entry if one exists
+ for i in "${!DEPRECATED_CMDS[@]}"; do
+ [[ ${DEPRECATED_CMDS[i]} == ${cmd} ]] && unset 'DEPRECATED_CMDS[i]'
+ done
+ elif $(cmp -s "${file}" "${DEPRECATED_HELPER}"); then
+ DEPRECATED_CMDS+=( "${cmd}" )
+ else
+ INTERNAL_CMDS+=( "${cmd}" )
+ fi
+ done
+ fi
+done
+
+if ${BANNED} && [[ -n ${BANNED_CMDS[@]} ]]; then
+ printf '%s\n' ${BANNED_CMDS[@]} | sort -u
+fi
+if ${DEPRECATED} && [[ -n ${DEPRECATED_CMDS[@]} ]]; then
+ printf '%s\n' ${DEPRECATED_CMDS[@]} | sort -u
+fi
+if ${INTERNAL} && [[ -n ${INTERNAL_CMDS[@]} ]]; then
+ printf '%s\n' ${INTERNAL_CMDS[@]} | sort -u
+fi
diff --git a/data/lib/pkgcore/ebd/generate_eapi_func_list b/data/lib/pkgcore/ebd/generate_eapi_func_list
new file mode 100755
index 000000000..e2bcebb9d
--- /dev/null
+++ b/data/lib/pkgcore/ebd/generate_eapi_func_list
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+#
+# Generate the list of functions specific to an EAPI version.
+#
+# This script is run dynamically in a repo or tarball layout on initialization
+# of the build environment for each ebuild since different EAPIs require
+# different lists of functions to be skipped. For installed versions, static
+# function lists are generated at install time and used instead.
+
+ONLY=false
+VISIBLE=false
+
+while getopts "ov" opt; do
+ case ${opt} in
+ o) ONLY=true ;;
+ v) VISIBLE=true ;;
+ *) ;;
+ esac
+done
+
+shift $((OPTIND-1))
+EAPI=${1:-0}
+${ONLY} && INITIAL_EAPI=${EAPI} || INITIAL_EAPI=0
+export PKGCORE_EBD_PATH=${BASH_SOURCE[0]%/*}
+
+shopt -s nullglob
+for (( eapi=${INITIAL_EAPI} ; eapi<=${EAPI} ; eapi++ )) ; do
+ for file in "${PKGCORE_EBD_PATH}/eapi/${eapi}"/*.bash; do
+ source "${file}" || { echo "failed loading ${file}" >&2; exit 1; }
+ done
+done
+
+${VISIBLE} || INTERNAL_FUNCS=( $(compgen -A function __) )
+
+# Sorting order; put PMS functionality first, then our internals.
+printf '%s\n' $(compgen -X '__*' -A function) ${INTERNAL_FUNCS[@]} | sort -u
diff --git a/data/lib/pkgcore/ebd/generate_eapi_lib b/data/lib/pkgcore/ebd/generate_eapi_lib
new file mode 100755
index 000000000..aaacf4e3f
--- /dev/null
+++ b/data/lib/pkgcore/ebd/generate_eapi_lib
@@ -0,0 +1,87 @@
+#!/usr/bin/env bash
+#
+# Generate EAPI specific bash libraries for various scopes.
+#
+# This script is run dynamically in a repo or tarball layout on initialization
+# of the build environment for each ebuild since different EAPIs require
+# different support to be enabled or overridden. For installed versions, static
+# function lists are generated at install time and used instead.
+
+load_eapi_libs() {
+ local scope="global"
+ local -a skip_funcs=( $(compgen -A function) )
+ local skip_regex=$(IFS='|'; echo "^(${skip_funcs[*]})$")
+
+ while getopts "s:" opt; do
+ case ${opt} in
+ s) scope=${OPTARG} ;;
+ *) exit 1 ;;
+ esac
+ done
+ shift $((OPTIND-1))
+ local EAPI=${1:-0}
+ local selected_func=$2
+
+ local eapi file func
+ for (( eapi=0 ; eapi<=${EAPI} ; eapi++ )) ; do
+ # load phase libs when not targeting global scope
+ if [[ ${scope} != global ]]; then
+ source "${PKGCORE_EBD_PATH}"/eapi/depend.bash || { echo "failed loading depend.bash" >&2; exit 1; }
+ if [[ ${scope} != phase ]]; then
+ file=${PKGCORE_EBD_PATH}/eapi/${eapi}/phase.bash
+ if [[ -f ${file} ]]; then
+ source "${file}" || { echo "failed loading ${file}" >&2; exit 1; }
+ fi
+ fi
+ fi
+
+ file=${PKGCORE_EBD_PATH}/eapi/${eapi}/${scope}.bash
+ if [[ -f ${file} ]]; then
+ source "${file}" || { echo "failed loading ${file}" >&2; exit 1; }
+ fi
+
+ # replace EAPI banned functions if any exist
+ for func in "${PKGCORE_BANNED_FUNCS[@]}"; do
+ if declare -F ${func} &>/dev/null; then
+ eval "${func}() { die \"\${FUNCNAME}: banned in EAPI ${eapi}\"; }"
+ else
+ echo "EAPI ${eapi}: undefined banned func: '${func}'" >&2
+ exit 1
+ fi
+ done
+ unset PKGCORE_BANNED_FUNCS
+
+ # replace EAPI deprecated functions if any exist
+ for func in "${PKGCORE_DEPRECATED_FUNCS[@]}"; do
+ if declare -F ${func} &>/dev/null; then
+ local func_src=$(declare -f ${func})
+ local warning="QA Notice: ${func}: deprecated in EAPI ${eapi}"
+ # rename deprecated function
+ eval "${func_src/#${func}/__deprecated_${func}}"
+ # replace deprecated function with QA warning + renamed function
+ eval "${func}() { eqawarn \"${warning}\"; __deprecated_${func}; }"
+ else
+ echo "EAPI ${eapi}: undefined deprecated func: '${func}'" >&2
+ exit 1
+ fi
+ done
+ unset PKGCORE_DEPRECATED_FUNCS
+ done
+
+ local -a eapi_funcs
+ for func in $(compgen -A function); do
+ [[ ! ${func} =~ ${skip_regex} ]] && eapi_funcs+=( ${func} )
+ done
+
+ if [[ -n ${selected_func} && ! ${selected_func} =~ ${skip_regex} ]]; then
+ declare -f ${selected_func}
+ else
+ declare -f ${eapi_funcs[@]}
+ fi
+}
+
+# output values if being run as a script
+if [[ ${BASH_SOURCE[0]} == $0 ]]; then
+ export PKGCORE_EBD_PATH=${BASH_SOURCE[0]%/*}
+ load_eapi_libs "$@"
+fi
diff --git a/data/lib/pkgcore/ebd/generate_global_func_list b/data/lib/pkgcore/ebd/generate_global_func_list
new file mode 100755
index 000000000..1a0cdc644
--- /dev/null
+++ b/data/lib/pkgcore/ebd/generate_global_func_list
@@ -0,0 +1,72 @@
+#!/usr/bin/env bash
+#
+# Generate the list of globally defined functions.
+#
+# This script is run dynamically in a repo or tarball layout on initialization
+# of the build environment. For installed versions, a static function list is
+# generated at install time and used instead.
+
+export PKGCORE_EBD_PATH=${BASH_SOURCE[0]%/*}
+
+# re-exec ourselves inside an empty environment
+if [[ -z ${PKGCORE_CLEAN_ENV} ]]; then
+ exec env -i \
+ PATH="${PATH}" \
+ PKGCORE_CLEAN_ENV=1 \
+ "$0" "$@"
+fi
+
+# avoid any potential issues of unicode sorting for whacked func names
+export LC_ALL=C
+DEBUG=false
+
+while getopts ":d" opt; do
+ case $opt in
+ d) DEBUG=true ;;
+ *) ;;
+ esac
+done
+
+# use seen array to only source files once
+declare -A seen
+source() {
+ local fp=$(readlink -f "$1")
+ ${seen[${fp}]:-false} && return 0
+ # die relies on these vars; we reuse them.
+ local CATEGORY=${PKGCORE_EBD_PATH}
+ local PF=$1
+ ${DEBUG} && echo "sourcing ${x}" >&2
+ . "$@" || { echo "!!! failed sourcing ${x}; exit $?" >&2; exit 3; }
+ seen[${fp}]=true
+ return 0
+}
+
+# proper sourcing order to satisfy dependencies
+forced_order_source=(
+ isolated-functions.bash
+ exit-handling.bash
+ eapi/depend.bash
+ eapi/common.bash
+ ebuild-daemon-lib.bash
+ ebuild-daemon.bash
+)
+
+# prefix all paths with ebd directory
+forced_order_source=( "${forced_order_source[@]/#/${PKGCORE_EBD_PATH}\/}" )
+
+# Source everything that requires a certain order first, then reload all libs
+# including any ones that were skipped the first time.
+#
+# EAPI specific libs are skipped since those need be sourced on demand
+# depending on an ebuild's EAPI.
+for x in "${forced_order_source[@]}" "${PKGCORE_EBD_PATH}"/*.bash; do
+ source "${x}"
+done
+
+# wipe our custom funcs
+unset -f source
+
+${DEBUG} && echo >&2
+# Sorting order; put PMS functionality first, then our internals.
+printf '%s\n' $(compgen -X '__*' -A function) $(compgen -A function __) |
+ sort -u
diff --git a/data/lib/pkgcore/ebd/helpers/0/dosed b/data/lib/pkgcore/ebd/helpers/0/dosed
new file mode 100755
index 000000000..6cdec3cf0
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/dosed
@@ -0,0 +1,22 @@
+#!/usr/bin/env pkgcore-ebuild-helper
+
+check_args 1 -
+
+pattern="s:${ED}::g"
+
+for x in "$@"; do
+ trg=${ED}/${x}
+ if [[ ! -e ${trg} ]]; then
+ pattern=${x}
+ continue
+ fi
+ if [[ ! -f ${trg} ]]; then
+ error "'${trg}' is not a regular file!";
+ continue
+ fi
+ tmp_file=${T}/${trg##*/}
+ if check_command cp "${trg}" "${tmp_file}"; then
+ check_command sed -e "${pattern}" "${tmp_file}" > "${trg}"
+ rm -f "${tmp_file}"
+ fi
+done
diff --git a/data/lib/pkgcore/ebd/helpers/0/emake b/data/lib/pkgcore/ebd/helpers/0/emake
new file mode 100755
index 000000000..41abc1bbc
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/emake
@@ -0,0 +1,4 @@
+#!/usr/bin/env pkgcore-ebuild-helper
+
+info "${MAKE:-make} ${MAKEOPTS} ${EXTRA_EMAKE} $@"
+check_command ${MAKE:-make} ${MAKEOPTS} ${EXTRA_EMAKE} "$@"
diff --git a/data/lib/pkgcore/ebd/helpers/0/pkg_postinst/fowners b/data/lib/pkgcore/ebd/helpers/0/pkg_postinst/fowners
new file mode 120000
index 000000000..b139f9174
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/pkg_postinst/fowners
@@ -0,0 +1 @@
+../src_install/fowners \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/pkg_postinst/fperms b/data/lib/pkgcore/ebd/helpers/0/pkg_postinst/fperms
new file mode 120000
index 000000000..78b020190
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/pkg_postinst/fperms
@@ -0,0 +1 @@
+../src_install/fperms \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/pkg_postinst/keepdir b/data/lib/pkgcore/ebd/helpers/0/pkg_postinst/keepdir
new file mode 120000
index 000000000..56cfcbd3c
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/pkg_postinst/keepdir
@@ -0,0 +1 @@
+../src_install/keepdir \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/pkg_preinst/dodir b/data/lib/pkgcore/ebd/helpers/0/pkg_preinst/dodir
new file mode 120000
index 000000000..c10af926d
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/pkg_preinst/dodir
@@ -0,0 +1 @@
+../src_install/dodir \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/pkg_preinst/fowners b/data/lib/pkgcore/ebd/helpers/0/pkg_preinst/fowners
new file mode 120000
index 000000000..b139f9174
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/pkg_preinst/fowners
@@ -0,0 +1 @@
+../src_install/fowners \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/pkg_preinst/fperms b/data/lib/pkgcore/ebd/helpers/0/pkg_preinst/fperms
new file mode 120000
index 000000000..78b020190
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/pkg_preinst/fperms
@@ -0,0 +1 @@
+../src_install/fperms \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/pkg_preinst/keepdir b/data/lib/pkgcore/ebd/helpers/0/pkg_preinst/keepdir
new file mode 120000
index 000000000..56cfcbd3c
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/pkg_preinst/keepdir
@@ -0,0 +1 @@
+../src_install/keepdir \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/dobin b/data/lib/pkgcore/ebd/helpers/0/src_install/dobin
new file mode 100755
index 000000000..ef534d424
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/dobin
@@ -0,0 +1,3 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+OPTIONS=( "--dest=\"${PKGCORE_DESTTREE}/bin\"" )
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/doconfd b/data/lib/pkgcore/ebd/helpers/0/src_install/doconfd
new file mode 100755
index 000000000..27a780e9f
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/doconfd
@@ -0,0 +1,4 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+PKGCORE_INSDESTTREE=/etc/conf.d
+IPC_CMD=doins
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/dodir b/data/lib/pkgcore/ebd/helpers/0/src_install/dodir
new file mode 100755
index 000000000..a1d7b41b8
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/dodir
@@ -0,0 +1,3 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+OPTIONS=( "--diroptions=\"${DIROPTIONS}\"" )
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/dodoc b/data/lib/pkgcore/ebd/helpers/0/src_install/dodoc
new file mode 100755
index 000000000..d6320d15a
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/dodoc
@@ -0,0 +1,3 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+OPTIONS=( "--dest=\"/usr/share/doc/${PF}/${PKGCORE_DOCDESTTREE}\"" )
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/doenvd b/data/lib/pkgcore/ebd/helpers/0/src_install/doenvd
new file mode 100755
index 000000000..a6f2871a2
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/doenvd
@@ -0,0 +1,4 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+PKGCORE_INSDESTTREE=/etc/env.d
+IPC_CMD=doins
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/doexe b/data/lib/pkgcore/ebd/helpers/0/src_install/doexe
new file mode 100755
index 000000000..fabd55bc1
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/doexe
@@ -0,0 +1,6 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+OPTIONS=(
+ "--dest=\"${PKGCORE_EXEDESTTREE}\""
+ "--insoptions=\"${EXEOPTIONS}\""
+)
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/dohard b/data/lib/pkgcore/ebd/helpers/0/src_install/dohard
new file mode 100755
index 000000000..251498da2
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/dohard
@@ -0,0 +1 @@
+#!/usr/bin/env pkgcore-ipc-helper
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/dohtml b/data/lib/pkgcore/ebd/helpers/0/src_install/dohtml
new file mode 100755
index 000000000..35f6ed605
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/dohtml
@@ -0,0 +1,3 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+OPTIONS=( "--dest=\"/usr/share/doc/${PF}/${PKGCORE_DOCDESTTREE:-html}\"" )
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/doinfo b/data/lib/pkgcore/ebd/helpers/0/src_install/doinfo
new file mode 100755
index 000000000..0ea3de53a
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/doinfo
@@ -0,0 +1,3 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+OPTIONS=( "--dest=/usr/share/info" )
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/doinitd b/data/lib/pkgcore/ebd/helpers/0/src_install/doinitd
new file mode 100755
index 000000000..9ed3f6339
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/doinitd
@@ -0,0 +1,4 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+PKGCORE_EXEDESTTREE=/etc/init.d
+IPC_CMD=doexe
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/doins b/data/lib/pkgcore/ebd/helpers/0/src_install/doins
new file mode 100755
index 000000000..5cf5f6a03
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/doins
@@ -0,0 +1,11 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+OPTIONS=(
+ "--dest=\"${PKGCORE_INSDESTTREE}\""
+ "--insoptions=\"${INSOPTIONS}\""
+ "--diroptions=\"${DIROPTIONS}\""
+)
+
+if [[ -n ${PKGCORE_INSDESTTREE} && -z ${PKGCORE_INSDESTTREE%${ED}*} ]]; then
+ __helper_exit 2 "do not give \${D} or \${ED} as part of the path arguments to doins"
+fi
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/dolib b/data/lib/pkgcore/ebd/helpers/0/src_install/dolib
new file mode 100755
index 000000000..4a901f1dd
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/dolib
@@ -0,0 +1,12 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+if [[ ${HELPER_NAME} == "dolib.so" ]]; then
+ LIBOPTIONS="-m0755"
+elif [[ ${HELPER_NAME} == "dolib.a" ]]; then
+ LIBOPTIONS="-m0644"
+fi
+
+OPTIONS=(
+ "--dest=\"${PKGCORE_DESTTREE}/$(__get_libdir lib)\""
+ "--insoptions=\"${LIBOPTIONS}\""
+)
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/dolib.a b/data/lib/pkgcore/ebd/helpers/0/src_install/dolib.a
new file mode 120000
index 000000000..c013e45e8
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/dolib.a
@@ -0,0 +1 @@
+dolib \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/dolib.so b/data/lib/pkgcore/ebd/helpers/0/src_install/dolib.so
new file mode 120000
index 000000000..c013e45e8
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/dolib.so
@@ -0,0 +1 @@
+dolib \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/doman b/data/lib/pkgcore/ebd/helpers/0/src_install/doman
new file mode 100755
index 000000000..4e15ab225
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/doman
@@ -0,0 +1,3 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+OPTIONS=( "--dest=/usr/share/man" )
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/domo b/data/lib/pkgcore/ebd/helpers/0/src_install/domo
new file mode 100755
index 000000000..22dce4892
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/domo
@@ -0,0 +1,7 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+if ${PKGCORE_HAS_DESTREE}; then
+ OPTIONS=( "--dest=\"${PKGCORE_DESTTREE}/share/locale\"" )
+else
+ OPTIONS=( "--dest=/usr/share/locale" )
+fi
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/dosbin b/data/lib/pkgcore/ebd/helpers/0/src_install/dosbin
new file mode 100755
index 000000000..4b9eafb21
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/dosbin
@@ -0,0 +1,3 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+OPTIONS=( "--dest=\"${PKGCORE_DESTTREE}/sbin\"" )
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/dosym b/data/lib/pkgcore/ebd/helpers/0/src_install/dosym
new file mode 120000
index 000000000..dacdb2f13
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/dosym
@@ -0,0 +1 @@
+dohard \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/fowners b/data/lib/pkgcore/ebd/helpers/0/src_install/fowners
new file mode 100755
index 000000000..2b91950dd
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/fowners
@@ -0,0 +1,7 @@
+#!/usr/bin/env pkgcore-ebuild-helper
+
+# at least two args are required- the owner/group chunk, and the target
+check_args 2 -
+
+# pathway must be absolute.
+check_command chown "${@/#\//${ED}/}"
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/fperms b/data/lib/pkgcore/ebd/helpers/0/src_install/fperms
new file mode 100755
index 000000000..bbc6719de
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/fperms
@@ -0,0 +1,7 @@
+#!/usr/bin/env pkgcore-ebuild-helper
+
+# at least two args are required- the owner/group chunk, and the target
+check_args 2 -
+
+# pathway must be absolute.
+check_command chmod "${@/#\//${ED}/}"
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/keepdir b/data/lib/pkgcore/ebd/helpers/0/src_install/keepdir
new file mode 100755
index 000000000..a1d7b41b8
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/keepdir
@@ -0,0 +1,3 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+OPTIONS=( "--diroptions=\"${DIROPTIONS}\"" )
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/newbin b/data/lib/pkgcore/ebd/helpers/0/src_install/newbin
new file mode 120000
index 000000000..26d671d49
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/newbin
@@ -0,0 +1 @@
+../../internals/_generic_new \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/newconfd b/data/lib/pkgcore/ebd/helpers/0/src_install/newconfd
new file mode 120000
index 000000000..26d671d49
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/newconfd
@@ -0,0 +1 @@
+../../internals/_generic_new \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/newdoc b/data/lib/pkgcore/ebd/helpers/0/src_install/newdoc
new file mode 120000
index 000000000..26d671d49
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/newdoc
@@ -0,0 +1 @@
+../../internals/_generic_new \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/newenvd b/data/lib/pkgcore/ebd/helpers/0/src_install/newenvd
new file mode 120000
index 000000000..26d671d49
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/newenvd
@@ -0,0 +1 @@
+../../internals/_generic_new \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/newexe b/data/lib/pkgcore/ebd/helpers/0/src_install/newexe
new file mode 120000
index 000000000..26d671d49
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/newexe
@@ -0,0 +1 @@
+../../internals/_generic_new \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/newinitd b/data/lib/pkgcore/ebd/helpers/0/src_install/newinitd
new file mode 120000
index 000000000..26d671d49
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/newinitd
@@ -0,0 +1 @@
+../../internals/_generic_new \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/newins b/data/lib/pkgcore/ebd/helpers/0/src_install/newins
new file mode 120000
index 000000000..26d671d49
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/newins
@@ -0,0 +1 @@
+../../internals/_generic_new \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/newlib.a b/data/lib/pkgcore/ebd/helpers/0/src_install/newlib.a
new file mode 120000
index 000000000..26d671d49
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/newlib.a
@@ -0,0 +1 @@
+../../internals/_generic_new \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/newlib.so b/data/lib/pkgcore/ebd/helpers/0/src_install/newlib.so
new file mode 120000
index 000000000..26d671d49
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/newlib.so
@@ -0,0 +1 @@
+../../internals/_generic_new \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/newman b/data/lib/pkgcore/ebd/helpers/0/src_install/newman
new file mode 120000
index 000000000..26d671d49
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/newman
@@ -0,0 +1 @@
+../../internals/_generic_new \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/0/src_install/newsbin b/data/lib/pkgcore/ebd/helpers/0/src_install/newsbin
new file mode 120000
index 000000000..26d671d49
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/0/src_install/newsbin
@@ -0,0 +1 @@
+../../internals/_generic_new \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/4/dosed b/data/lib/pkgcore/ebd/helpers/4/dosed
new file mode 120000
index 000000000..22465e004
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/4/dosed
@@ -0,0 +1 @@
+../internals/banned \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/4/src_install/dohard b/data/lib/pkgcore/ebd/helpers/4/src_install/dohard
new file mode 120000
index 000000000..8c40f6117
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/4/src_install/dohard
@@ -0,0 +1 @@
+../../internals/banned \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/5/src_install/doheader b/data/lib/pkgcore/ebd/helpers/5/src_install/doheader
new file mode 100755
index 000000000..17f473b4a
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/5/src_install/doheader
@@ -0,0 +1,4 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+PKGCORE_INSDESTTREE=/usr/include
+IPC_CMD=doins
diff --git a/data/lib/pkgcore/ebd/helpers/5/src_install/newheader b/data/lib/pkgcore/ebd/helpers/5/src_install/newheader
new file mode 120000
index 000000000..26d671d49
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/5/src_install/newheader
@@ -0,0 +1 @@
+../../internals/_generic_new \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/6/src_install/dohtml b/data/lib/pkgcore/ebd/helpers/6/src_install/dohtml
new file mode 120000
index 000000000..02d54a782
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/6/src_install/dohtml
@@ -0,0 +1 @@
+../../internals/deprecated \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/7/nonfatal b/data/lib/pkgcore/ebd/helpers/7/nonfatal
new file mode 100755
index 000000000..941998fe1
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/7/nonfatal
@@ -0,0 +1,5 @@
+#!/usr/bin/env pkgcore-ebuild-helper
+
+check_args 1 -
+
+PKGCORE_NONFATAL=true "$@"
diff --git a/data/lib/pkgcore/ebd/helpers/7/src_install/dohtml b/data/lib/pkgcore/ebd/helpers/7/src_install/dohtml
new file mode 120000
index 000000000..8c40f6117
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/7/src_install/dohtml
@@ -0,0 +1 @@
+../../internals/banned \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/7/src_install/dolib b/data/lib/pkgcore/ebd/helpers/7/src_install/dolib
new file mode 120000
index 000000000..8c40f6117
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/7/src_install/dolib
@@ -0,0 +1 @@
+../../internals/banned \ No newline at end of file
diff --git a/data/lib/pkgcore/ebd/helpers/8/src_install/doconfd b/data/lib/pkgcore/ebd/helpers/8/src_install/doconfd
new file mode 100755
index 000000000..296a48827
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/8/src_install/doconfd
@@ -0,0 +1,5 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+PKGCORE_INSDESTTREE=/etc/conf.d
+INSOPTIONS=-m0644
+IPC_CMD=doins
diff --git a/data/lib/pkgcore/ebd/helpers/8/src_install/doenvd b/data/lib/pkgcore/ebd/helpers/8/src_install/doenvd
new file mode 100755
index 000000000..140b894d5
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/8/src_install/doenvd
@@ -0,0 +1,5 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+PKGCORE_INSDESTTREE=/etc/env.d
+INSOPTIONS=-m0644
+IPC_CMD=doins
diff --git a/data/lib/pkgcore/ebd/helpers/8/src_install/doheader b/data/lib/pkgcore/ebd/helpers/8/src_install/doheader
new file mode 100755
index 000000000..086b406d3
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/8/src_install/doheader
@@ -0,0 +1,5 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+PKGCORE_INSDESTTREE=/usr/include
+INSOPTIONS=-m0644
+IPC_CMD=doins
diff --git a/data/lib/pkgcore/ebd/helpers/8/src_install/doinitd b/data/lib/pkgcore/ebd/helpers/8/src_install/doinitd
new file mode 100755
index 000000000..0b6aa9c97
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/8/src_install/doinitd
@@ -0,0 +1,5 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+PKGCORE_EXEDESTTREE=/etc/init.d
+EXEOPTIONS=-m0755
+IPC_CMD=doexe
diff --git a/data/lib/pkgcore/ebd/helpers/common/pkgcore-ebuild-helper b/data/lib/pkgcore/ebd/helpers/common/pkgcore-ebuild-helper
new file mode 100755
index 000000000..ad5943ead
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/common/pkgcore-ebuild-helper
@@ -0,0 +1,75 @@
+#!/usr/bin/env bash
+
+# protect against env screwups.
+if [[ -z ${PKGCORE_EBD_PATH} ]]; then
+ PKGCORE_EBD_PATH=$(readlink -f "${0}")
+ # and go up 3, out of helpers.
+ PKGCORE_EBD_PATH=${PKGCORE_EBD_PATH%/*}
+ PKGCORE_EBD_PATH=${PKGCORE_EBD_PATH%/*}
+ PKGCORE_EBD_PATH=${PKGCORE_EBD_PATH%/*}
+fi
+export PKGCORE_EBD_PATH
+
+source "${PKGCORE_EBD_PATH}"/exit-handling.bash || {
+ echo "failed to load exit-handling library: PKGCORE_EBD_PATH=${PKGCORE_EBD_PATH}" >&2
+ exit -127
+}
+
+if [[ $# -lt 1 ]]; then
+ die "ebuild-helper invoked without a target helper arg"
+fi
+
+source "${PKGCORE_EBD_PATH}"/ebuild-daemon-lib.bash || \
+ die "failed to load ebuild-daemon-lib.bash"
+source "${PKGCORE_EBD_PATH}"/isolated-functions.bash || \
+ die "failed to load isolated-functions.bash"
+source "${PKGCORE_EBD_PATH}"/eapi/depend.bash >&2 || \
+ die "failed sourcing eapi/depend.bash"
+source "${PKGCORE_EBD_PATH}"/eapi/common.bash >&2 || \
+ die "failed sourcing eapi/common.bash"
+source "${PKGCORE_EBD_PATH}"/helpers/internals/helper-lib.bash >&2 || \
+ die "failed sourcing helpers/internals/helper-lib.bash"
+
+failed=false
+
+MASTER_HELPER_NAME=${1##*/}
+HELPER_ERROR_PREFIX=
+
+if ! ${PKGCORE_PREFIX_SUPPORT:=false}; then
+ export ED=${D}
+elif [[ ${ED:-unset} == "unset" ]]; then
+ error "The variable ED is missing from the environment, but is required for prefix mode."
+ exit -1
+fi
+
+invoke_script() {
+ [[ $# -eq 0 ]] && die "${FUNCNAME}: missing required arguments"
+ local HELPER_PATH=$1
+ local HELPER_NAME=${1##*/}
+ local HELPER_EAPI=${1%/*}
+ HELPER_EAPI=${HELPER_EAPI##*/}
+ shift
+ local HELPER_ARG_COUNT=$#
+ if [[ ! -e ${HELPER_PATH} ]]; then
+ HELPER_PATH=$(type -p "${HELPER_NAME}")
+ [[ -z ${HELPER_PATH} ]] && die "${HELPER_NAME} command not found"
+ fi
+
+ local OLD_ERROR_PREFIX=${HELPER_ERROR_PREFIX}
+ local HELPER_ERROR_PREFIX=${OLD_ERROR_PREFIX:+${OLD_ERROR_PREFIX}: }${HELPER_NAME}
+
+ source "${HELPER_PATH}"
+
+ if ${failed}; then
+ if ${PKGCORE_NONFATAL}; then
+ echo "WARNING: nonzero exitcode from ${HELPER_ERROR_PREFIX}" >&2
+ # need to track the exit code here...
+ return 1
+ fi
+ die "helper failed: ${HELPER_NAME} $@"
+ exit 1
+ fi
+ return 0
+}
+invoke_script "$@"
+exit $(( $? ))
diff --git a/data/lib/pkgcore/ebd/helpers/common/pkgcore-ipc-helper b/data/lib/pkgcore/ebd/helpers/common/pkgcore-ipc-helper
new file mode 100755
index 000000000..dcde1f945
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/common/pkgcore-ipc-helper
@@ -0,0 +1,71 @@
+#!/usr/bin/env bash
+
+# protect against env screwups.
+if [[ -z ${PKGCORE_EBD_PATH} ]]; then
+ PKGCORE_EBD_PATH=$(readlink -f "${0}")
+ # and go up 3, out of helpers.
+ PKGCORE_EBD_PATH=${PKGCORE_EBD_PATH%/*}
+ PKGCORE_EBD_PATH=${PKGCORE_EBD_PATH%/*}
+ PKGCORE_EBD_PATH=${PKGCORE_EBD_PATH%/*}
+fi
+export PKGCORE_EBD_PATH
+
+source "${PKGCORE_EBD_PATH}"/exit-handling.bash || {
+ echo "failed to load exit-handling library: PKGCORE_EBD_PATH=${PKGCORE_EBD_PATH}" >&2
+ exit -127
+}
+
+if [[ $# -lt 1 ]]; then
+ die "ipc-helper invoked without a target helper arg"
+fi
+
+source "${PKGCORE_EBD_PATH}"/ebuild-daemon-lib.bash || \
+ die "failed to load ebuild-daemon-lib.bash"
+source "${PKGCORE_EBD_PATH}"/isolated-functions.bash || \
+ die "failed to load isolated-functions.bash"
+source "${PKGCORE_EBD_PATH}"/eapi/depend.bash >&2 || \
+ die "failed sourcing eapi/depend.bash"
+source "${PKGCORE_EBD_PATH}"/eapi/common.bash >&2 || \
+ die "failed sourcing eapi/common.bash"
+source "${PKGCORE_EBD_PATH}"/helpers/internals/helper-lib.bash >&2 || \
+ die "failed sourcing helpers/internals/helper-lib.bash"
+
+HELPER_ERROR_PREFIX=
+
+if ! ${PKGCORE_PREFIX_SUPPORT:=false}; then
+ export ED=${D}
+elif [[ ${ED:-unset} == "unset" ]]; then
+ error "The variable ED is missing from the environment, but is required for prefix mode."
+ exit -1
+fi
+
+run_ipc_helper() {
+ [[ $# -eq 0 ]] && die "${FUNCNAME}: missing required arguments"
+ local HELPER_PATH=$1
+ local HELPER_NAME=${1##*/}
+ local HELPER_EAPI=${1%/*}
+ HELPER_EAPI=${HELPER_EAPI##*/}
+ shift
+ local HELPER_ARG_COUNT=$#
+ if [[ ! -e ${HELPER_PATH} ]]; then
+ HELPER_PATH=$(type -p "${HELPER_NAME}")
+ [[ -z ${HELPER_PATH} ]] && die "${HELPER_NAME} command not found"
+ fi
+
+ local OLD_ERROR_PREFIX=${HELPER_ERROR_PREFIX}
+ local HELPER_ERROR_PREFIX=${OLD_ERROR_PREFIX:+${OLD_ERROR_PREFIX}: }${HELPER_NAME}
+
+ local IPC_CMD=${HELPER_NAME}
+ source "${HELPER_PATH}"
+
+ # load all parent command opts when running a subcommand that is possibly nested
+ local orig_cmd=${HELPER_NAME}
+ while [[ ${orig_cmd} != ${IPC_CMD} ]]; do
+ orig_cmd=${IPC_CMD}
+ source "$(type -p ${IPC_CMD})" >&2 || die "failed sourcing ${IPC_CMD}"
+ done
+
+ __ebd_ipc_cmd ${IPC_CMD} "${OPTIONS[*]}" "$@"
+}
+run_ipc_helper "$@"
+exit $(( $? ))
diff --git a/data/lib/pkgcore/ebd/helpers/common/prepalldocs b/data/lib/pkgcore/ebd/helpers/common/prepalldocs
new file mode 100755
index 000000000..552f73d58
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/common/prepalldocs
@@ -0,0 +1,67 @@
+#!/usr/bin/env pkgcore-ebuild-helper
+
+shopt -s extdebug extglob
+
+if ! ${PKGCORE_PREFIX_SUPPORT:=false}; then
+ ED=${D}
+elif [[ ${ED:-unset} == "unset" ]]; then
+ __helper_exit -1 "The variable ED is missing from the environment, but is required for prefix mode; failing."
+fi
+
+dir=${ED}/usr/share/doc/${PF}
+
+[[ ! -d ${dir} ]] && return
+
+z=$(find "${dir}" \
+ '(' -type f -or -type l ')' \
+ -not -name '*.gz' \
+ -not -name '*.bz2' \
+ -not -name '*.xz' \
+ -not -name '*.Z' \
+ -not -name '*.js' \
+ -not -path "${ED}/usr/share/doc/${PF}/html/*" \
+ -print \
+ 2>/dev/null)
+
+[[ -z ${z} ]] && return
+
+if [[ -z ${PORTAGE_COMPRESS_SUFFIX} ]]; then
+ case ${PORTAGE_COMPRESS} in
+ gzip) suffix="gz";;
+ bzip2) suffix="bz2";;
+ xz) suffix="xz";;
+ (p?)zstd suffix="zst";;
+ *) die "prepalldocs error: please set PORTAGE_COMPRESS_SUFFIX in make.conf";;
+ esac
+fi
+
+IFS=$'\n'
+echo "doc: ${PORTAGE_COMPRESS} ${PORTAGE_COMPRESS_FLAGS}"
+for y in ${z}; do
+ if [[ -L ${y} ]]; then
+ # Symlink ...
+ mylink=${y}
+ linkto=$(readlink "${y}")
+
+ if [[ ${linkto##*.} != ${suffix} ]]; then
+ linkto=${linkto}.${suffix}
+ fi
+ if [[ ${mylink##*.} != ${suffix} ]]; then
+ mylink=${mylink}.${suffix}
+ fi
+
+ echo " link fixed ${mylink##*/}"
+ ln -snf "${linkto}" "${mylink}"
+ if [[ ${y} != ${mylink} ]]; then
+ echo " link removed ${y##*/}"
+ rm -f "${y}"
+ fi
+ else
+ if [[ ${y##*.} != ${suffix} ]]; then
+ echo " compressing ${y##*/}" >&2
+ "${PORTAGE_COMPRESS}" ${PORTAGE_COMPRESS_FLAGS} -f "${y}"
+ fi
+ fi
+done
+
+:
diff --git a/data/lib/pkgcore/ebd/helpers/common/prepallstrip b/data/lib/pkgcore/ebd/helpers/common/prepallstrip
new file mode 100755
index 000000000..d17004e9f
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/common/prepallstrip
@@ -0,0 +1,7 @@
+#!/usr/bin/env pkgcore-ebuild-helper
+
+check_args 0 0
+
+if ! __feature_is_enabled prepstrip && ! __safe_has nostrip ${RESTRICT}; then
+ check_command_or_stop prepstrip "${ED}"
+fi
diff --git a/data/lib/pkgcore/ebd/helpers/common/prepinfo b/data/lib/pkgcore/ebd/helpers/common/prepinfo
new file mode 100755
index 000000000..b1466f26e
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/common/prepinfo
@@ -0,0 +1,64 @@
+#!/usr/bin/env pkgcore-ebuild-helper
+
+shopt -s extdebug extglob
+
+if ! ${PKGCORE_PREFIX_SUPPORT:=false}; then
+ ED=${D}
+elif [[ ${ED:-unset} == "unset" ]]; then
+ __helper_exit -1 "The variable ED is missing from the environment, but is required for prefix mode; failing."
+fi
+
+if [[ -z $1 ]]; then
+ z=${ED}/usr/share/info
+else
+ if [[ -d ${ED}/$1/share/info ]]; then
+ z=${ED}/$1/share/info
+ else
+ z=${ED}/$1/info
+ fi
+fi
+
+[[ ! -d ${z} ]] && return
+
+rm -f "${z}"/dir{,.old}{,.info{,.gz,.bz2,.xz,.Z}}
+
+if [[ -z ${PORTAGE_COMPRESS_SUFFIX} ]]; then
+ case ${PORTAGE_COMPRESS} in
+ gzip) suffix="gz";;
+ bzip2) suffix="bz2";;
+ xz) suffix="xz";;
+ (p?)zstd suffix="zst";;
+ *) die "prepinfo: error fixing links: please set PORTAGE_COMPRESS_SUFFIX in make.conf";;
+ esac
+fi
+
+echo "info: ${PORTAGE_COMPRESS} ${PORTAGE_COMPRESS_FLAGS}"
+
+for x in $(find "${z}"/ \( -type f -or -type l \) -maxdepth 1 -mindepth 1 2>/dev/null); do
+ if [[ -L ${x} ]]; then
+ # Symlink ...
+ mylink=${x}
+ linkto=$(readlink "${x}")
+
+ if [[ ${linkto##*.} != ${suffix} ]]; then
+ linkto=${linkto}.${suffix}
+ fi
+ if [[ ${mylink##*.} != ${suffix} ]]; then
+ mylink=${mylink}.${suffix}
+ fi
+
+ echo " fixing GNU info symlink: ${mylink##*/}"
+ ln -snf "${linkto}" "${mylink}"
+ if [[ ${x} != ${mylink} ]]; then
+ echo " removing old symlink: ${x##*/}"
+ rm -f "${x}"
+ fi
+ else
+ if [[ ${x##*.} != ${suffix} ]]; then
+ echo " compressing GNU info page: ${x##*/}"
+ "${PORTAGE_COMPRESS}" ${PORTAGE_COMPRESS_FLAGS} -f "${x}"
+ fi
+ fi
+done
+
+:
diff --git a/data/lib/pkgcore/ebd/helpers/common/prepman b/data/lib/pkgcore/ebd/helpers/common/prepman
new file mode 100755
index 000000000..9cc5755db
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/common/prepman
@@ -0,0 +1,63 @@
+#!/usr/bin/env pkgcore-ebuild-helper
+
+shopt -s extdebug extglob
+
+if ! ${PKGCORE_PREFIX_SUPPORT:=false}; then
+ ED=${D}
+elif [[ ${ED:-unset} == "unset" ]]; then
+ __helper_exit -1 "The variable ED is missing from the environment, but is required for prefix mode; failing."
+fi
+
+if [[ -z $1 ]]; then
+ z=${ED}/usr/share/man
+else
+ z=${ED}/$1/man
+fi
+
+[[ ! -d ${z} ]] && return
+
+if [[ -z ${PORTAGE_COMPRESS_SUFFIX} ]]; then
+ case ${PORTAGE_COMPRESS} in
+ gzip) suffix="gz";;
+ bzip2) suffix="bz2";;
+ xz) suffix="xz";;
+ (p?)zstd suffix="zst";;
+ *) die "prepman error: please set PORTAGE_COMPRESS_SUFFIX in make.conf";;
+ esac
+fi
+
+echo "man: ${PORTAGE_COMPRESS} ${PORTAGE_COMPRESS_FLAGS}"
+
+for x in $(find "${z}"/ -type d 2>/dev/null); do
+ for y in $(find "${x}"/ \( -type f -or -type l \) ! -name '.keep*' -maxdepth 1 -mindepth 1 2>/dev/null); do
+ if [[ -L ${y} ]]; then
+ # Symlink ...
+ mylink=${y}
+ linkto=$(readlink "${y}")
+
+ # Do NOT change links to directories
+ if [[ -d ${z}/${linkto} ]]; then
+ continue
+ fi
+
+ if [[ ${linkto##*.} != ${suffix} ]]; then
+ linkto=${linkto}.${suffix}
+ fi
+ if [[ ${mylink##*.} != ${suffix} ]]; then
+ mylink=${mylink}.${suffix}
+ fi
+
+ echo " link fixed ${mylink##*/}"
+ ln -snf "${linkto}" "${mylink}"
+ if [[ ${y} != ${mylink} ]]; then
+ echo " link removed ${y##*/}"
+ rm -f "${y}"
+ fi
+ else
+ if [[ ${y##*.} != ${suffix} && ! -d ${y} ]]; then
+ echo " compressing ${y##*/}"
+ "${PORTAGE_COMPRESS}" ${PORTAGE_COMPRESS_FLAGS} -f "${y}"
+ fi
+ fi
+ done
+done
diff --git a/data/lib/pkgcore/ebd/helpers/common/prepstrip b/data/lib/pkgcore/ebd/helpers/common/prepstrip
new file mode 100755
index 000000000..8547d259c
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/common/prepstrip
@@ -0,0 +1,66 @@
+#!/usr/bin/env pkgcore-ebuild-helper
+
+shopt -s extdebug
+
+# exit if the feature isn't requested, or the restrict isn't there.
+__feature_is_enabled installsources || return
+__safe_has installsources ${RESTRICT} && return
+
+if ! ${PKGCORE_PREFIX_SUPPORT:=false}; then
+ ED=${D}
+elif [[ ${ED:-unset} == "unset" ]]; then
+ __helper_exit -1 "The variable ED is missing from the environment, but is required for prefix mode; failing."
+fi
+
+for x in debugedit scanelf rsync; do
+ if ! type -P ${x} >/dev/null; then
+ ewarn "FEATURES=installsources is enabled but the ${x} binary could not"
+ ewarn "be found. This feature will not work unless ${x} is installed!"
+ return
+ fi
+done
+
+save_elf_sources() {
+ local x=$1
+ local sources_dir=/usr/src/debug/${CATEGORY}/${PF}
+ debugedit -b "${WORKDIR}" -d "${sources_dir}" \
+ -l "${T}"/debug.sources "${x}"
+ if [[ -s ${T}/debug.sources ]]; then
+ [[ -d ${ED}/${sources_dir} ]] || mkdir -p "${ED}/${sources_dir}"
+ grep -zv '/<built-in>$' "${T}"/debug.sources | \
+ (cd "${WORKDIR}"; LANG=C sort -z -u | \
+ rsync -rtL0 --files-from=- "${WORKDIR}/" "${ED}/${sources_dir}/" )
+ fi
+}
+
+# The existence of the section .symtab tells us that a binary is stripped.
+# We want to log already stripped binaries, as this may be a QA violation.
+# They prevent us from getting the splitdebug data.
+if ! __safe_has binchecks ${RESTRICT} && ! __safe_has strip ${RESTRICT}; then
+ f=$(scanelf -yqRBF '#k%F' -k '!.symtab' "$@")
+ if [[ -n ${f} ]]; then
+ echo -e "\a\n"
+ ewarn "QA Notice: Pre-stripped files found:"
+ ewarn "${f}"
+ echo "${f}" > "${T}"/scanelf-already-stripped.log
+ fi
+fi
+
+# Now we look for unstripped binaries.
+for x in $(scanelf -yqRBF '#k%F' -k '.symtab' "$@"); do
+ f=$(file "${x}") || continue
+ [[ -z ${f} ]] && continue
+
+ # only split debug info for final linked objects
+ # or kernel modules as debuginfo for intermediatary
+ # files (think crt*.o from gcc/glibc) is useless and
+ # actually causes problems. install sources for all
+ # elf types though cause that stuff is good.
+
+ if [[ ${f} == *"SB executable"* || ${f} == *"SB pie executable"* ||
+ ${f} == *"SB shared object"* ]]; then
+ save_elf_sources "${x}"
+ elif [[ ${f} == *"SB relocatable"* ]]; then
+ save_elf_sources "${x}"
+ fi
+done
diff --git a/data/lib/pkgcore/ebd/helpers/internals/_generic_new b/data/lib/pkgcore/ebd/helpers/internals/_generic_new
new file mode 100755
index 000000000..1e15106eb
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/internals/_generic_new
@@ -0,0 +1,22 @@
+#!/usr/bin/env pkgcore-ipc-helper
+
+check_args 2
+
+if [[ -z ${T} ]]; then
+ __helper_exit 2 "environment issue (ebuild commands somehow filtered the env for ${HELPER_NAME} call)- \${T} was empty"
+fi
+
+TMP=$(mktemp -d -p "${T}" ".${HELPER_NAME}_XXXXXX")
+trap 'rm -rf "${TMP}"' EXIT
+
+if ${PKGCORE_NEW_READS_STDIN} && [[ $1 == "-" ]]; then
+ if [[ -t 0 ]]; then
+ __helper_exit 1 "no input data available, stdin is a tty"
+ fi
+ check_command_or_stop cat > "${TMP}/$2"
+else
+ check_command_or_stop cp -- "$1" "${TMP}/$2"
+fi
+
+set -- "${TMP}/$2"
+IPC_CMD=do${HELPER_NAME#new}
diff --git a/data/lib/pkgcore/ebd/helpers/internals/banned b/data/lib/pkgcore/ebd/helpers/internals/banned
new file mode 100755
index 000000000..a9ecde875
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/internals/banned
@@ -0,0 +1,3 @@
+#!/usr/bin/env pkgcore-ebuild-helper
+
+die "${HELPER_NAME}: banned in EAPI ${HELPER_EAPI}"
diff --git a/data/lib/pkgcore/ebd/helpers/internals/deprecated b/data/lib/pkgcore/ebd/helpers/internals/deprecated
new file mode 100755
index 000000000..7fd964c5f
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/internals/deprecated
@@ -0,0 +1,15 @@
+#!/usr/bin/env pkgcore-ebuild-helper
+
+eqawarn "QA Notice: ${HELPER_NAME}: deprecated in EAPI ${HELPER_EAPI}"
+
+# remove deprecated location from PATH and run original helper
+deprecated_path=$(__which ${HELPER_NAME})
+__var_push PATH=${PATH/${deprecated_path%/*}:/}
+ORIG_HELPER=$(__which ${HELPER_NAME})
+__var_pop
+
+if [[ ${deprecated_path} == ${ORIG_HELPER} ]]; then
+ die "couldn't find original '${HELPER_NAME}' helper, internal error"
+fi
+
+"${ORIG_HELPER}" "$@"
diff --git a/data/lib/pkgcore/ebd/helpers/internals/helper-lib.bash b/data/lib/pkgcore/ebd/helpers/internals/helper-lib.bash
new file mode 100644
index 000000000..886232777
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/internals/helper-lib.bash
@@ -0,0 +1,80 @@
+# various helper functionality
+
+error() {
+ echo "${HELPER_ERROR_PREFIX}: ${@-no message given}" >&2
+ failed=true
+}
+
+warn() {
+ echo "${HELPER_ERROR_PREFIX}: warning, ${@-no message given}" >&2
+}
+
+info() {
+ echo "${HELPER_ERROR_PREFIX}: $@" >&2
+}
+
+check_args() {
+ local tense="argument"
+ local min=$(( $1 ))
+ local max
+ [[ ${min} -gt 1 ]] && tense="arguments"
+ if [[ $2 == '-' ]]; then
+ max=${HELPER_ARG_COUNT}
+ elif [[ -z $2 ]]; then
+ max=$1
+ fi
+ max=$(( max ))
+
+ if [[ ${HELPER_ARG_COUNT} -ge ${min} && ${HELPER_ARG_COUNT} -le ${max} ]]; then
+ return 0
+ fi
+ if [[ ${min} -eq ${max} ]]; then
+ die "${HELPER_ERROR_PREFIX}: requires exactly ${min} ${tense}, got ${HELPER_ARG_COUNT}"
+ elif [[ $2 == '-' ]]; then
+ die "${HELPER_ERROR_PREFIX}: requires at least ${min} ${tense}, got ${HELPER_ARG_COUNT}"
+ else:
+ die "${HELPER_ERROR_PREFIX}: requires at least ${min} ${tense}, and at most ${max} arguments, got ${HELPER_ARG_COUNT}"
+ fi
+}
+
+check_command() {
+ local ret
+ "$@"
+ ret=$?
+ [[ ${ret} == 0 ]] && return 0
+ error "exitcode ${ret} from $*"
+ return $(( ret ))
+}
+
+check_command_or_stop() {
+ check_command "$@"
+ __helper_check_exit $? "$@ failed, cannot continue"
+ return 0
+}
+
+__helper_exit() {
+ local ret=$1
+ shift
+ [[ ${ret} == 0 ]] && exit 0
+
+ local error_msg="${HELPER_ERROR_PREFIX}: exitcode ${ret}"
+ [[ -n $@ ]] && error_msg+=": $@"
+
+ if ${PKGCORE_NONFATAL}; then
+ eerror "${error_msg}"
+ exit ${ret}
+ fi
+
+ die "${error_msg}"
+}
+
+__helper_failed() {
+ PKGCORE_IS_NOT_HELPER=
+ die "helper failed: ${BASH_COMMAND}"
+}
+
+__helper_check_exit() {
+ [[ $1 == 0 ]] && return
+ shift
+ __helper_exit "$@"
+}
diff --git a/data/lib/pkgcore/ebd/helpers/internals/prepall b/data/lib/pkgcore/ebd/helpers/internals/prepall
new file mode 100755
index 000000000..3a9840275
--- /dev/null
+++ b/data/lib/pkgcore/ebd/helpers/internals/prepall
@@ -0,0 +1,88 @@
+#!/usr/bin/env pkgcore-ebuild-helper
+
+prepman
+prepinfo
+prepalldocs
+prepallstrip
+
+if ! ${PKGCORE_PREFIX_SUPPORT:=false}; then
+ ED=${D}
+elif [[ ${ED:-unset} == "unset" ]]; then
+ __helper_exit -1 "The variable ED is missing from the environment, but is required for prefix mode; failing."
+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{,32,64} \
+ "${ED}"/lib{,32,64} \
+ "${ED}"/usr/lib{,32,64} \
+ "${ED}"/usr/X11R6/lib{,32,64}; do
+ [[ ! -d ${i} ]] && continue
+
+ for j in "${i}"/*.so.* "${i}"/*.so; do
+ [[ ! -e ${j} ]] && continue
+ [[ -L ${j} ]] && continue
+ [[ -x ${j} ]] && continue
+ echo "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
+ echo "removing executable bit: /${j/${ED}/}"
+ chmod -x "${j}"
+ 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
+for a in "${ED}"/usr/lib*/*.a; do
+ s=${a%.a}.so
+ if [[ ! -e ${s} ]]; then
+ s=${s%usr/*}${s##*/usr/}
+ if [[ -e ${s} ]]; then
+ echo -e "\aQA Notice: missing gen_usr_ldscript for ${s##*/}\a"
+ sleep 1
+ fi
+ fi
+done
+
+# Make sure people don't store libtool files or static libs in /lib
+f=$(ls "${ED}"/lib*/*.{a,la} 2>/dev/null)
+if [[ -n ${f} ]]; then
+ echo -e "\n\aQA Notice: excessive files found in the / partition\a"
+ echo "${f}"
+ sleep 1
+fi
+
+# Verify that the libtool files don't contain bogus $ED entries.
+for a in "${ED}"/usr/lib*/*.la; do
+ s=${a##*/}
+ if grep -qs "${ED}" "${a}"; then
+ echo -e "\n\aQA Notice: ${s} appears to contain PORTAGE_TMPDIR paths\a"
+ sleep 1
+ fi
+done
+
+if type -p scanelf > /dev/null; then
+ # Run some sanity checks on shared libraries
+ for d in "${ED}"/lib* "${ED}"/usr/lib*; do
+ f=$(scanelf -ByF '%S %p' "${d}"/lib*.so* | gawk '$2 == "" { print }')
+ if [[ -n ${f} ]]; then
+ echo -e "\n\aQA Notice: the following shared libraries lack a SONAME\a"
+ echo "${f}"
+ sleep 1
+ fi
+
+ f=$(scanelf -ByF '%n %p' "${d}"/lib*.so* | gawk '$2 == "" { print }')
+ if [[ -n ${f} ]]; then
+ echo -e "\n\aQA Notice: the following shared libraries lack NEEDED entries\a"
+ echo "${f}"
+ sleep 1
+ fi
+ done
+fi
diff --git a/data/lib/pkgcore/ebd/isolated-functions.bash b/data/lib/pkgcore/ebd/isolated-functions.bash
new file mode 100644
index 000000000..1723cdc0f
--- /dev/null
+++ b/data/lib/pkgcore/ebd/isolated-functions.bash
@@ -0,0 +1,366 @@
+# Various internal functions
+
+# Internal logging function, don't use this in ebuilds.
+__elog_base() {
+ local messagetype
+ [[ -z $1 || -z ${T} || ! -d ${T}/logging ]] && return 1
+ case $1 in
+ INFO|WARN|ERROR|LOG|QA)
+ messagetype=$1
+ shift
+ ;;
+ *)
+ echo -e " ${PKGCORE_RC_BAD}*${PKGCORE_RC_NORMAL} Invalid use of internal function __elog_base(), next message will not be logged" >&2
+ return 1
+ ;;
+ esac
+ echo "$*" >> "${T}/logging/${EBUILD_PHASE}.${messagetype}"
+ return 0
+}
+
+__colored_output_disable() {
+ PKGCORE_RC_COLS="25 80"
+ PKGCORE_RC_ENDCOL=
+ PKGCORE_RC_GOOD=
+ PKGCORE_RC_WARN=
+ PKGCORE_RC_BAD=
+ PKGCORE_RC_NORMAL=
+ PKGCORE_RC_HILITE=
+ PKGCORE_RC_BRACKET=
+} &> /dev/null
+
+__colored_output_enable() {
+ # try setting the column width to bash's internal COLUMNS variable,
+ # then try to get it via stty. no go? hardcode it to 80.
+ PKGCORE_RC_COLS=${COLUMNS:-0}
+ if (( PKGCORE_RC_COLS <= 0 )); then
+ PKGCORE_RC_COLS=$(set -- $(stty size 2>/dev/null) ; echo ${2:-0})
+ if (( PKGCORE_RC_COLS <= 0 )); then
+ PKGCORE_RC_COLS=80
+ fi
+ fi
+ export COLUMNS=${PKGCORE_RC_COLS}
+
+ # Use PKGCORE_RC_PREFIX in build env to avoid clipping when capturing the
+ # output and displaying with a custom prefix.
+ PKGCORE_RC_COLS=$(( PKGCORE_RC_COLS - 8 - PKGCORE_RC_PREFIX )) # width of [ ok ] == 7
+
+ # Now, ${PKGCORE_RC_ENDCOL} will move us to the end of the column;
+ # irregardless of character width.
+ export PKGCORE_RC_ENDCOL=$'\e[A\e['${PKGCORE_RC_COLS}'C'
+
+ export PKGCORE_RC_GOOD=$'\e[32;01m'
+ export PKGCORE_RC_WARN=$'\e[33;01m'
+ export PKGCORE_RC_BAD=$'\e[31;01m'
+ export PKGCORE_RC_HILITE=$'\e[36;01m'
+ export PKGCORE_RC_BRACKET=$'\e[34;01m'
+ export PKGCORE_RC_NORMAL=$'\e[0m'
+} &> /dev/null
+
+# Version of has, only to be used when the invoker knows that the targets will
+# never have \001 in them.
+__safe_has() {
+ local needle=$1
+ shift
+ local IFS=$'\001'
+ [[ "${IFS}${*}${IFS}" == *"${IFS}${needle}${IFS}"* ]]
+}
+
+__feature_is_enabled() {
+ local IFS=$' \t\n'
+ __safe_has "$1" ${FEATURES}
+} &> /dev/null
+
+__which() {
+ [[ $# -ne 1 ]] && die "${FUNCNAME}: requires a single command name arg, got $@"
+ type -P "$1" || die "'$1' not found in PATH"
+}
+
+__is_function() {
+ declare -F "$1" &> /dev/null
+} &> /dev/null
+
+__run_function_if_exists() {
+ __is_function "$1" || return 0
+ "$@"
+}
+
+__qa_run_function_if_exists() {
+ __is_function "$1" || return 0
+ __qa_invoke "$@"
+}
+
+# Check if a directory is empty.
+# Returns: 0 if empty, 1 otherwise.
+__directory_is_empty() {
+ __shopt_push -s dotglob nullglob
+ local files=( ${1}/* )
+ __shopt_pop
+ [[ ${#files[@]} -gt 0 ]] && return 1
+ return 0
+}
+
+# Reverse a given array.
+# Example:
+# $ a=(1 2 3 4 5)
+# $ a=( $(__reverse_array a) )
+# $ echo ${a[@]}
+# 5 4 3 2 1
+__reverse_array() {
+ local _array_ref="$1"[@]
+ local -a array=( "${!_array_ref}" )
+ local i
+ for (( i=${#array[@]}-1 ; i>=0 ; i-- )) ; do
+ echo "${array[i]}"
+ done
+}
+
+__strip_duplicate_slashes() {
+ if [[ -n $1 ]]; then
+ local removed=$1
+ while [[ ${removed} == *//* ]]; do
+ removed=${removed//\/\///}
+ done
+ echo "${removed}"
+ fi
+}
+
+declare -a PKGCORE_SHOPT_STACK
+
+# Save the current shell option state and set a shell option.
+# Returns: 0 on success, dies on failure.
+__shopt_push() {
+ PKGCORE_SHOPT_STACK[${#PKGCORE_SHOPT_STACK[@]}]=${BASHOPTS}
+ PKGCORE_SHOPT_STACK[${#PKGCORE_SHOPT_STACK[@]}]=$-
+ if [[ $1 == -[su] ]]; then
+ # shopt modification
+ shopt "$@" || die "bad shopt options: $@"
+ elif [[ -n $@ ]]; then
+ set "$@" || die "bad set invocation: $@"
+ fi
+ return 0
+} &> /dev/null
+
+# Revert to the most recent shell option state.
+# Returns: 0 on success, dies on failure.
+__shopt_pop() {
+ [[ $# -ne 0 ]] && die "${FUNCNAME}: accepts no args, got $@"
+ local count=$(( ${#PKGCORE_SHOPT_STACK[@]} - 1 ))
+ [[ ${count} -le 0 ]] && die "${FUNCNAME}: invoked with nothing on the stack"
+
+ local set_val=${PKGCORE_SHOPT_STACK[${count}]}
+ if [[ $- != ${set_val} ]]; then
+ set ${-:++${-}} ${set_val:+-${set_val}} || die "failed enforcing set state of ${set_val}"
+ fi
+ unset -v PKGCORE_SHOPT_STACK\[${count}\] || die "${FUNCNAME}: readonly shopt stack"
+
+ count=$(( count - 1 ))
+
+ local previous=${PKGCORE_SHOPT_STACK[${count}]}
+ unset -v PKGCORE_SHOPT_STACK\[${count}\] || die "${FUNCNAME}: readonly shopt stack"
+ [[ ${BASHOPTS} == ${previous} ]] && return 0
+
+ local IFS=' '
+ local current=${BASHOPTS}
+ if [[ -n ${current} ]]; then
+ shopt -u ${current//:/ } >&2 || die "failed wiping current shopt settings of ${current}"
+ fi
+ if [[ -n ${previous} ]]; then
+ shopt -s ${previous//:/ } >&2 || die "failed forcing old shopt settings to ${previous}"
+ fi
+ return 0
+} &> /dev/null
+
+declare -a PKGCORE_SAVED_IFS
+
+# Save the current IFS value and set a new one.
+# Returns: 0 on success, dies on failure.
+__IFS_push() {
+ PKGCORE_SAVED_IFS[${#PKGCORE_SAVED_IFS[@]}]=${IFS-unset}
+ if [[ $1 == unset ]]; then
+ unset -v IFS || die "${FUNCNAME}: IFS is readonly"
+ else
+ IFS=$1
+ fi
+ :
+}
+
+# Revert to the most recent IFS setting.
+# Returns: 0 on success, dies on failure.
+__IFS_pop() {
+ if [[ ${#PKGCORE_SAVED_IFS[@]} -eq 0 ]]; then
+ die "${FUNCNAME}: invoked with nothing on the stack"
+ fi
+ IFS=${PKGCORE_SAVED_IFS[$(( ${#PKGCORE_SAVED_IFS[@]} - 1 ))]}
+ if [[ ${IFS} == unset ]]; then
+ unset -v IFS || die "${FUNCNAME}: IFS is readonly"
+ fi
+ unset -v PKGCORE_SAVED_IFS\[$(( ${#PKGCORE_SAVED_IFS[@]} - 1 ))\] || die "${FUNCNAME}: readonly IFS stack"
+ :
+}
+
+declare -a PKGCORE_VAR_STACK
+
+# Save the given variable's value and set a new one.
+# Returns: 0 on success, dies on failure.
+__var_push() {
+ local export_opts
+ if [[ $1 == -n ]]; then
+ export_opts="-n"
+ shift
+ fi
+ [[ $# -eq 0 ]] && die "${FUNCNAME}: invoked with no arguments"
+
+ local arg var orig_val
+ for arg in "$@"; do
+ var=${arg%%=*}
+
+ # If the specified variable currently has a value we save it;
+ # otherwise, just push the variable name onto the stack.
+ if orig_val=$(declare -p ${var} 2>/dev/null); then
+ orig_val=${orig_val/declare *${var}=[\'\"]/${var}=}
+ orig_val=${orig_val%[\'\"]}
+ else
+ orig_val=${var}
+ fi
+
+ # toss the current value
+ unset -v ${var} 2>/dev/null || die "${FUNCNAME}: '${var}' is readonly"
+
+ # export a new value if one was specified
+ if [[ ${arg} == *=* ]]; then
+ export ${export_opts} "${arg}" || die "${FUNCNAME}: failed to export '${arg}'"
+ fi
+
+ PKGCORE_VAR_STACK[${#PKGCORE_VAR_STACK[@]}]=${orig_val}
+ done
+}
+
+# Revert the most recent variable value change.
+# Returns: 0 on success, dies on failure.
+__var_pop() {
+ [[ ${#PKGCORE_VAR_STACK[@]} -gt 0 ]] \
+ || die "${FUNCNAME}: invoked with nothing on the stack"
+
+ local count=$1
+ case $# in
+ 0) count=1;;
+ 1) [[ ${count} == *[!0-9]* ]] && die "${FUNCNAME}: arg must be a number: $*";;
+ *) die "${FUNCNAME}: only accepts one arg: $*";;
+ esac
+
+ local var arg
+ while (( count-- )); do
+ arg=${PKGCORE_VAR_STACK[$(( ${#PKGCORE_VAR_STACK[@]} - 1 ))]}
+ var=${arg%%=*}
+
+ # unset the variable on the top of the stack
+ unset -v ${var} 2>/dev/null || die "${FUNCNAME}: '${var}' is readonly"
+
+ # reset its value if one was stored
+ if [[ ${arg} == *=* ]]; then
+ export "${arg}" || die "${FUNCNAME}: failed to export '${arg}'"
+ fi
+
+ unset -v PKGCORE_VAR_STACK\[$(( ${#PKGCORE_VAR_STACK[@]} - 1 ))\] || die "${FUNCNAME}: readonly variable stack"
+ done
+}
+
+declare -a PKGCORE_RESET_STACK
+
+# Save the current shell option and variable stack states.
+# Returns: 0
+__env_push() {
+ PKGCORE_RESET_STACK[${#PKGCORE_RESET_STACK[@]}]=${#PKGCORE_SHOPT_STACK[@]}
+ PKGCORE_RESET_STACK[${#PKGCORE_RESET_STACK[@]}]=${#PKGCORE_VAR_STACK[@]}
+}
+
+# Revert to the last marked shell option and variable stack states.
+# Returns: 0 on success, dies on failure.
+__env_pop() {
+ if [[ ${#PKGCORE_RESET_STACK[@]} -lt 2 ]]; then
+ die "${FUNCNAME}: not enough values on the stack"
+ fi
+
+ local var_stack_reset=${PKGCORE_RESET_STACK[$(( ${#PKGCORE_RESET_STACK[@]} - 1 ))]}
+ unset -v PKGCORE_RESET_STACK\[$(( ${#PKGCORE_RESET_STACK[@]} - 1 ))\] || die "${FUNCNAME}: readonly env stack"
+ local shopt_stack_reset=${PKGCORE_RESET_STACK[$(( ${#PKGCORE_RESET_STACK[@]} - 1 ))]}
+ unset -v PKGCORE_RESET_STACK\[$(( ${#PKGCORE_RESET_STACK[@]} - 1 ))\] || die "${FUNCNAME}: readonly env stack"
+
+ while [[ ${#PKGCORE_VAR_STACK[@]} -gt ${var_stack_reset} ]]; do
+ __var_pop
+ done
+ while [[ ${#PKGCORE_SHOPT_STACK[@]} -gt ${shopt_stack_reset} ]]; do
+ __shopt_pop
+ done
+}
+
+declare -a PKGCORE_STDOUT
+declare -a PKGCORE_STDERR
+
+# Echo a given command to stderr if debugging is enabled then run it while
+# capturing stdout/stderr to PKGCORE_STDOUT/PKGCORE_STDERR arrays.
+__run() {
+ [[ ${PKGCORE_DEBUG} -ge 1 ]] && echo $1 >&2
+ local ret stdout stderr
+ source <({ stderr=( "$({ mapfile -t stdout< <(eval $1; ret=$?; declare -p ret >&3); } 3>&2 2>&1; declare -p stdout >&2)" ); declare -p stderr; } 2>&1)
+ PKGCORE_STDOUT=( "${stdout[@]}" )
+ PKGCORE_STDERR=( "${stderr[@]}" )
+ [[ ${PKGCORE_DEBUG} -ge 1 ]] && printf '%b\n' "${PKGCORE_STDERR[@]}" >&2
+ return ${ret}
+}
+
+# Echo a given command to stderr and then run it.
+__echo_and_run() {
+ [[ ! ${PKGCORE_DEBUG} -ge 1 ]] && local -x PKGCORE_DEBUG=1
+ __run "$1"
+}
+
+__qa_invoke() {
+ if ${PKGCORE_QA_SUPPRESSED:-false}; then
+ "$@"
+ return $(( $? ))
+ fi
+ local pkgcore_should_fail=false
+ # save env and shopt settings.
+ # in addition, protect the stack from bad pkgcore calls, or bad consumers accessing internals
+ local PKGCORE_SAVED_IFS=()
+ local PKGCORE_SHOPT_STACK=()
+
+ __IFS_push "${IFS}"
+ __shopt_push
+
+ "$@"
+ local ret=$?
+
+ if [[ ${#PKGCORE_SAVED_IFS[@]} -ne 1 ]]; then
+ echo "QA warning: unbalanced __IFS_push/__IFS_pop detected. internal error? count was ${#PKGCORE_SAVED_IFS[@]}"
+ pkgcore_should_fail=true
+ fi
+ if [[ ${#PKGCORE_SHOPT_STACK[@]} -ne 2 ]]; then
+ echo "QA warning: unbalanced __shopt_push/__shopt_pop detected. internal error? count was ${#PKGCORE_SHOPT_STACK[@]}"
+ pkgcore_should_fail=true
+ fi
+
+ if [[ ${PKGCORE_SAVED_IFS[0]} != ${IFS-unset} ]]; then
+ echo "QA WARNING: invocation $@ manipulated IFS to ${IFS}, but didn't restore it to its original value!"
+ fi
+ __IFS_pop
+
+ # While these echo statements are ugly, written this way to ensure bash
+ # does it as a single write- aka, keep it within the size of atomic writes
+ # for pipes, relevant for threaded output straight to term.
+ if [[ ${PKGCORE_SHOPT_STACK[0]} != ${BASHOPTS} ]]; then
+ echo "QA warning: shopt modification bled out of invocation $@"$'\n'" : was ${PKGCORE_SHOPT_STACK[0]}"$'\n'" : now ${BASHOPTS}" >&2
+ fi
+
+ if [[ ${PKGCORE_SHOPT_STACK[1]} != $- ]]; then
+ echo "QA warning: set modification bled out of invocation $@"$'\n'" : was ${PKGCORE_SHOPT_STACK[1]}"$'\n'" : now $-" >&2
+ fi
+ __shopt_pop
+
+ ${pkgcore_should_fail} && die "invocation $@ modified globals and didn't clean up"
+ return $(( ret ))
+}
+
+:
diff --git a/data/lib/pkgcore/shell/bash/pkgcore.bash b/data/lib/pkgcore/shell/bash/pkgcore.bash
new file mode 100644
index 000000000..fcca094a9
--- /dev/null
+++ b/data/lib/pkgcore/shell/bash/pkgcore.bash
@@ -0,0 +1,91 @@
+# Common library of shell functions for parsing various Gentoo-related data
+# and leveraging pkgcore functionality.
+
+# get an attribute for a given package
+_pkgattr() {
+ local prog=$(_get_caller)
+ local pkg_attr=$1 pkg_atom=$2 repo=$3
+ local ret=0 pid fdout fderr
+ local -a pkg error
+
+ if [[ -z ${pkg_atom} ]]; then
+ echo "${prog}: enter a valid package name or repo path" >&2
+ return 1
+ fi
+
+ # setup pipes for stdout/stderr capture
+ local tmpdir=$(mktemp -d)
+ trap "rm -rf '${tmpdir}'" EXIT HUP INT TERM
+ mkfifo "${tmpdir}"/{stdout,stderr}
+
+ if [[ -n ${repo} ]]; then
+ pquery -r "${repo}" --raw --unfiltered --cpv -R --one-attr "${pkg_attr}" \
+ -n -- "${pkg_atom}" >"${tmpdir}"/stdout 2>"${tmpdir}"/stderr &
+ else
+ pquery --ebuild-repos --raw --unfiltered --cpv -R --one-attr "${pkg_attr}" \
+ -n -- "${pkg_atom}" >"${tmpdir}"/stdout 2>"${tmpdir}"/stderr &
+ fi
+
+ # capture pquery stdout/stderr into separate vars
+ pid=$!
+ exec {fdout}<"${tmpdir}"/stdout {fderr}<"${tmpdir}"/stderr
+ rm -rf "${tmpdir}"
+ mapfile -t -u ${fdout} pkg
+ mapfile -t -u ${fderr} error
+ wait ${pid}
+ ret=$?
+ exec {fdout}<&- {fderr}<&-
+
+ if [[ ${ret} != 0 ]]; then
+ # re-prefix the main pquery error message with the shell function name
+ echo "${prog}: ${error[0]#pquery: error: }" >&2
+ # output the remaining portion of the error message
+ local line
+ for line in "${error[@]:1}"; do
+ echo -E "${line}" >&2
+ done
+ return 1
+ fi
+
+ local choice
+ if [[ -z ${pkg[@]} ]]; then
+ echo "${prog}: no matches found: ${pkg_atom}" >&2
+ return 1
+ elif [[ ${#pkg[@]} > 1 ]]; then
+ echo "${prog}: multiple matches found: ${pkg_atom}" >&2
+ choice=$(_choose "${pkg[@]%%|*}")
+ [[ $? -ne 0 ]] && return 1
+ else
+ choice=-1
+ fi
+ echo ${pkg[${choice}]#*|}
+}
+
+# get the caller of the current function
+_get_caller() {
+ local caller
+ if [[ ${FUNCNAME[-1]} == "source" ]]; then
+ caller=$(basename ${BASH_SOURCE[-1]})
+ else
+ caller=${FUNCNAME[-1]}
+ fi
+ echo ${caller}
+}
+
+# cross-shell compatible PATH searching
+_which() {
+ type -P "$1" >/dev/null
+}
+
+# cross-shell compatible read num chars
+_read_nchars() {
+ local var
+ read -n $1 var
+ echo ${var}
+}
+
+# cross-shell compatible array index helper
+# bash arrays start at 0
+_array_index() {
+ echo $1
+}
diff --git a/data/lib/pkgcore/shell/bin/pkgcore-sh-helper b/data/lib/pkgcore/shell/bin/pkgcore-sh-helper
new file mode 100755
index 000000000..96e2a03fd
--- /dev/null
+++ b/data/lib/pkgcore/shell/bin/pkgcore-sh-helper
@@ -0,0 +1,16 @@
+#!/usr/bin/env sh
+
+# exit out if not running via an external script
+[ -z "$1" ] && exit 1
+
+SCRIPT_PATH=$1
+SCRIPT=$(basename ${SCRIPT_PATH})
+shift
+
+SHELL=$(ps -p $(ps -p $$ -o ppid=) -o comm=)
+if [ "${SHELL}" != "bash" ] && [ "${SHELL}" != "zsh" ]; then
+ echo "${SCRIPT}: unsupported shell: ${SHELL}" >&2
+ exit 1
+fi
+
+exec ${SHELL} -c "source \"$(dirname ${0})\"/../pkgcore.sh && SCRIPT=${SCRIPT} source \"${SCRIPT_PATH}\" $@"
diff --git a/data/lib/pkgcore/shell/bin/psite b/data/lib/pkgcore/shell/bin/psite
new file mode 100755
index 000000000..6d200c5f8
--- /dev/null
+++ b/data/lib/pkgcore/shell/bin/psite
@@ -0,0 +1,47 @@
+#!/usr/bin/env pkgcore-sh-helper
+# open a package's homepage in a browser
+#
+# For queries returning multiple packages, a list of options is presented to
+# the user to choose from. In the same manner, if a package has multiple
+# homepages listed, a list of homepages is outputted for selection.
+#
+# Note that this requires xdg-utils to be installed for xdg-open.
+
+# Default to the current working directory if no argument is passed so this can
+# be run with no arguments from within an ebuild's directory.
+if [[ $# -eq 0 ]]; then
+ set -- "${PWD}" "$@"
+elif [[ $1 == "-h" || $1 == "--help" ]]; then
+ cat <<-EOF
+ ${SCRIPT}: open a package's homepage in a browser
+ usage: ${SCRIPT} pkg [repo]
+ example: ${SCRIPT} gcc -- open gcc's homepage
+ example: ${SCRIPT} coreutils gentoo -- open the coreutils::gentoo homepage
+ EOF
+ exit
+fi
+
+homepage=( $(_pkgattr homepage "$@") )
+[[ $? -ne 0 ]] && exit 1
+
+if [[ -z ${homepage[@]} ]]; then
+ echo "${SCRIPT}: no homepage found: $1" >&2
+ exit 1
+elif [[ ${#homepage[@]} -gt 1 ]]; then
+ echo "${SCRIPT}: multiple homepages found:" >&2
+ choice=$(_choose "${homepage[@]}")
+ [[ $? -ne 0 ]] && exit 1
+ homepage=${homepage[choice]}
+fi
+
+# fallback to xdg-open if $BROWSER is unset
+if [[ -z ${BROWSER} ]]; then
+ BROWSER=xdg-open
+fi
+
+if ! _which ${BROWSER}; then
+ echo "${SCRIPT}: ${BROWSER} not available" >&2
+ return 1
+fi
+
+${BROWSER} "${homepage}" &>/dev/null &
diff --git a/data/lib/pkgcore/shell/pkgcore.sh b/data/lib/pkgcore/shell/pkgcore.sh
new file mode 100644
index 000000000..74581c025
--- /dev/null
+++ b/data/lib/pkgcore/shell/pkgcore.sh
@@ -0,0 +1,90 @@
+# Common library of useful shell functions leveraging pkgcore functionality.
+# Source this file from your .bashrc, .zshrc, or similar.
+#
+# Only bash and zsh are currently supported.
+
+# determine interactive parent shell
+PKGSHELL=$(ps -p $$ -ocomm=)
+if [[ ${PKGSHELL} != "bash" && ${PKGSHELL} != "zsh" ]]; then
+ echo "pkgcore.sh: unsupported shell: ${PKGSHELL}" >&2
+ return 1
+fi
+
+# determine the directory path where this script exists
+if [[ ${PKGSHELL} == "bash" ]]; then
+ SCRIPTDIR=$(dirname $(realpath ${BASH_SOURCE[0]}))
+else
+ SCRIPTDIR=${${(%):-%x}:A:h}
+fi
+
+# source bash/zsh specific support
+source "${SCRIPTDIR}"/${PKGSHELL}/pkgcore.${PKGSHELL}
+export PATH=${SCRIPTDIR}/bin:${PATH}
+unset PKGSHELL SCRIPTDIR
+
+# interactively choose a value from an array
+#
+# usage: _choose "${array[@]}"
+# returns: index of array choice (assuming array indexing starts at 1)
+_choose() {
+ local choice num_opts=$#
+
+ # show available choices
+ local x i=0
+ for x in $@; do
+ echo " $(( ++i )): ${x}" >&2
+ done
+
+ # read user choice, checking for invalid values
+ local invalid=0
+ while true; do
+ echo -n "Please select one: " >&2
+ choice=$(_read_nchars ${#num_opts})
+ if [[ ! ${choice} =~ [0-9]+ || ${choice} -lt 1 || ${choice} -gt ${num_opts} ]]; then
+ (( invalid++ ))
+ echo " -- Invalid choice!" >&2
+ # three invalids seen, giving up
+ [[ ${invalid} -gt 2 ]] && break
+ continue
+ fi
+ echo >&2
+ break
+ done
+
+ # default to array indexes starting at 0
+ (( choice-- ))
+ echo $(_array_index ${choice})
+}
+
+# change to a package directory
+#
+# This will change the current working directory to the sys-devel/gcc directory
+# in the gentoo repo. Note that pkgcore's extended atom syntax is supported so
+# one can also abbreviate the command to `pcd gcc gentoo` assuming there is
+# only one package with a name of 'gcc' in the gentoo repo. In the case where
+# multiple matches are found the list of choices is returned to select from.
+#
+# This should work for any local repo type on disk, e.g. one can also use this
+# to enter the repos for installed or binpkgs via 'vdb' or 'binpkg' repo
+# arguments, respectively.
+pcd() {
+ if [[ $1 == "-h" || $1 == "--help" ]]; then
+ cat <<-EOF
+ pcd: change to a package directory
+ usage: pcd pkg [repo]
+ example: pcd gcc gentoo -- change to the sys-devel/gcc directory in the gentoo repo
+ example: pcd coreutils vdb -- change to the sys-apps/coreutils dir in the vdb
+ EOF
+ return 0
+ fi
+
+ local pkgpath=$(_pkgattr path "$@")
+ [[ -z ${pkgpath} ]] && return 1
+
+ # find the nearest parent directory
+ while [[ ! -d ${pkgpath} ]]; do
+ pkgpath=$(dirname "${pkgpath}")
+ done
+
+ pushd "${pkgpath}" >/dev/null
+}
diff --git a/data/lib/pkgcore/shell/zsh/pkgcore.zsh b/data/lib/pkgcore/shell/zsh/pkgcore.zsh
new file mode 100644
index 000000000..0ee9cd9d6
--- /dev/null
+++ b/data/lib/pkgcore/shell/zsh/pkgcore.zsh
@@ -0,0 +1,348 @@
+# Common library of shell functions for parsing various Gentoo-related data
+# and leveraging pkgcore functionality.
+
+# get an attribute for a given package
+_pkgattr() {
+ local prog=$(_get_caller)
+ local pkg_attr=$1 pkg_atom=$2 repo=$3
+ local ret=0 pid fdout fderr
+ local -a pkg error
+
+ if [[ -z ${pkg_atom} ]]; then
+ echo "${prog}: enter a valid package name or repo path" >&2
+ return 1
+ fi
+
+ # setup pipes for stdout/stderr capture
+ local tmpdir=$(mktemp -d)
+ trap "rm -rf '${tmpdir}'" EXIT HUP INT TERM
+ mkfifo "${tmpdir}"/{stdout,stderr}
+
+ if [[ -n ${repo} ]]; then
+ pquery -r "${repo}" --raw --unfiltered --cpv -R --one-attr "${pkg_attr}" \
+ -n -- "${pkg_atom}" >"${tmpdir}"/stdout 2>"${tmpdir}"/stderr &
+ else
+ pquery --ebuild-repos --raw --unfiltered --cpv -R --one-attr "${pkg_attr}" \
+ -n -- "${pkg_atom}" >"${tmpdir}"/stdout 2>"${tmpdir}"/stderr &
+ fi
+
+ # capture pquery stdout/stderr into separate vars
+ pid=$!
+ exec {fdout}<"${tmpdir}"/stdout {fderr}<"${tmpdir}"/stderr
+ rm -rf "${tmpdir}"
+ pkg=("${(@f)$(<&${fdout})}")
+ error=("${(@f)$(<&${fderr})}")
+ wait ${pid}
+ ret=$?
+ exec {fdout}<&- {fderr}<&-
+
+ if [[ ${ret} != 0 ]]; then
+ # re-prefix the main pquery error message with the shell function name
+ echo "${prog}: ${error[1]#pquery: error: }" >&2
+ # output the remaining portion of the error message
+ local line
+ for line in "${error[@]:1}"; do
+ echo -E "${line}" >&2
+ done
+ return 1
+ fi
+
+ local choice
+ if [[ -z ${pkg[@]} ]]; then
+ echo "${prog}: no matches found: ${pkg_atom}" >&2
+ return 1
+ elif [[ ${#pkg[@]} > 1 ]]; then
+ echo "${prog}: multiple matches found: ${pkg_atom}" >&2
+ choice=$(_choose "${pkg[@]%%|*}")
+ [[ $? -ne 0 ]] && return 1
+ else
+ choice=-1
+ fi
+ echo ${pkg[${choice}]#*|}
+}
+
+# get the caller of the current function
+_get_caller() {
+ echo ${${funcstack[-1]}:t}
+}
+
+# cross-shell compatible PATH searching
+_which() {
+ whence -p "$1" >/dev/null
+}
+
+# cross-shell compatible read num chars
+_read_nchars() {
+ local var
+ read -k $1 var
+ echo ${var}
+}
+
+# cross-shell compatible array index helper
+# zsh arrays start at 1
+_array_index() {
+ index=$1
+ echo $(( ++index ))
+}
+
+## Completion related functions ##
+
+# configured repo info
+#
+# Note that this only supports the repos.conf format,
+# PORTDIR/PORTDIR_OVERLAY in make.conf are not supported.
+#
+# optional args:
+# -t repo_types -- show specific repo types (defaults to showing source repos)
+# The repo_types parameter can be any of the following characters in combination:
+# e: package.provided "repo"
+# i: vdb "repo"
+# s: all source repos (default if the -t option isn't passed)
+# b: all binary repos
+# a: repo-stack "repo"
+# For example, `_repos -t sbi` will return the list of source, binary, and
+# installed repos.
+# -v section:key
+# -p print the output instead of using completion
+# -l use repo locations instead of repo_ids
+_repos() {
+ typeset -A opts
+ zparseopts -E -A opts t: l p v:
+
+ local repo_name output_type
+ typeset -a repos repo_types output
+
+ # verify selected repo types
+ if [[ -n ${opts[(I)-t]} ]]; then
+ local -a supported_repo_types=(e i s b a)
+ repo_types=(${(s::)opts[-t]})
+ for type in ${repo_types[@]}; do
+ if [[ ! ${type} =~ [${supported_repo_types[@]}] ]]; then
+ echo "${funcstack[1]}: invalid repo type: ${type}" >&2
+ echo "supported types: ${supported_repo_types[@]} (see docs)" >&2
+ return 1
+ fi
+ done
+ else
+ # default to showing source repos
+ repo_types=(s)
+ fi
+
+ if [[ -e /etc/portage/repos.conf ]]; then
+ repos_conf_files=( /etc/portage/repos.conf /etc/portage/repos.conf/** )
+ else
+ repos_conf_files=( /usr/share/pkgcore/config/repos.conf )
+ fi
+
+ IFS='= '
+
+ local file
+ for file in "${repos_conf_files[@]}"; do
+ [[ -f ${file} ]] || continue
+ while read -r name value; do
+ # skip comments and empty lines
+ [[ -z ${name} || ${name} == '#'* ]] && continue
+ if [[ (${name} == '['*']') && -z ${value} ]]; then
+ repo_name=${name//[\[\]]}
+ [[ ${repo_name} != "DEFAULT" ]] && repos+=(${repo_name})
+ typeset -A ${repo_name}
+ else
+ eval "${repo_name}[${name}]=\"${value}\""
+ fi
+ done < ${file}
+ done
+
+ if [[ -n ${opts[(I)-v]} ]]; then
+ section=${opts[-v]%%:*}
+ value=${opts[-v]##*:}
+ eval "output=\${${section}[${value}]}"
+ elif [[ -n ${opts[(I)-l]} ]]; then
+ # repo paths
+ output_type="repo paths"
+ for repo in ${repos[@]}; do
+ eval "output+=(\${${repo}[location]})"
+ done
+ else
+ # repo names
+ output_type="repos"
+
+ [[ ${repo_types} =~ "s" ]] && output+=(${repos[@]})
+ [[ ${repo_types} =~ "e" ]] && output+=( provided )
+ [[ ${repo_types} =~ "i" ]] && output+=( vdb )
+ [[ ${repo_types} =~ "b" ]] && output+=( binpkg )
+ [[ ${repo_types} =~ "a" ]] && output+=( repo-stack )
+ fi
+
+ if [[ -n ${compstate} ]] && [[ -z ${opts[(I)-p]} ]]; then
+ _describe -t repos ${output_type} output
+ else
+ print ${output}
+ fi
+}
+
+# available licenses
+#
+# optional args:
+# -r repo specify the repo to use; otherwise the default repo is used
+# -p print the output instead of using completion
+_licenses() {
+ typeset -A opts
+ zparseopts -E -A opts p r:
+
+ typeset -a licenses
+
+ if [[ -n ${opts[(I)-r]} ]]; then
+ repo=${opts[-r]}
+ else
+ repo=$(_repos -p -v DEFAULT:main-repo)
+ fi
+
+ repo_path=${$(_repos -p -v "${repo}:location")%/}
+ licenses=("${repo_path}"/licenses/*(.:t))
+
+ if [[ -n ${compstate} ]] && [[ -z ${opts[(I)-p]} ]]; then
+ _describe -t licenses 'licenses' licenses
+ else
+ print ${licenses}
+ fi
+}
+
+# global/local USE flag info
+#
+# optional args
+# -r repo specify the repo to use; otherwise the default repo is used
+# -p print the output instead of using completion
+# -g only show global use flags
+# -l only show local use flags
+# -o don't show use flag descriptions
+_use() {
+ typeset -A opts
+ zparseopts -E -A opts o p r:
+
+ local desc
+ typeset -a use use_global use_local
+
+ if [[ -n ${opts[(I)-r]} ]]; then
+ repo=${opts[-r]}
+ else
+ repo=$(_repos -p -v DEFAULT:main-repo)
+ fi
+
+ repo_path=${$(_repos -p -v "${repo}:location")%/}
+ [[ -f ${repo_path}/profiles/use.desc ]] && use_global=(${(S)${${(f)"$(<${repo_path}/profiles/use.desc)"}:#\#*}/ - /:})
+ [[ -f ${repo_path}/profiles/use.local.desc ]] && use_local=(${(S)${(S)${${(f)"$(<${repo_path}/profiles/use.local.desc)"}:#\#*}/*:/}/ - /:})
+
+ if [[ -z ${opts[(I)-g]} && -z ${opts[(I)-l]} ]]; then
+ # both global and local use flags are shown by default
+ use=( ${use_global} ${use_local} )
+ elif [[ -n ${opts[(I)-g]} ]]; then
+ use=${use_global}
+ desc='global '
+ elif [[ -n ${opts[(I)-l]} ]]; then
+ use=${use_local}
+ desc='local '
+ fi
+
+ # strip use flag descriptions
+ if [[ -n ${opts[(I)-o]} ]]; then
+ use=(${^use/:*/})
+ fi
+
+ if [[ -n ${compstate} ]] && [[ -z ${opts[(I)-p]} ]]; then
+ _describe -t use "${desc}use flag" use
+ else
+ print ${use}
+ fi
+}
+
+# package categories provided by repos
+#
+# optional args
+# -r repo specify the repo to use; otherwise the default repo is used
+# -p print the output instead of using completion
+_categories() {
+ typeset -A opts
+ zparseopts -E -A opts p r:
+
+ typeset -a categories
+
+ if [[ -n ${opts[(I)-r]} ]]; then
+ repo=${opts[-r]}
+ else
+ repo=$(_repos -p -v DEFAULT:main-repo)
+ fi
+
+ repo_path=${$(_repos -p -v "${repo}:location")%/}
+ [[ -f ${repo_path}/profiles/categories ]] && categories=(${${(f)"$(<${repo_path}/profiles/categories)"}:#\#*})
+
+ if [[ -n ${compstate} ]] && [[ -z ${opts[(I)-p]} ]]; then
+ _describe -t categories 'categories' categories
+ else
+ print ${categories}
+ fi
+}
+
+# arches provided by repos
+#
+# optional args
+# -r repo specify the repo to use; otherwise the default repo is used
+# -p print the output instead of using completion
+_arches() {
+ typeset -A opts
+ zparseopts -E -A opts p r:
+
+ typeset -a arches
+
+ if [[ -n ${opts[(I)-r]} ]]; then
+ repo=${opts[-r]}
+ else
+ repo=$(_repos -p -v DEFAULT:main-repo)
+ fi
+
+ repo_path=${$(_repos -p -v "${repo}:location")%/}
+ [[ -f ${repo_path}/profiles/arch.list ]] && arches=(${${(f)"$(<${repo_path}/profiles/arch.list)"}:#\#*})
+
+ if [[ -n ${compstate} ]] && [[ -z ${opts[(I)-p]} ]]; then
+ _describe -t arches 'arches' arches
+ else
+ print ${arches}
+ fi
+}
+
+# profiles provided by repos
+#
+# optional args
+# -r repo specify the repo to use; otherwise the default repo is used
+# -p print the output instead of using completion
+# -f output full, absolute profile paths
+_profiles() {
+ typeset -A opts
+ zparseopts -E -A opts a p f r:
+
+ local file repo repo_path arch path pstatus
+ typeset -a profiles
+
+ if [[ -n ${opts[(I)-r]} ]]; then
+ repo=${opts[-r]}
+ else
+ repo=$(_repos -p -v DEFAULT:main-repo)
+ fi
+
+ repo_path=${$(_repos -p -v "${repo}:location")%/}
+ file=${repo_path}/profiles/profiles.desc
+
+ if [[ -f ${file} ]]; then
+ while read -r arch path pstatus; do
+ # skip comments and empty lines
+ [[ -z ${arch} || ${arch} == '#'* ]] && continue
+ [[ -n ${opts[(I)-f]} ]] && path=${repo_path}/profiles/${path}
+ profiles+=(${path})
+ done < ${file}
+ fi
+
+ if [[ -n ${compstate} ]] && [[ -z ${opts[(I)-p]} ]]; then
+ _describe -t profiles 'profiles' profiles $*
+ else
+ print ${profiles}
+ fi
+}
diff --git a/data/share/bash-completion/completions/pquery b/data/share/bash-completion/completions/pquery
new file mode 100644
index 000000000..6bc0cbdf0
--- /dev/null
+++ b/data/share/bash-completion/completions/pquery
@@ -0,0 +1,153 @@
+# bash completion for pquery
+
+source "/usr/share/bash-completion/helpers/gentoo-common.sh"
+
+_pquery() {
+ local i cmd cur prev words cword split
+ _init_completion || return
+
+ local base_options=(
+ -h --help
+ --version
+ --debug
+ -q --quiet
+ -v --verbose
+ --color
+
+ # config options
+ --config
+ --domain
+
+ # repository matching options
+ --raw
+ --unfiltered
+ --virtuals
+ -r --repo
+ -E --ebuild-repos
+ -B --binary-repos
+ -I --installed
+ -A --all-repos
+
+ # package matching options
+ --all
+ --has-use
+ --license
+ --revdep
+ --revdep-pkgs
+ --restrict-revdep
+ --restrict-revdep-pkgs
+ -S --description
+ --eapi
+ --owns
+ --owns-re
+ --maintainer
+ --maintainer-name
+ --maintainer-email
+ --environment
+ --pkgset
+ -u --upgrade
+
+ # output options
+ -1, --first
+ -a, --atom
+ --cpv
+ -R
+ --slot
+ -n --no-version
+ --min
+ --max
+ --blame
+ --size
+ --contents
+ --highlight-dep
+ --print-revdep
+ --attr
+ --force-attr
+ --one-attr
+ --force-one-attr
+ )
+
+ local boolean_options=(
+ true
+ false
+ )
+
+ local attributes=(
+ all allmetadata
+
+ path repo source_repository
+ longdescription maintainers
+ category package fullver revision version
+ environment cbuild chost ctarget
+ inherited defined_phases
+
+ eapi description homepage
+ distfiles files uris fetchables
+ license slot subslot keywords iuse required_use use restrict properties
+
+ alldepends depend bdepend idepend pdepend rdepend
+ raw_alldepends raw_depend raw_bdepend raw_idepend raw_pdepend raw_rdepend
+ )
+
+ # find repo location
+ local REPO="$(git rev-parse --show-toplevel)"
+ for ((i = 1; i < ${COMP_CWORD}; i++)); do
+ case "${COMP_WORDS[i]}" in
+ -r | --repo)
+ REPO=$(_parsereposconf "${COMP_WORDS[i+1]}" location)
+ : ${REPO:=${COMP_WORDS[i+1]}}
+ ;;
+ esac
+ done
+
+ case ${prev} in
+ --color)
+ COMPREPLY=($(compgen -W "${boolean_options[*]}" -- "${cur}"))
+ ;;
+ --config)
+ COMPREPLY=($(compgen -f -- "${cur}"))
+ ;;
+ --domain)
+ COMPREPLY=()
+ ;;
+ --has-use | --license | --revdep | --revdep-pkgs | --restrict-revdep | --restrict-revdep-pkgs | \
+ -S | --description | --eapi | --owns | --owns-re | --environment | --pkgset | \
+ --maintainer | --maintainer-name | --maintainer-email)
+ COMPREPLY=()
+ ;;
+ --virtuals)
+ COMPREPLY=($(compgen -W "only disable" -- "${cur}"))
+ ;;
+ -r | --repo)
+ COMPREPLY=($(compgen -W "$(_parsereposconf -l)" -- "${cur}"))
+ COMPREPLY+=($(compgen -d -- "${cur}"))
+ ;;
+ --highlight-dep | --print-revdep)
+ COMPREPLY=()
+ ;;
+ --attr | --force-attr | --one-attr | --force-one-attr)
+ COMPREPLY=($(compgen -W "${attributes[*]}" -- "${cur}"))
+ ;;
+ --highlight-dep | --print-revdep)
+ COMPREPLY=()
+ ;;
+ *)
+ if [[ ${cur} == -* ]]; then
+ COMPREPLY+=($(compgen -W "${base_options[*]}" -- "${cur}"))
+ else
+ _list_repo_atoms() {
+ eval cd "${REPO}" || return
+ if [[ $cur == */* ]]; then
+ compgen -W "$(compgen -G "${cur}*" )" -- "${cur}"
+ else
+ compgen -W "$(compgen -G "${cur}*" -S / )" -- "${cur}"
+ fi
+ }
+ COMPREPLY+=( $(_list_repo_atoms) )
+ fi
+ ;;
+ esac
+}
+complete -F _pquery pquery
+
+# vim: set ft=bash sw=4 et sts=4 :
diff --git a/data/config/make.globals b/data/share/pkgcore/config/make.globals
index baf85593f..baf85593f 100644
--- a/data/config/make.globals
+++ b/data/share/pkgcore/config/make.globals
diff --git a/data/config/repos.conf b/data/share/pkgcore/config/repos.conf
index ecc8e8412..ecc8e8412 100644
--- a/data/config/repos.conf
+++ b/data/share/pkgcore/config/repos.conf
diff --git a/data/stubconfig/repos.conf b/data/share/pkgcore/stubconfig/repos.conf
index 61c65b2d4..61c65b2d4 100644
--- a/data/stubconfig/repos.conf
+++ b/data/share/pkgcore/stubconfig/repos.conf
diff --git a/data/stubrepo/metadata/layout.conf b/data/share/pkgcore/stubrepo/metadata/layout.conf
index dae6b4b06..dae6b4b06 100644
--- a/data/stubrepo/metadata/layout.conf
+++ b/data/share/pkgcore/stubrepo/metadata/layout.conf
diff --git a/data/stubrepo/profiles/arch.list b/data/share/pkgcore/stubrepo/profiles/arch.list
index 21d5bd8c7..21d5bd8c7 100644
--- a/data/stubrepo/profiles/arch.list
+++ b/data/share/pkgcore/stubrepo/profiles/arch.list
diff --git a/data/stubrepo/profiles/default/make.defaults b/data/share/pkgcore/stubrepo/profiles/default/make.defaults
index 12024de7b..12024de7b 100644
--- a/data/stubrepo/profiles/default/make.defaults
+++ b/data/share/pkgcore/stubrepo/profiles/default/make.defaults
diff --git a/data/stubrepo/profiles/profiles.desc b/data/share/pkgcore/stubrepo/profiles/profiles.desc
index 09e4e5a13..09e4e5a13 100644
--- a/data/stubrepo/profiles/profiles.desc
+++ b/data/share/pkgcore/stubrepo/profiles/profiles.desc
diff --git a/data/stubrepo/profiles/repo_name b/data/share/pkgcore/stubrepo/profiles/repo_name
index af495602f..af495602f 100644
--- a/data/stubrepo/profiles/repo_name
+++ b/data/share/pkgcore/stubrepo/profiles/repo_name
diff --git a/data/xml-schema/metadata.xsd b/data/share/pkgcore/xml-schema/metadata.xsd
index 3812045a6..3812045a6 100644
--- a/data/xml-schema/metadata.xsd
+++ b/data/share/pkgcore/xml-schema/metadata.xsd
diff --git a/data/share/zsh/site-functions/_pkgcore b/data/share/zsh/site-functions/_pkgcore
new file mode 100644
index 000000000..3e2aed84a
--- /dev/null
+++ b/data/share/zsh/site-functions/_pkgcore
@@ -0,0 +1,725 @@
+#compdef pclean pconfig pebuild pinspect pmaint pmerge pquery psite pcd
+
+SHELL_LIB=$(python -c 'from pkgcore import const; print(const.LIBDIR_PATH)')/shell/zsh/pkgcore.zsh
+source "${SHELL_LIB}" || print "$0: failed to load '${SHELL_LIB}'" >&2
+unset SHELL_LIB
+
+common_main_args=(
+ '(- :)'--version'[show version information and exit]'
+ '--config[use config config or skip loading system config]:config path:_files'
+ "--color[Color output]:yes/no:((y\:'yes' n\:'no'))"
+)
+
+common_output_args=(
+ '(- :)'{-h,--help}'[show help information and exit]'
+ '(--debug --help -h)--debug[enable debugging output]'
+ '(--quiet -q --verbose -v)'{-q,--quiet}'[suppress non-error output]'
+ '(--verbose -v --quiet -q)'{-v,--verbose}'[show verbose output]'
+)
+
+common_args=(
+ $common_main_args
+ $common_output_args
+)
+
+domain_common_args=(
+ $common_args
+ '--domain[domain to use for this operation]'
+)
+
+_pclean() {
+ local curcontext=$curcontext state state_descr line ret=1
+ typeset -A opt_args
+
+ _arguments -C \
+ $common_args \
+ '(-): :->command' \
+ '(-)*:: :->subcommand' \
+ && ret=0
+
+ case $state in
+ (command)
+ typeset -a subcommands
+
+ subcommands=(
+ dist:'remove distfiles'
+ pkg:'remove binpkgs'
+ tmp:'remove tmpdir entries'
+ )
+
+ _describe -t subcommands subcommand subcommands && ret=0
+
+ ;;
+ (subcommand)
+ curcontext=${curcontext%:*}-$line[1]:
+ typeset -a shared_opts file_opts repo_opts
+
+ shared_opts=(
+ {'(--pretend)-p','(-p)--pretend'}'[dry run without performing any changes]'
+ {'(--exclude)-x','(-x)--exclude'}'[list of packages to exclude from removal]'
+ {'(--exclude-file)-X','(-X)--exclude-file'}'[path to exclusion file]'
+ '*:target:'
+ )
+
+ file_opts=(
+ {'(--modified)-m','(-m)--modified'}'[skip files that have been modified since a given time]'
+ {'(--size)-s','(-s)--size'}'[skip files bigger than a given size]'
+ )
+
+ repo_opts=(
+ {'(--installed)-I','(-I)--installed'}'[skip files for packages that are currently installed]'
+ {'(--fetch-restricted)-f','(-f)--fetch-restricted'}'[skip fetch-restricted files]'
+ )
+
+ pkg_opts=(
+ '--source-repo[remove binpkgs with matching source repo]'
+ )
+
+ case $line[1] in
+ (dist)
+ _arguments -C -A '-*' \
+ $domain_common_args \
+ $shared_opts \
+ $file_opts \
+ $repo_opts \
+ {'(--ignore-failures)-i','(-i)--ignore-failures'}'[ignore checksum parsing errors]' \
+ && ret=0
+ ;;
+ (pkg)
+ _arguments -C -A '-*' \
+ $domain_common_args \
+ $shared_opts \
+ $file_opts \
+ $repo_opts \
+ $pkg_opts \
+ && ret=0
+ ;;
+ (tmp)
+ _arguments -C -A '-*' \
+ $domain_common_args \
+ $shared_opts \
+ {'(--all)-a','(-a)--all'}'[wipe the entire tmpdir]' \
+ && ret=0
+ ;;
+ (*)
+ _nothing
+ ;;
+ esac
+ ;;
+ esac
+
+ return ret
+}
+
+_pconfig() {
+ local curcontext=$curcontext state state_descr line ret=1
+ typeset -A opt_args
+
+ _arguments -C \
+ $common_args \
+ '(-): :->command' \
+ '(-)*:: :->subcommand' \
+ && ret=0
+
+ case $state in
+ (command)
+ typeset -a subcommands
+
+ subcommands=(
+ classes:'list all classes referenced by the config'
+ describe_class:'describe the arguments a class needs, how to use it in a config'
+ uncollapsable:'show configuration objects that could not be collapsed/instantiated'
+ dump:'dump the entire configuration'
+ configurables:'list registered configurables (may not be complete)'
+ dump-uncollapsed:'dump the configuration in a raw, uncollapsed form'
+ package:"invoke a package's custom configuration scripts"
+ world:'inspect and modify the world file'
+ )
+
+ _describe -t subcommands subcommand subcommands && ret=0
+
+ ;;
+ (subcommand)
+ curcontext=${curcontext%:*}-$line[1]:
+
+ case $line[1] in
+ (classes|uncollapsable|dump-uncollapsed)
+ _arguments -C -A '-*' \
+ $common_output_args \
+ && ret=0
+ ;;
+ (describe_class)
+ _arguments -C -A '-*' \
+ $common_output_args \
+ '*:classes' \
+ && ret=0
+ ;;
+ (dump|configurables)
+ _arguments -C -A '-*' \
+ $common_output_args \
+ '*:type' \
+ && ret=0
+ ;;
+ (package)
+ _arguments -C -A '-*' \
+ $domain_common_args \
+ '*:restriction or atom' \
+ && ret=0
+ ;;
+ (world)
+ _arguments -C -A '-*' \
+ $domain_common_args \
+ '(- :)'{-l,--list}'[list the current world file contents for this domain]' \
+ '*'{-r,--remove}'[remove an entry from the world file]:package atom:' \
+ '*'{-a,--add}'[add an entry to the world file]:package atom:' \
+ && ret=0
+ ;;
+ (*)
+ _nothing
+ ;;
+ esac
+ ;;
+ esac
+
+ return ret
+}
+
+_pebuild() {
+ local curcontext=$curcontext state state_descr line ret=1
+ typeset -A opt_args
+
+ _arguments -C \
+ $domain_common_args \
+ "--no-auto[run just the specified phases; it's up to the invoker to get the order right]" \
+ '(-): :->atom-or-ebuild' \
+ '(-)*:: :->phase' \
+ && ret=0
+
+ case $state in
+ (atom-or-ebuild)
+ # complete ebuilds before directories
+ zstyle ':completion:*' file-patterns '*%p(^-/):other-files:ebuilds *(-/):directories:directories'
+
+ _arguments \
+ '*:ebuilds:_files -g \*.ebuild' \
+ && ret=0
+ ;;
+ (phase)
+ typeset -a phases
+
+ phases=(
+ setup:'run package specific setup actions or checks'
+ unpack:'unpack all the sources to the workdir'
+ prepare:'preparation of all sources such as applying patches'
+ configure:'run configuration steps'
+ compile:'run compilation steps'
+ test:'run test steps'
+ install:'install the package to the temp directory'
+ clean:"remove the package's temporary directory"
+ )
+
+ _describe -V -t phases phase phases && ret=0
+ ;;
+
+ (*)
+ _nothing
+ ;;
+ esac
+
+ return ret
+}
+
+_pinspect() {
+ local curcontext=$curcontext state state_descr line ret=1
+ typeset -A opt_args
+
+ _arguments -C \
+ $common_args \
+ '(-): :->command' \
+ '(-)*:: :->subcommand' \
+ && ret=0
+
+ case $state in
+ (command)
+ typeset -a subcommands
+
+ subcommands=(
+ pkgsets:'pkgset related introspection'
+ eapi_usage:'report of eapi usage for targeted repos'
+ license_usage:'report of license usage for targeted repos'
+ eclass_usage:'report of eclass usage for targeted repos'
+ mirror_usage:'report of SRC_URI mirror usage for targeted repos'
+ distfiles_usage:'report detailing distfiles space usage for targeted repos'
+ query:'auxiliary access to ebuild/repository info via portageq akin API'
+ portageq:'portageq compatible interface to query commands'
+ profile:'profile related querying'
+ digests:'identify what packages are missing digest info'
+ )
+
+ _describe -t subcommands subcommand subcommands && ret=0
+
+ ;;
+ (subcommand)
+ curcontext=${curcontext%:*}-$line[1]:
+
+ typeset -a historical_repo_data_opts
+ historical_repo_data_opts=(
+ '(- :)'{-h,--help}'[show help information and exit]'
+ '--no-final-summary[disable outputting a summary of data across all repos]'
+ '--sort-by-name[sort output by name, rather then by frequency]'
+ '--first[show only the first N detail items]:number'
+ '--last[show only the last N detail items]:number'
+ '*:repo:_repos -t siab'
+ )
+
+ case $line[1] in
+ (pkgsets)
+ _arguments -C -A '-*' \
+ '(- :)'{-h,--help}'[show help information and exit]' \
+ '--all[display info on all pkgsets]' \
+ ':pkgset:' \
+ && ret=0
+ ;;
+ ((eapi|license|eclass|mirror)_usage)
+ _arguments -C -A '-*' \
+ $historical_repo_data_opts \
+ && ret=0
+ ;;
+ (distfiles_usage)
+ _arguments -C -A '-*' \
+ '--no-repo-summary[disable outputting repo summaries]' \
+ '--no-detail[disable outputting a detail view of all repos]' \
+ '--include-nonmirrored[if set, nonmirrored distfiles will be included in the total]' \
+ '--include-restricted[if set, fetch restricted distfiles will be included in the total]' \
+ $historical_repo_data_opts \
+ && ret=0
+ ;;
+ (query)
+ _arguments -C \
+ '(- :)'{-h,--help}'[show help information and exit]' \
+ '(-): :->command' \
+ '(-)*:: :->subcommand' \
+ && ret=0
+
+ case $state in
+ (command)
+ typeset -a subcommands
+
+ subcommands=(
+ best_version:'return the maximum visble version for a given atom'
+ env_var:'return configuration defined variables'
+ get_profiles:'show available profiles for a given repo'
+ get_repo_path:'show repo path for a given repo'
+ get_repos:'return list of configured repos'
+ has_version:'return 0 if an atom is merged, 1 if not'
+ mass_best_version:'multiple best_version calls'
+ )
+
+ _describe -t subcommands subcommand subcommands && ret=0
+ ;;
+ (subcommand)
+ curcontext=${curcontext%:*}-$line[1]:
+
+ typeset -a subcmd_opts
+ query_subcmd_opts=(
+ '(- :)'{-h,--help}'[show help information and exit]'
+ '--eapi[limit all operations to just what the given EAPI supports]:EAPI'
+ '--use[override the use flags used for transitive USE deps]:USE'
+ '--domain[domain to use for this operation]:domain'
+ '--domain-at-root[specify the domain to use via its root path]:root path:_path_files -/'
+ )
+
+ case $line[1] in
+ (best_version|has_version|mass_best_version)
+ _arguments -C -A '-*' \
+ $subcmd_opts \
+ '*:package atom' \
+ && ret=0
+ ;;
+ (env_var)
+ _arguments -C -A '-*' \
+ $subcmd_opts \
+ '*:variable' \
+ && ret=0
+ ;;
+ (get_profiles|get_repo_path)
+ _arguments -C -A '-*' \
+ $subcmd_opts \
+ ':repo:_repos' \
+ && ret=0
+ ;;
+ (get_repos)
+ _arguments -C -A '-*' \
+ $subcmd_opts \
+ && ret=0
+ ;;
+ (*)
+ _nothing
+ ;;
+ esac
+ ;;
+ (*)
+ _nothing
+ ;;
+ esac
+ ;;
+ (portageq)
+ _arguments -C \
+ '(- :)'{-h,--help}'[show help information and exit]' \
+ '(-): :->command' \
+ '(-)*:: :->subcommand' \
+ && ret=0
+
+ case $state in
+ (command)
+ typeset -a subcommands
+
+ subcommands=(
+ best_version:'return the maximum visble version for a given atom'
+ envvar:'return configuration defined variables (deprecated)'
+ envvar2:'return configuration defined variables'
+ get_repo_news_path:'show the news path for a given repo'
+ get_repo_path:'show repo path for a given repo'
+ get_repos:'return list of configured repos'
+ has_version:'return 0 if an atom is merged, 1 if not'
+ mass_best_version:'multiple best_version calls'
+ match:'shorthand for `pquery --installed`'
+ )
+
+ _describe -t subcommands subcommand subcommands && ret=0
+ ;;
+ (subcommand)
+ curcontext=${curcontext%:*}-$line[1]:
+
+ typeset -a portageq_subcmd_opts
+ subcmd_opts=(
+ '(- :)'{-h,--help}'[show help information and exit]'
+ '--eapi[limit all operations to just what the given EAPI supports]:EAPI'
+ '--use[override the use flags used for transitive USE deps]:USE'
+ )
+
+ case $line[1] in
+ (best_version|has_version|mass_best_version|match)
+ _arguments -C -A '-*' \
+ $subcmd_opts \
+ '1:root path:_path_files -/' \
+ '2:package atom' \
+ && ret=0
+ ;;
+ (envvar|envvar2)
+ _arguments -C -A '-*' \
+ $subcmd_opts \
+ '1:root path:_path_files -/' \
+ '2:variable' \
+ && ret=0
+ ;;
+ (get_repo_path|get_repo_news_path)
+ _arguments -C -A '-*' \
+ $subcmd_opts \
+ '1:root path:_path_files -/' \
+ '2:repo:_repos' \
+ && ret=0
+ ;;
+ (get_repos)
+ _arguments -C -A '-*' \
+ $subcmd_opts \
+ && ret=0
+ ;;
+ (*)
+ _nothing
+ ;;
+ esac
+ ;;
+ (*)
+ _nothing
+ ;;
+ esac
+ ;;
+ (profile)
+ typeset -a profile_attrs
+ local profile_opts='-f'
+
+ profile_attrs=(
+ parent:'output the linearized tree of inherited parents'
+ eapi:'output EAPI support required for reading this profile'
+ deprecated:'dump deprecation notices, if any'
+ provided:'list all package.provided packages'
+ system:'output the system package set'
+ use_expand:'output the USE_EXPAND configuration for this profile'
+ iuse_effective:'output the IUSE_EFFECTIVE value for this profile'
+ masks:'inspect package masks'
+ unmasks:'inspect package unmasks'
+ bashrcs:'inspect bashrcs'
+ keywords:'inspect package.keywords'
+ accept_keywords:'inspect package.accept_keywords'
+ use:'inspect package.use'
+ masked_use:'inspect masked use flags'
+ stable_masked_use:'inspect stable masked use flags'
+ forced_use:'inspect forced use flags'
+ stable_forced_use:'inspect stable forced use flags'
+ defaults:'inspect defined configuration for this profile'
+ arch:'output the arch defined for this profile'
+ status:'output the status of this profile'
+ )
+
+ # only complete profiles from the specified repo
+ if (( words[(I)-r|--repo] )); then
+ local repo=${words[(( $words[(I)-r|--repo] + 1 ))]}
+ profile_opts="-r ${repo}"
+ fi
+
+ _arguments -C -A '-*' \
+ '(- :)'{-h,--help}'[show help information and exit]' \
+ {'(--repo)-r','(-r)--repo'}'[target repository]:repo:_repos' \
+ '1:profile attribute:(($profile_attrs))' \
+ "2:profile:_profiles ${profile_opts}" \
+ && ret=0
+ ;;
+ (digests)
+ _arguments -C -A '-*' \
+ '(- :)'{-h,--help}'[show help information and exit]' \
+ ':repo:_repos' \
+ && ret=0
+ ;;
+ (*)
+ _nothing
+ ;;
+ esac
+ ;;
+ esac
+ return ret
+}
+
+_pmaint() {
+ local curcontext=$curcontext state state_descr line ret=1
+ typeset -A opt_args
+
+ _arguments -C \
+ $common_args \
+ '(-): :->command' \
+ '(-)*:: :->subcommand' \
+ && ret=0
+
+ case $state in
+ (command)
+ typeset -a subcommands
+
+ subcommands=(
+ sync:'synchronize a local repository with its defined remote'
+ copy:'copy binpkgs between repositories; primarily useful for quickpkging a livefs pkg'
+ regen:'regenerate repository caches'
+ env-update:'update env.d and ldconfig'
+ mirror:'mirror the sources for a package in full'
+ )
+
+ _describe -t subcommands subcommand subcommands && ret=0
+ ;;
+ (subcommand)
+ curcontext=${curcontext%:*}-$line[1]:
+
+ case $line[1] in
+ (sync)
+ _arguments -C -w -S -s -A '-*' \
+ $common_output_args \
+ '*:repo:_repos' \
+ && ret=0
+ ;;
+ (copy)
+ _arguments -C -w -S -s -A '-*' \
+ $common_output_args \
+ {'(--source-repo)-s','(-s)--source-repo'}'[copy strictly from the supplied repository]:repo:_repos' \
+ {'(--ignore-missing)-i','(-i)--ignore-missing'}"[if a matching pkg already exists in the target, don't update it]" \
+ ':target repo:_repos' \
+ ':query:' \
+ && ret=0
+ ;;
+ (regen)
+ _arguments -C -w -S -s -A '-*' \
+ $common_output_args \
+ '--disable-eclass-caching[disable caching eclasses into functions (results in a ~2x slower regen process, only disable when debugging)]' \
+ {'(--threads)-t','(-t)--threads'}'[number of threads to use for regeneration (defaults to using all available processors]:number' \
+ '--force[force regeneration to occur regardless of staleness checks]' \
+ '--rsync[update timestamps for rsync repos]' \
+ '--use-local-desc[update local USE flag description cache (profiles/use.local.desc)]' \
+ '--pkg-desc-index[update package description cache (metadata/pkg_desc_index)]' \
+ '*:repo:_repos' \
+ && ret=0
+ ;;
+ (env-update)
+ _arguments -C -w -S -s -A '-*' \
+ $common_output_args \
+ '--skip-ldconfig[do not update etc/ldso.conf and ld.so.cache]' \
+ && ret=0
+ ;;
+ (mirror)
+ _arguments -C -w -S -s -A '-*' \
+ $common_output_args \
+ {'(--ignore-failures)-f','(-f)--ignore-failures'}'[if a failure occurs, keep going]' \
+ ':query:' \
+ && ret=0
+ ;;
+ (*)
+ _nothing
+ ;;
+ esac
+ ;;
+ esac
+
+ return ret
+}
+
+_pmerge() {
+ local curcontext=$curcontext state state_descr line ret=1
+ typeset -A opt_args
+ typeset -a pkg ops resolver output
+
+ pkg=(
+ {'(--newuse)-N','(-N)--newuse'}'[check for changed useflags in installed packages (implies -1)]'
+ )
+
+ ops=(
+ {'(--unmerge)-C','(-C)--unmerge'}'[unmerge a package]'
+ '--clean[remove installed packages not referenced by any target packages/sets]'
+ {'(--pretend)-p','(-p)--pretend'}"[do the resolution, but don't merge/fetch anything]"
+ '--ignore-failures[ignore failures while running all types of tasks]'
+ {'(--ask)-a','(-a)--ask'}'[do the resolution, but ask to merge/fetch anything]'
+ "--force[force merging to a repo, regardless of if it's frozen]"
+ {'(--fetchonly)-f','(-f)--fetchonly'}'[do only the fetch steps of the resolved plan]'
+ {'(--oneshot)-1','(-1)--oneshot'}'[do not record changes in the world file]'
+ )
+
+ resolver=(
+ {'(--upgrade)-u','(-u)--upgrade'}'[try to upgrade already installed packages/dependencies]'
+ {'(--downgrade)-d','(-d)--downgrade'}'[try to downgrade already installed packages/dependencies]'
+ {'(--deep)-D','(-D)--deep'}'[force the resolver to verify already installed dependencies]'
+ '--preload-vdb-state[enable preloading of the installed packages database]'
+ {'(--ignore-cycles)-i','(-i)--ignore-cycles'}"[ignore cycles if they're found to be unbreakable]"
+ "--with-bdeps[process build dependencies for built packages (by default they're ignored]"
+ {'(--nodeps)-O','(-O)--nodeps'}'[disable dependency resolution]'
+ {'(--noreplace)-n','(-n)--noreplace'}"[don't reinstall target atoms if they're already installed]"
+ {'(--buildpkg)-b','(-b)--buildpkg'}'[build binpkgs]'
+ {'(--usepkg)-k','(-k)--usepkg'}'[prefer to use binpkgs]'
+ {'(--usepkgonly)-K','(-K)--usepkgonly'}'[use only binpkgs]'
+ {'(--source-only)-S','(-S)--source-only'}'[use only source packages, no binpkgs]'
+ {'(--empty)-e','(-e)--empty'}'[force rebuilding of all involved packages]'
+ )
+
+ output=(
+ "--quiet-repo-display[use numbers to indicate repos instead of ::repo output in the package merge list]"
+ {'(--formatter)-F','(-F)--formatter'}'[output formatter to use]:formatter:((basic pkgcore portage portage-verbose))'
+ )
+
+ _arguments -C -w -S -s -A '-*' \
+ $domain_common_args \
+ $pkg \
+ $ops \
+ $resolver \
+ $output \
+ '*:target:' \
+ && ret=0
+
+ return ret
+}
+
+_pquery() {
+ local curcontext=$curcontext state state_descr line ret=1
+ typeset -A opt_args
+ typeset -a repo pkg output
+
+ repo=(
+ '--raw[disable configuration and filtering]'
+ '--no-filters[disable all license filtering and visibility filtering]'
+ "--virtuals[specific virtuals handling (everything is matched by default)]:options:((only\:'only match virtuals' disable\:'no matching virtuals'))"
+ {'(--repo)-r','(-r)--repo'}'[target repository]:repo:_repos -t seib'
+ {'(--ebuild-repos)-E','(-E)--ebuild-repos'}'[search all ebuild repos]'
+ {'(--binary-repos)-B','(-B)--binary-repos'}'[search all binary repos]'
+ {'(--installed)-I','(-I)--installed'}'[search installed pkgs]'
+ {'(--all-repos)-A','(-A)--all-repos'}'[search all repos including the vdb]'
+ )
+
+ pkg=(
+ '--all[match all packages (equivalent to "pquery *")]'
+ '--has-use[exact string match on a USE flag]:use flag:_use -o'
+ '--license[exact match on a license]:license:_licenses'
+ '--revdep[shorthand for --restrict-revdep atom --print-revdep atom]:pkg atom:'
+ '--revdep-pkgs[shorthand for --restrict-revdep-pkgs atom --print-revdep atom]:pkg atom:'
+ '--restrict-revdep[dependency on an atom]:pkg atom:'
+ '--restrict-revdep-pkgs[dependency on pkgs that match a specific atom]:pkg atom:'
+ {'(--description)-S','(-S)--description'}'[regexp search on description and longdescription]:description regex'
+ '--eapi[match packages using a given EAPI]'
+ '--owns[exact match on an owned file/dir]:path:_files'
+ '--owns-re[like "owns" but using a regexp for matching]:path regex:_files'
+ '--maintainer[comma-separated list of regexes to search for maintainers]'
+ '--maintainer-name[comma-separated list of maintainer name regexes to search for]'
+ '--maintainer-email[comma-separated list of maintainer email regexes to search for]'
+ '--maintainer-needed[match packages without a maintainer]'
+ '--environment[regexp search in environment.bz2]'
+ '--pkgset[find packages that match the given package set]'
+ {'(--upgrade)-u','(-u)--upgrade'}'[matched installed packages without best slotted version]'
+ )
+
+ output=(
+ {'(--first)-1','(-1)--first'}'[stop when first match is found]'
+ {'(--no-version)-n','(-n)--no-version'}'[collapse multiple matching versions together]'
+ '--min[show only the lowest version for each package]'
+ '--max[show only the highest version for each package]'
+ '--cpv[print the category/package-version]'
+ {'(--atom)-a','(-a)--atom'}'[print =cat/pkg-3 instead of cat/pkg-3 (implies --cpv, has no effect with --no-version)]'
+ "--attr[print this attribute's value (can be specified more than once)]"
+ '--force-attr[like --attr but accepts any string as attribute name instead of only explicitly supported names]'
+ '--one-attr[print one attribute, suppresses other output]'
+ '--force-one-attr[like --one-attr but accepts any string as attribute name instead of only explicitly supported names]'
+ '--one-attr[print one attribute, suppresses other output]'
+ '--size[display size of all files owned by the package]'
+ '--contents[list files owned by the package]'
+ '--highlight-dep[highlight dependencies matching this atom]'
+ '--blame[shorthand for --attr maintainers]'
+ '--print-revdep[print what condition(s) trigger a dep]'
+ )
+
+ _arguments -C \
+ $domain_common_args \
+ $repo \
+ $pkg \
+ $output \
+ '*:target:' \
+ && ret=0
+
+ return ret
+}
+
+_pcd() {
+ local curcontext=$curcontext state state_descr line ret=1
+ typeset -A opt_args
+
+ _arguments -C \
+ '(- :)'{-h,--help}'[show help information and exit]' \
+ '1:package atom' \
+ '2:repo:_repos -t sib' \
+ && ret=0
+
+ return ret
+}
+
+_psite() {
+ local curcontext=$curcontext state state_descr line ret=1
+ typeset -A opt_args
+
+ _arguments -C \
+ '(- :)'{-h,--help}'[show help information and exit]' \
+ '1:package atom' \
+ '2:repo:_repos -t sib' \
+ && ret=0
+
+ return ret
+}
+
+_pkgcore() {
+ local ret=1
+ _call_function ret _$service
+ return ret
+}
+
+_pkgcore
+
+# vim: set et sw=2 ts=2 ft=zsh: