diff -urpN portage-2.2.0_alpha160.orig/bin/isolated-functions.sh portage-2.2.0_alpha160/bin/isolated-functions.sh --- portage-2.2.0_alpha160.orig/bin/isolated-functions.sh 2013-02-22 13:02:56.738295182 -0800 +++ portage-2.2.0_alpha160/bin/isolated-functions.sh 2013-02-22 13:04:33.766961208 -0800 @@ -17,7 +17,7 @@ assert() { done } -__assert_sigpipe_ok() { +__helpers_assert_sigpipe_ok() { # When extracting a tar file like this: # # bzip2 -dc foo.tar.bz2 | tar xof - @@ -32,15 +32,19 @@ __assert_sigpipe_ok() { # which says, "When a command terminates on a fatal # signal whose number is N, Bash uses the value 128+N # as the exit status." - local x pipestatus=${PIPESTATUS[*]} - for x in $pipestatus ; do + for x in ${pipestatus} ; do # Allow SIGPIPE through (128 + 13) - [[ $x -ne 0 && $x -ne ${PORTAGE_SIGPIPE_STATUS:-141} ]] && die "$@" + if [[ ${x} -ne 0 && ${x} -ne ${PORTAGE_SIGPIPE_STATUS:-141} ]] ; then + __helpers_die "${FUNCNAME}: error ${x}: $*" + return ${x} + fi done # Require normal success for the last process (tar). - [[ $x -eq 0 ]] || die "$@" + [[ ${x} -eq 0 ]] || __helpers_die "${FUNCNAME}: error ${x}: $*" || return ${x} + + return 0 } shopt -s extdebug @@ -92,28 +96,78 @@ nonfatal() { die "$FUNCNAME() not supported in this EAPI" fi if [[ $# -lt 1 ]]; then - die "$FUNCNAME(): Missing argument" + # Well they said nonfatal and forgot to finish their sentence. + # Something ain't right, to be sure, but die()ing here seems a bit + # pendantic and mean-spirited :) + local phase_str= + [[ -n ${EBUILD_PHASE} ]] && phase_str=" (${EBUILD_PHASE} phase)" + eerror "ERROR: ${CATEGORY}/${PF}${phase_str}:" + eerror " ${FUNCNAME}: Missing argument" + eerror + return 1 fi PORTAGE_NONFATAL=1 "$@" } +# Memorizing the return-code at the beginning of __helpers_die() +# and returning it unchanged (unless it's 0) is intended as a +# courtesy to invokers who may use a bash sequence like: +# +# failure_prone_action || \ +# __helpers_die "${FUNCNAME}: descriptive error message" || \ +# return $? +# +# as syntactic sugar for the following equivalent code: +# +# failure_prone_action +# ret=$? +# if [[ ${ret} -ne 0 ]] ; then +# __helpers_die "${FUNCNAME}: descriptive error message" +# return ${ret} +# fi +# +# However, beware: this trick will not work for positive +# conditionals because __helpers_die always returns a nonzero +# failure code (if it returns at all). Neither +# +# action_intended_to_fail && __helpers_die msg && return $? +# +# nor +# +# action_intended_to_fail && __helpers_die msg || return $? +# +# will work as intended. The following would be a clean, correct +# way to trigger __helpers_die() from a positive conditional: +# +# action_intended_to_fail && { +# __helpers_die "${FUNCNAME}: descriptive error message" +# return 1 +# } +# +# # NB: if this were the last command in your helper function, you +# # should "return 0" here, as $? is always nonzero at this point. +# __helpers_die() { - if ___eapi_helpers_can_die; then + local retcode=$? + (( retcode == 0 )) && retcode=1 + + if ___eapi_helpers_can_die && [[ "${PORTAGE_NONFATAL:-0}" != 1 ]]; then die "$@" else - echo -e "$@" >&2 + local phase_str= + [[ -n ${EBUILD_PHASE} ]] && phase_str=" (${EBUILD_PHASE} phase)" + ewarn "WARNING: ${CATEGORY}/${PF}${phase_str}:" + ewarn " ${FUNCNAME}: ${*:-(no error message)}" + ewarn fi + + return "${retcode}" } die() { local IFS=$' \t\n' - if [[ $PORTAGE_NONFATAL -eq 1 ]]; then - echo -e " $WARN*$NORMAL ${FUNCNAME[1]}: WARNING: $@" >&2 - return 1 - fi - set +e if [ -n "${QA_INTERCEPTORS}" ] ; then # die was called from inside inherit. We need to clean up diff -urpN portage-2.2.0_alpha160.orig/bin/phase-helpers.sh portage-2.2.0_alpha160/bin/phase-helpers.sh --- portage-2.2.0_alpha160.orig/bin/phase-helpers.sh 2013-02-22 13:02:56.738295182 -0800 +++ portage-2.2.0_alpha160/bin/phase-helpers.sh 2013-02-22 13:41:06.931031864 -0800 @@ -94,6 +94,7 @@ insopts() { export INSOPTIONS="$@" # `install` should never be called with '-s' ... + # FIXME: strip -s and call __helpers_die? has -s ${INSOPTIONS} && die "Never call insopts() with -s" } @@ -105,6 +106,7 @@ exeopts() { export EXEOPTIONS="$@" # `install` should never be called with '-s' ... + # FIXME: strip -s and call __helpers_die? has -s ${EXEOPTIONS} && die "Never call exeopts() with -s" } @@ -112,6 +114,7 @@ libopts() { export LIBOPTIONS="$@" # `install` should never be called with '-s' ... + # FIXME: strip -s and call __helpers_die? has -s ${LIBOPTIONS} && die "Never call libopts() with -s" } @@ -154,12 +157,14 @@ keepdir() { | tr "\n" "\0" | \ while read -r -d $'\0' ; do >> "$REPLY" || \ - die "Failed to recursively create .keep files" + __helpers_die "Failed to recursively create .keep files" || \ + return $? done else for x in "$@"; do >> "${ED}${x}/.keep_${CATEGORY}_${PN}-${SLOT%/*}" || \ - die "Failed to create .keep in ${ED}${x}" + __helpers_die "Failed to create .keep in ${ED}${x}" || \ + return $? done fi } @@ -288,7 +293,7 @@ unpack() { local suffix local myfail local eapi=${EAPI:-0} - [ -z "$*" ] && die "Nothing passed to the 'unpack' command" + [ -z "$*" ] && { __helpers_die "Nothing passed to the 'unpack' command" ; return 1 ; } for x in "$@"; do __vecho ">>> Unpacking ${x} to ${PWD}" @@ -301,65 +306,72 @@ unpack() { if [[ ${x} == "./"* ]] ; then srcdir="" elif [[ ${x} == ${DISTDIR%/}/* ]] ; then - die "Arguments to unpack() cannot begin with \${DISTDIR}." + __helpers_die "Arguments to unpack() cannot begin with \${DISTDIR}." + return 1 elif [[ ${x} == "/"* ]] ; then - die "Arguments to unpack() cannot be absolute" + __helpers_die "Arguments to unpack() cannot be absolute" + return 1 else srcdir="${DISTDIR}/" fi - [[ ! -s ${srcdir}${x} ]] && die "${x} does not exist" + [[ -s ${srcdir}${x} ]] || __helpers_die "${x} does not exist" || return 1 __unpack_tar() { if [ "${y}" == "tar" ]; then $1 -c -- "$srcdir$x" | tar xof - - __assert_sigpipe_ok "$myfail" + __helpers_assert_sigpipe_ok "$myfail" || return $? else local cwd_dest=${x##*/} cwd_dest=${cwd_dest%.*} - $1 -c -- "${srcdir}${x}" > "${cwd_dest}" || die "$myfail" + $1 -c -- "${srcdir}${x}" > "${cwd_dest}" || \ + __helpers_die "$myfail" || return $? fi } myfail="failure unpacking ${x}" case "${suffix}" in tar) - tar xof "$srcdir$x" || die "$myfail" + tar xof "$srcdir$x" || __helpers_die "$myfail" || return $? ;; tgz) - tar xozf "$srcdir$x" || die "$myfail" + tar xozf "$srcdir$x" || __helpers_die "$myfail" || return $? ;; tbz|tbz2) ${PORTAGE_BUNZIP2_COMMAND:-${PORTAGE_BZIP2_COMMAND} -d} -c -- "$srcdir$x" | tar xof - - __assert_sigpipe_ok "$myfail" + __helpers_assert_sigpipe_ok "$myfail" || return $? ;; zip|jar) # unzip will interactively prompt under some error conditions, # as reported in bug #336285 ( set +x ; while true ; do echo n || break ; done ) | \ - unzip -qo "${srcdir}${x}" || die "$myfail" + unzip -qo "${srcdir}${x}" || \ + { __helpers_die "$myfail" || return 1 ; } ;; gz|z) - __unpack_tar "gzip -d" + __unpack_tar "gzip -d" || return $? ;; bz2|bz) - __unpack_tar "${PORTAGE_BUNZIP2_COMMAND:-${PORTAGE_BZIP2_COMMAND} -d}" + __unpack_tar "${PORTAGE_BUNZIP2_COMMAND:-${PORTAGE_BZIP2_COMMAND} -d}" || \ + return $? ;; 7z) local my_output my_output="$(7z x -y "${srcdir}${x}")" if [ $? -ne 0 ]; then + local my_result=$? echo "${my_output}" >&2 - die "$myfail" + __helpers_die "$myfail" + return ${my_result} fi ;; rar) - unrar x -idq -o+ "${srcdir}${x}" || die "$myfail" + unrar x -idq -o+ "${srcdir}${x}" || __helpers_die "$myfail" || return $? ;; lha|lzh) - lha xfq "${srcdir}${x}" || die "$myfail" + lha xfq "${srcdir}${x}" || __helpers_die "$myfail" || return $? ;; a) - ar x "${srcdir}${x}" || die "$myfail" + ar x "${srcdir}${x}" || __helpers_die "$myfail" || return $? ;; deb) # Unpacking .deb archives can not always be done with @@ -369,31 +381,35 @@ unpack() { # installed. if type -P deb2targz > /dev/null; then y=${x##*/} - local created_symlink=0 - if [ ! "$srcdir$x" -ef "$y" ] ; then + if [ ! "${srcdir}${x}" -ef "${y}" ] ; then # deb2targz always extracts into the same directory as # the source file, so create a symlink in the current # working directory if necessary. - ln -sf "$srcdir$x" "$y" || die "$myfail" - created_symlink=1 - fi - deb2targz "$y" || die "$myfail" - if [ $created_symlink = 1 ] ; then + ln -sf "${srcdir}${x}" "${y}" || \ + __helpers_die "${myfail}" || return $? + deb2targz "${y}" || \ + __helpers_die "${myfail}" || return $? # Clean up the symlink so the ebuild # doesn't inadvertently install it. - rm -f "$y" + rm -f "${y}" || \ + __helpers_die "${myfail}" || return $? + else + deb2targz "${y}" || \ + __helpers_die "${myfail}" || return $? fi - mv -f "${y%.deb}".tar.gz data.tar.gz || die "$myfail" + mv -f "${y%.deb}".tar.gz data.tar.gz || \ + __helpers_die "${myfail}" || return $? else - ar x "$srcdir$x" || die "$myfail" + ar x "${srcdir}${x}" \ + || __helpers_die "${myfail}" || return $? fi ;; lzma) - __unpack_tar "lzma -d" + __unpack_tar "lzma -d" || return $? ;; xz) if ___eapi_unpack_supports_xz; then - __unpack_tar "xz -d" + __unpack_tar "xz -d" || return $? else __vecho "unpack ${x}: file format not recognized. Ignoring." fi @@ -405,8 +421,8 @@ unpack() { done # Do not chmod '.' since it's probably ${WORKDIR} and PORTAGE_WORKDIR_MODE # should be preserved. - find . -mindepth 1 -maxdepth 1 ! -type l -print0 | \ - ${XARGS} -0 chmod -fR a+rX,u+w,g-w,o-w + find . -mindepth 1 -maxdepth 1 ! -type l -execdir chmod -fR a+rX,u+w,g-w,o-w '{}' + || \ + __helpers_die "${myfail}" || return $? } econf() { @@ -417,7 +433,7 @@ econf() { fi __hasg() { - local x s=$1 + local x s="$1" shift for x ; do [[ ${x} == ${s} ]] && echo "${x}" && return 0 ; done return 1 @@ -443,10 +459,14 @@ econf() { if [[ -n $CONFIG_SHELL && \ "$(head -n1 "$ECONF_SOURCE/configure")" =~ ^'#!'[[:space:]]*/bin/sh([[:space:]]|$) ]] ; then # preserve timestamp, see bug #440304 - touch -r "$ECONF_SOURCE/configure" "$ECONF_SOURCE/configure._portage_tmp_.$$" || die + touch -r "$ECONF_SOURCE/configure" "$ECONF_SOURCE/configure._portage_tmp_.$$" || \ + __helpers_die || return $? sed -e "1s:^#![[:space:]]*/bin/sh:#!$CONFIG_SHELL:" -i "$ECONF_SOURCE/configure" || \ - die "Substition of shebang in '$ECONF_SOURCE/configure' failed" - touch -r "$ECONF_SOURCE/configure._portage_tmp_.$$" "$ECONF_SOURCE/configure" || die + __helpers_die "Substition of shebang in '$ECONF_SOURCE/configure' failed" || \ + return $? + touch -r "$ECONF_SOURCE/configure._portage_tmp_.$$" "$ECONF_SOURCE/configure" || \ + __helpers_die "Failed to touch $ECONF_SOURCE/configure._portage_tmp_.$$" || \ + return $? rm -f "$ECONF_SOURCE/configure._portage_tmp_.$$" fi if [ -e "${EPREFIX}"/usr/share/gnuconfig/ ]; then @@ -515,12 +535,15 @@ econf() { echo "!!! Please attach the following file when seeking support:" echo "!!! ${PWD}/config.log" fi - die "econf failed" + __helpers_die "econf failed" + return 1 fi elif [ -f "${ECONF_SOURCE}/configure" ]; then - die "configure is not executable" + __helpers_die "configure is not executable" + return 1 else - die "no configure script found" + __helpers_die "no configure script found" + return 1 fi } @@ -562,9 +585,10 @@ einstall() { sysconfdir="${ED}etc" \ ${LOCAL_EXTRA_EINSTALL} \ ${MAKEOPTS} ${EXTRA_EMAKE} -j1 \ - "$@" install || die "einstall failed" + "$@" install || __helpers_die "einstall failed" || return $? else - die "no Makefile found" + __helpers_die "no Makefile found" + return 1 fi } @@ -626,7 +650,7 @@ __eapi2_src_configure() { __eapi2_src_compile() { if [ -f Makefile ] || [ -f GNUmakefile ] || [ -f makefile ]; then - emake || die "emake failed" + emake || __helpers_die "emake failed" || return $? fi } @@ -653,7 +677,8 @@ __eapi4_src_install() { # @DESCRIPTION: # Return true if given package is installed. Otherwise return false. # Callers may override the ROOT variable in order to match packages from an -# alternative ROOT. +# alternative ROOT. Note that we do not use __helpers_die here because +# a nonzero return value does not indicate failure. has_version() { local atom eroot host_root=false root=${ROOT} @@ -667,7 +692,7 @@ has_version() { if ${host_root} ; then if ! ___eapi_best_version_and_has_version_support_--host-root; then - die "${FUNCNAME[0]}: option --host-root is not supported with EAPI ${EAPI}" + die ${FUNCNAME[0]}: option --host-root is not supported with EAPI ${EAPI} fi root=/ fi @@ -706,7 +731,8 @@ has_version() { # @DESCRIPTION: # Returns the best/most-current match. # Callers may override the ROOT variable in order to match packages from an -# alternative ROOT. +# alternative ROOT. Note that we do not use __helpers_die here because in +# this case non-zero return values have nonfailing semantic significance. best_version() { local atom eroot host_root=false root=${ROOT} @@ -758,7 +784,7 @@ if ___eapi_has_master_repositories; then master_repositories() { local output repository=$1 retval shift - [[ $# -gt 0 ]] && die "${FUNCNAME[0]}: unused argument(s): $*" + [[ $# -gt 0 ]] && { __helpers_die "${FUNCNAME[0]}: unused argument(s): $*" ; return 1 ; } if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then "${PORTAGE_BIN_PATH}/ebuild-ipc" master_repositories "${EROOT}" "${repository}" @@ -790,7 +816,7 @@ if ___eapi_has_repository_path; then repository_path() { local output repository=$1 retval shift - [[ $# -gt 0 ]] && die "${FUNCNAME[0]}: unused argument(s): $*" + [[ $# -gt 0 ]] && { __helpers_die "${FUNCNAME[0]}: unused argument(s): $*" ; return 1 ; } if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then "${PORTAGE_BIN_PATH}/ebuild-ipc" repository_path "${EROOT}" "${repository}" @@ -821,7 +847,7 @@ fi if ___eapi_has_available_eclasses; then available_eclasses() { local output repository=${PORTAGE_REPO_NAME} retval - [[ $# -gt 0 ]] && die "${FUNCNAME[0]}: unused argument(s): $*" + [[ $# -gt 0 ]] && { __helpers_die "${FUNCNAME[0]}: unused argument(s): $*" ; return 1 ; } if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then "${PORTAGE_BIN_PATH}/ebuild-ipc" available_eclasses "${EROOT}" "${repository}" @@ -853,7 +879,7 @@ if ___eapi_has_eclass_path; then eclass_path() { local eclass=$1 output repository=${PORTAGE_REPO_NAME} retval shift - [[ $# -gt 0 ]] && die "${FUNCNAME[0]}: unused argument(s): $*" + [[ $# -gt 0 ]] && { __helpers_die "${FUNCNAME[0]}: unused argument(s): $*" ; return 1 ; } if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then "${PORTAGE_BIN_PATH}/ebuild-ipc" eclass_path "${EROOT}" "${repository}" "${eclass}" @@ -885,7 +911,7 @@ if ___eapi_has_license_path; then license_path() { local license=$1 output repository=${PORTAGE_REPO_NAME} retval shift - [[ $# -gt 0 ]] && die "${FUNCNAME[0]}: unused argument(s): $*" + [[ $# -gt 0 ]] && { __helpers_die "${FUNCNAME[0]}: unused argument(s): $*" ; return 1 ; } if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then "${PORTAGE_BIN_PATH}/ebuild-ipc" license_path "${EROOT}" "${repository}" "${license}" diff -urpN portage-2.2.0_alpha160.orig/bin/save-ebuild-env.sh portage-2.2.0_alpha160/bin/save-ebuild-env.sh --- portage-2.2.0_alpha160.orig/bin/save-ebuild-env.sh 2013-01-23 17:32:01.000000000 -0800 +++ portage-2.2.0_alpha160/bin/save-ebuild-env.sh 2013-02-22 13:04:33.766961208 -0800 @@ -46,7 +46,7 @@ __save_ebuild_env() { done unset x - unset -f assert __assert_sigpipe_ok \ + unset -f assert __helpers_assert_sigpipe_ok \ __dump_trace die \ __quiet_mode __vecho __elog_base eqawarn elog \ einfo einfon ewarn eerror ebegin __eend eend KV_major \ diff -urpN portage-2.2.0_alpha160.orig/doc/package/ebuild/eapi/4.docbook portage-2.2.0_alpha160/doc/package/ebuild/eapi/4.docbook --- portage-2.2.0_alpha160.orig/doc/package/ebuild/eapi/4.docbook 2013-01-23 17:32:01.000000000 -0800 +++ portage-2.2.0_alpha160/doc/package/ebuild/eapi/4.docbook 2013-02-22 13:04:33.766961208 -0800 @@ -11,9 +11,14 @@ The dohard and dosed helpers from previo
All helpers die on failure -All helpers now die automatically whenever some sort of error occurs. -Helper calls may be prefixed with the 'nonfatal' helper in order -to prevent errors from being fatal. +All helpers now die automatically whenever any meaningful error occurs. +The 'nonfatal' helper may be used to effect the error-handling behavior +of EAPIs 0-3, in which recoverable errors emit a warning and return +nonzero exit-codes to invokees. It is used by prepending 'nonfatal' to any helper +invocation; for example, by replacing 'dodoc /foo.txt' with 'nonfatal dodoc /foo.txt'. +The 'nonfatal' helper should not be applied to +statements other than helper invocations, and has no effect on the 'die' +and 'assert' helpers.