From 536eead0b367f9365d1d1574aff3a37a56b96d47 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Fri, 8 Aug 2008 06:49:34 +0000 Subject: * Fix the default() implementation so that it maps the ebuild argument to the correct phase function. * Add --exclude-init-phases option to save_ebuild_env() for filtering out unnecessary functions and variables when creating environment.bz2. * Add support for default() and default_* functions that die in all ebuild phases so that improper use of these functions is quickly discovered. svn path=/main/trunk/; revision=11346 --- bin/ebuild.sh | 152 +++++++++++++++++++++++++++++++++++----------- bin/isolated-functions.sh | 23 +++++++ pym/portage/__init__.py | 12 +++- pym/portage/const.py | 2 +- 4 files changed, 151 insertions(+), 38 deletions(-) diff --git a/bin/ebuild.sh b/bin/ebuild.sh index b7612a384..6cd69b7e2 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -1014,15 +1014,9 @@ dyn_install() { # local variables can leak into the saved environment. unset f - ( - # To avoid environment.bz2 bloat, cleanse variables that are - # are no longer needed after src_install(). Don't cleanse from - # the global environment though, in case the user wants to repeat - # this phase (like with FEATURES=noauto and the ebuild command). - unset S _E_DOCDESTTREE_ _E_EXEDESTTREE_ - save_ebuild_env | filter_readonly_variables \ - --filter-sandbox --allow-extra-vars > environment - ) + save_ebuild_env --exclude-init-phases | filter_readonly_variables \ + --filter-sandbox --allow-extra-vars > environment + bzip2 -f9 environment cp "${EBUILD}" "${PF}.ebuild" @@ -1352,43 +1346,134 @@ remove_path_entry() { PATH="${stripped_path}" } -# @FUNCTION: source_all_bashrcs +# @FUNCTION: _ebuild_arg_to_phase # @DESCRIPTION: -# Source a relevant bashrc files and perform other miscellaneous -# environment initialization when appropriate: -# -# * If EAPI is set, define default_* functions provided by the current EAPI. -# -source_all_bashrcs() { - [ -n "$EBUILD_PHASE" ] || return - local x +# Translate a known ebuild(1) argument into the precise +# name of it's corresponding ebuild phase. +_ebuild_arg_to_phase() { + [ $# -ne 2 ] && die "expected exactly 2 args, got $#: $*" + local eapi=$1 + local arg=$2 + local phase_func="" + + case "$arg" in + setup) + phase_func=pkg_setup + ;; + nofetch) + phase_func=pkg_nofetch + ;; + unpack) + phase_func=src_unpack + ;; + configure) + ! hasq $eapi 0 1 2_pre1 && \ + phase_func=src_configure + ;; + compile) + phase_func=src_compile + ;; + test) + phase_func=src_test + ;; + install) + phase_func=src_install + ;; + preinst) + phase_func=pkg_preinst + ;; + postinst) + phase_func=pkg_postinst + ;; + prerm) + phase_func=pkg_prerm + ;; + postrm) + phase_func=pkg_postrm + ;; + esac + + [[ -z $phase_func ]] && return 1 + echo "$phase_func" + return 0 +} + +_ebuild_phase_funcs() { + [ $# -ne 2 ] && die "expected exactly 2 args, got $#: $*" + local eapi=$1 + local phase_func=$2 + local eapi_has_default_fns=$(hasq $eapi 0 1 2_pre1 && echo 0 || echo 1) local default_phases="pkg_nofetch src_unpack src_configure src_compile src_test" + local x default_func="" - if [[ -n $EAPI ]] && ! hasq "$EAPI" 0 1 2_pre1 ; then - for x in $default_phases ; do - eval "default_$x() { _default_$x \"\$@\" ; }" - done + [[ $eapi_has_default_fns = 1 ]] && \ + hasq $phase_func $default_phases && \ + default_func=$phase_func - [[ $(type -t src_configure) = function ]] || \ - src_configure() { _default_src_configure "$@" ; } + if [[ $eapi_has_default_fns = 1 ]] ; then - default() { - _default_${EBUILD_PHASE} - } + if [[ -n $default_func ]] ; then + + for x in $default_phases ; do + eval "default_$x() { _default_$x \"\$@\" ; }" + done + + [[ $(type -t src_configure) = function ]] || \ + src_configure() { _default_src_configure "$@" ; } + + eval "default() { + _default_$default_func "$@" + }" + + else + + for x in $default_phases ; do + eval "default_$x() { + die \"default_$x() is not supported in phase $default_func\" + }" + done + + eval "default() { + die \"default() is not supported with EAPI='$eapi' during phase $phase_func\" + }" + + fi else + for x in $default_phases ; do eval "default_$x() { - die \"default_$x() is not supported with EAPI='$EAPI'\" + die \"default_$x() is not supported with EAPI='$eapi' during phase $phase_func\" }" done default() { - die "default() is not supported with EAPI='$EAPI'" + die "default() is not supported with EAPI='$eapi' during phase $phase_func" } fi +} + +# @FUNCTION: source_all_bashrcs +# @DESCRIPTION: +# Source a relevant bashrc files and perform other miscellaneous +# environment initialization when appropriate. +# +# If EAPI is set then define functions provided by the current EAPI: +# +# * default_* aliases for the current EAPI phase functions +# * A "default" function which is an alias for the default phase +# function for the current phase. +# +source_all_bashrcs() { + [ -n "$EBUILD_PHASE" ] || return + local x + + if [[ -n $EAPI ]] ; then + local phase_func=$(_ebuild_arg_to_phase "$EAPI" $EBUILD_PHASE) + [[ -n $phase_func ]] && _ebuild_phase_funcs "$EAPI" $phase_func + fi local OCC="${CC}" OCXX="${CXX}" # source the existing profile.bashrc's. @@ -1823,12 +1908,9 @@ ebuild_main() { if [[ $EBUILD_PHASE == postinst ]] && [[ -n $PORTAGE_UPDATE_ENV ]]; then # Update environment.bz2 in case installation phases # need to pass some variables to uninstallation phases. - ( - unset S _E_DOCDESTTREE_ _E_EXEDESTTREE_ - save_ebuild_env | filter_readonly_variables \ - --filter-sandbox --allow-extra-vars | \ - bzip2 -c -f9 > "$PORTAGE_UPDATE_ENV" - ) + save_ebuild_env --exclude-init-phases | \ + filter_readonly_variables --filter-sandbox --allow-extra-vars \ + | bzip2 -c -f9 > "$PORTAGE_UPDATE_ENV" fi ;; unpack|configure|compile|test|clean|install) diff --git a/bin/isolated-functions.sh b/bin/isolated-functions.sh index 364df5bbb..378e03f91 100755 --- a/bin/isolated-functions.sh +++ b/bin/isolated-functions.sh @@ -507,9 +507,24 @@ hasq() { # @FUNCTION: save_ebuild_env # @DESCRIPTION: # echo the current environment to stdout, filtering out redundant info. +# +# --exclude-init-phases causes pkg_nofetch and src_* phase functions to +# be excluded from the output. These function are not needed for installation +# or removal of the packages, and can therefore be safely excluded. +# save_ebuild_env() { ( + if hasq --exclude-init-phases $* ; then + unset S _E_DOCDESTTREE_ _E_EXEDESTTREE_ + unset -f pkg_nofetch src_unpack src_configure \ + src_compile src_test src_install + if [[ -n $PYTHONPATH ]] ; then + export PYTHONPATH=${PYTHONPATH/${PORTAGE_PYM_PATH}:} + [[ -z $PYTHONPATH ]] && unset PYTHONPATH + fi + fi + # misc variables set by bash unset BASH HOSTTYPE IFS MACHTYPE OLDPWD \ OPTERR OPTIND OSTYPE PS4 PWD SHELL SHLVL @@ -528,6 +543,13 @@ save_ebuild_env() { # There's no need to bloat environment.bz2 with internally defined # functions and variables, so filter them out if possible. + for x in pkg_setup pkg_nofetch src_unpack src_configure \ + src_compile src_test src_install pkg_preinst pkg_postinst \ + pkg_prerm pkg_postrm ; do + unset -f {,_}default_$x + done + unset x + unset -f dump_trace die diefunc quiet_mode vecho elog_base eqawarn elog \ esyslog einfo einfon ewarn eerror ebegin _eend eend KV_major \ KV_minor KV_micro KV_to_int get_KV unset_colors set_colors has \ @@ -546,6 +568,7 @@ save_ebuild_env() { save_ebuild_env filter_readonly_variables preprocess_ebuild_env \ source_all_bashrcs ebuild_main \ ebuild_phase ebuild_phase_with_hooks \ + _ebuild_arg_to_phase _ebuild_phase_funcs default \ ${QA_INTERCEPTORS} # portage config variables and variables set directly by portage diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 4656a5de7..15766f9a0 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -4042,8 +4042,16 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks", "ebuild's files must be downloaded" print "!!! manually. See the comments in" + \ " the ebuild for more information.\n" - mysettings["EBUILD_PHASE"] = "unpack" - spawn(EBUILD_SH_BINARY + " nofetch", mysettings) + ebuild_phase = mysettings.get("EBUILD_PHASE") + try: + mysettings["EBUILD_PHASE"] = "nofetch" + spawn(_shell_quote(EBUILD_SH_BINARY) + \ + " nofetch", mysettings) + finally: + if ebuild_phase is None: + mysettings.pop("EBUILD_PHASE", None) + else: + mysettings["EBUILD_PHASE"] = ebuild_phase elif listonly: continue elif not filedict[myfile]: diff --git a/pym/portage/const.py b/pym/portage/const.py index 19d858b11..2958cf3ce 100644 --- a/pym/portage/const.py +++ b/pym/portage/const.py @@ -58,7 +58,7 @@ INCREMENTALS = ["USE", "USE_EXPAND", "USE_EXPAND_HIDDEN", "FEATURES", EBUILD_PHASES = ["setup", "unpack", "configure", "compile", "test", "install", "package", "preinst", "postinst","prerm", "postrm", - "other"] + "nofetch", "other"] EAPI = 1 -- cgit v1.2.3-1-g7c22