On sob, 2017-03-11 at 16:03 +0100, Michał Górny wrote:
> Move epatch and epatch_user (along with the descriptions for all their
> variables) into a dedicated epatch.eclass. This function is very
> complex, therefore it benefits from separate eclass and a dedicated
> maintainer. Furthermore, it is mostly obsoleted by eapply* in EAPI 6.
> 
> The new eclass is implicitly inherited by eutils to preserve
> compatibility. However, the inherit will be removed in EAPI 7,
> and the ebuilds should switch to inheriting epatch directly or using
> eapply*.
> 
> Thanks to Ulrich Müller for doing the necessary research.
> ---
>  eclass/epatch.eclass | 458 
> +++++++++++++++++++++++++++++++++++++++++++++++++++
>  eclass/eutils.eclass | 440 +------------------------------------------------
>  2 files changed, 459 insertions(+), 439 deletions(-)
>  create mode 100644 eclass/epatch.eclass
> 
> diff --git a/eclass/epatch.eclass b/eclass/epatch.eclass
> new file mode 100644
> index 000000000000..fb0a10b53583
> --- /dev/null
> +++ b/eclass/epatch.eclass
> @@ -0,0 +1,458 @@
> +# Copyright 1999-2017 Gentoo Foundation
> +# Distributed under the terms of the GNU General Public License v2
> +
> +# @ECLASS: epatch.eclass
> +# @MAINTAINER:
> +# base-sys...@gentoo.org
> +# @BLURB: easy patch application functions
> +# @DESCRIPTION:
> +# An eclass providing epatch and epatch_user functions to easily apply
> +# patches to ebuilds. Mostly superseded by eapply* in EAPI 6.
> +
> +if [[ -z ${_EPATCH_ECLASS} ]]; then
> +
> +# @VARIABLE: EPATCH_SOURCE
> +# @DESCRIPTION:
> +# Default directory to search for patches.
> +EPATCH_SOURCE="${WORKDIR}/patch"
> +# @VARIABLE: EPATCH_SUFFIX
> +# @DESCRIPTION:
> +# Default extension for patches (do not prefix the period yourself).
> +EPATCH_SUFFIX="patch.bz2"
> +# @VARIABLE: EPATCH_OPTS
> +# @DESCRIPTION:
> +# Options to pass to patch.  Meant for ebuild/package-specific tweaking
> +# such as forcing the patch level (-p#) or fuzz (-F#) factor.  Note that
> +# for single patch tweaking, you can also pass flags directly to epatch.
> +EPATCH_OPTS=""
> +# @VARIABLE: EPATCH_COMMON_OPTS
> +# @DESCRIPTION:
> +# Common options to pass to `patch`.  You probably should never need to
> +# change these.  If you do, please discuss it with base-system first to
> +# be sure.
> +# @CODE
> +#    -g0 - keep RCS, ClearCase, Perforce and SCCS happy #24571
> +#    --no-backup-if-mismatch - do not leave .orig files behind
> +#    -E - automatically remove empty files
> +# @CODE
> +EPATCH_COMMON_OPTS="-g0 -E --no-backup-if-mismatch"
> +# @VARIABLE: EPATCH_EXCLUDE
> +# @DESCRIPTION:
> +# List of patches not to apply.       Note this is only file names,
> +# and not the full path.  Globs accepted.
> +EPATCH_EXCLUDE=""
> +# @VARIABLE: EPATCH_SINGLE_MSG
> +# @DESCRIPTION:
> +# Change the printed message for a single patch.
> +EPATCH_SINGLE_MSG=""
> +# @VARIABLE: EPATCH_MULTI_MSG
> +# @DESCRIPTION:
> +# Change the printed message for multiple patches.
> +EPATCH_MULTI_MSG="Applying various patches (bugfixes/updates) ..."
> +# @VARIABLE: EPATCH_FORCE
> +# @DESCRIPTION:
> +# Only require patches to match EPATCH_SUFFIX rather than the extended
> +# arch naming style.
> +EPATCH_FORCE="no"
> +# @VARIABLE: EPATCH_USER_EXCLUDE
> +# @DEFAULT_UNSET
> +# @DESCRIPTION:
> +# List of patches not to apply.       Note this is only file names,
> +# and not the full path.  Globs accepted.
> +
> +# @FUNCTION: epatch
> +# @USAGE: [options] [patches] [dirs of patches]
> +# @DESCRIPTION:
> +# epatch is designed to greatly simplify the application of patches.  It can
> +# process patch files directly, or directories of patches.  The patches may 
> be
> +# compressed (bzip/gzip/etc...) or plain text.  You generally need not 
> specify
> +# the -p option as epatch will automatically attempt -p0 to -p4 until things
> +# apply successfully.
> +#
> +# If you do not specify any patches/dirs, then epatch will default to the
> +# directory specified by EPATCH_SOURCE.
> +#
> +# Any options specified that start with a dash will be passed down to patch
> +# for this specific invocation.  As soon as an arg w/out a dash is found, 
> then
> +# arg processing stops.
> +#
> +# When processing directories, epatch will apply all patches that match:
> +# @CODE
> +#    if ${EPATCH_FORCE} != "yes"
> +#            ??_${ARCH}_foo.${EPATCH_SUFFIX}
> +#    else
> +#            *.${EPATCH_SUFFIX}
> +# @CODE
> +# The leading ?? are typically numbers used to force consistent patch 
> ordering.
> +# The arch field is used to apply patches only for the host architecture with
> +# the special value of "all" means apply for everyone.  Note that using 
> values
> +# other than "all" is highly discouraged -- you should apply patches all the
> +# time and let architecture details be detected at configure/compile time.
> +#
> +# If EPATCH_SUFFIX is empty, then no period before it is implied when 
> searching
> +# for patches to apply.
> +#
> +# Refer to the other EPATCH_xxx variables for more customization of behavior.
> +epatch() {
> +     _epatch_draw_line() {
> +             # create a line of same length as input string
> +             [[ -z $1 ]] && set "$(printf "%65s" '')"
> +             echo "${1//?/=}"
> +     }
> +
> +     unset P4CONFIG P4PORT P4USER # keep perforce at bay #56402
> +
> +     # First process options.  We localize the EPATCH_OPTS setting
> +     # from above so that we can pass it on in the loop below with
> +     # any additional values the user has specified.
> +     local EPATCH_OPTS=( ${EPATCH_OPTS[*]} )
> +     while [[ $# -gt 0 ]] ; do
> +             case $1 in
> +             -*) EPATCH_OPTS+=( "$1" ) ;;
> +             *) break ;;
> +             esac
> +             shift
> +     done
> +
> +     # Let the rest of the code process one user arg at a time --
> +     # each arg may expand into multiple patches, and each arg may
> +     # need to start off with the default global EPATCH_xxx values
> +     if [[ $# -gt 1 ]] ; then
> +             local m
> +             for m in "$@" ; do
> +                     epatch "${m}"
> +             done
> +             return 0
> +     fi
> +
> +     local SINGLE_PATCH="no"
> +     # no args means process ${EPATCH_SOURCE}
> +     [[ $# -eq 0 ]] && set -- "${EPATCH_SOURCE}"
> +
> +     if [[ -f $1 ]] ; then
> +             SINGLE_PATCH="yes"
> +             set -- "$1"
> +             # Use the suffix from the single patch (localize it); the code
> +             # below will find the suffix for us
> +             local EPATCH_SUFFIX=$1
> +
> +     elif [[ -d $1 ]] ; then
> +             # We have to force sorting to C so that the wildcard expansion 
> is consistent #471666.
> +             evar_push_set LC_COLLATE C
> +             # Some people like to make dirs of patches w/out suffixes (vim).
> +             set -- "$1"/*${EPATCH_SUFFIX:+."${EPATCH_SUFFIX}"}
> +             evar_pop
> +
> +     elif [[ -f ${EPATCH_SOURCE}/$1 ]] ; then
> +             # Re-use EPATCH_SOURCE as a search dir
> +             epatch "${EPATCH_SOURCE}/$1"
> +             return $?
> +
> +     else
> +             # sanity check ... if it isn't a dir or file, wtf man ?
> +             [[ $# -ne 0 ]] && EPATCH_SOURCE=$1
> +             echo
> +             eerror "Cannot find \$EPATCH_SOURCE!  Value for \$EPATCH_SOURCE 
> is:"
> +             eerror
> +             eerror "  ${EPATCH_SOURCE}"
> +             eerror "  ( ${EPATCH_SOURCE##*/} )"
> +             echo
> +             die "Cannot find \$EPATCH_SOURCE!"
> +     fi
> +
> +     # Now that we know we're actually going to apply something, merge
> +     # all of the patch options back in to a single variable for below.
> +     EPATCH_OPTS="${EPATCH_COMMON_OPTS} ${EPATCH_OPTS[*]}"
> +
> +     local PIPE_CMD
> +     case ${EPATCH_SUFFIX##*\.} in
> +             xz)      PIPE_CMD="xz -dc"    ;;
> +             lzma)    PIPE_CMD="lzma -dc"  ;;
> +             bz2)     PIPE_CMD="bzip2 -dc" ;;
> +             gz|Z|z)  PIPE_CMD="gzip -dc"  ;;
> +             ZIP|zip) PIPE_CMD="unzip -p"  ;;
> +             *)       ;;
> +     esac
> +
> +     [[ ${SINGLE_PATCH} == "no" ]] && einfo "${EPATCH_MULTI_MSG}"
> +
> +     local x
> +     for x in "$@" ; do
> +             # If the patch dir given contains subdirs, or our EPATCH_SUFFIX
> +             # didn't match anything, ignore continue on
> +             [[ ! -f ${x} ]] && continue
> +
> +             local patchname=${x##*/}
> +
> +             # Apply single patches, or forced sets of patches, or
> +             # patches with ARCH dependant names.
> +             #       ???_arch_foo.patch
> +             # Else, skip this input altogether
> +             local a=${patchname#*_} # strip the ???_
> +             a=${a%%_*}              # strip the _foo.patch
> +             if ! [[ ${SINGLE_PATCH} == "yes" || \
> +                             ${EPATCH_FORCE} == "yes" || \
> +                             ${a} == all     || \
> +                             ${a} == ${ARCH} ]]
> +             then
> +                     continue
> +             fi
> +
> +             # Let people filter things dynamically
> +             if [[ -n ${EPATCH_EXCLUDE}${EPATCH_USER_EXCLUDE} ]] ; then
> +                     # let people use globs in the exclude
> +                     eshopts_push -o noglob
> +
> +                     local ex
> +                     for ex in ${EPATCH_EXCLUDE} ; do
> +                             if [[ ${patchname} == ${ex} ]] ; then
> +                                     einfo "  Skipping ${patchname} due to 
> EPATCH_EXCLUDE ..."
> +                                     eshopts_pop
> +                                     continue 2
> +                             fi
> +                     done
> +
> +                     for ex in ${EPATCH_USER_EXCLUDE} ; do
> +                             if [[ ${patchname} == ${ex} ]] ; then
> +                                     einfo "  Skipping ${patchname} due to 
> EPATCH_USER_EXCLUDE ..."
> +                                     eshopts_pop
> +                                     continue 2
> +                             fi
> +                     done
> +
> +                     eshopts_pop
> +             fi
> +
> +             if [[ ${SINGLE_PATCH} == "yes" ]] ; then
> +                     if [[ -n ${EPATCH_SINGLE_MSG} ]] ; then
> +                             einfo "${EPATCH_SINGLE_MSG}"
> +                     else
> +                             einfo "Applying ${patchname} ..."
> +                     fi
> +             else
> +                     einfo "  ${patchname} ..."
> +             fi
> +
> +             # Handle aliased patch command #404447 #461568
> +             local patch="patch"
> +             eval $(alias patch 2>/dev/null | sed 's:^alias ::')
> +
> +             # most of the time, there will only be one run per unique name,
> +             # but if there are more, make sure we get unique log filenames
> +             local STDERR_TARGET="${T}/${patchname}.out"
> +             if [[ -e ${STDERR_TARGET} ]] ; then
> +                     STDERR_TARGET="${T}/${patchname}-$$.out"
> +             fi
> +
> +             printf "***** %s *****\nPWD: %s\nPATCH TOOL: %s -> %s\nVERSION 
> INFO:\n%s\n\n" \
> +                     "${patchname}" \
> +                     "${PWD}" \
> +                     "${patch}" \
> +                     "$(type -P "${patch}")" \
> +                     "$(${patch} --version)" \
> +                     > "${STDERR_TARGET}"
> +
> +             # Decompress the patch if need be
> +             local count=0
> +             local PATCH_TARGET
> +             if [[ -n ${PIPE_CMD} ]] ; then
> +                     PATCH_TARGET="${T}/$$.patch"
> +                     echo "PIPE_COMMAND:  ${PIPE_CMD} ${x} > 
> ${PATCH_TARGET}" >> "${STDERR_TARGET}"
> +
> +                     if ! (${PIPE_CMD} "${x}" > "${PATCH_TARGET}") >> 
> "${STDERR_TARGET}" 2>&1 ; then
> +                             echo
> +                             eerror "Could not extract patch!"
> +                             #die "Could not extract patch!"
> +                             count=5
> +                             break
> +                     fi
> +             else
> +                     PATCH_TARGET=${x}
> +             fi
> +
> +             # Check for absolute paths in patches.  If sandbox is disabled,
> +             # people could (accidently) patch files in the root filesystem.
> +             # Or trigger other unpleasantries #237667.  So disallow -p0 on
> +             # such patches.
> +             local abs_paths=$(egrep -n '^[-+]{3} /' "${PATCH_TARGET}" | awk 
> '$2 != "/dev/null" { print }')
> +             if [[ -n ${abs_paths} ]] ; then
> +                     count=1
> +                     printf "NOTE: skipping -p0 due to absolute paths in 
> patch:\n%s\n" "${abs_paths}" >> "${STDERR_TARGET}"
> +             fi
> +             # Similar reason, but with relative paths.
> +             local rel_paths=$(egrep -n '^[-+]{3} [^ ]*[.][.]/' 
> "${PATCH_TARGET}")
> +             if [[ -n ${rel_paths} ]] ; then
> +                     echo
> +                     eerror "Rejected Patch: ${patchname} !"
> +                     eerror " ( ${PATCH_TARGET} )"
> +                     eerror
> +                     eerror "Your patch uses relative paths '../':"
> +                     eerror "${rel_paths}"
> +                     echo
> +                     die "you need to fix the relative paths in patch"
> +             fi
> +
> +             # Dynamically detect the correct -p# ... i'm lazy, so shoot me 
> :/
> +             local patch_cmd
> +             while [[ ${count} -lt 5 ]] ; do
> +                     patch_cmd="${patch} -p${count} ${EPATCH_OPTS}"
> +
> +                     # Generate some useful debug info ...
> +                     (
> +                     _epatch_draw_line "***** ${patchname} *****"
> +                     echo
> +                     echo "PATCH COMMAND:  ${patch_cmd} --dry-run -f < 
> '${PATCH_TARGET}'"
> +                     echo
> +                     _epatch_draw_line "***** ${patchname} *****"
> +                     ${patch_cmd} --dry-run -f < "${PATCH_TARGET}" 2>&1
> +                     ret=$?
> +                     echo
> +                     echo "patch program exited with status ${ret}"
> +                     exit ${ret}
> +                     ) >> "${STDERR_TARGET}"
> +
> +                     if [ $? -eq 0 ] ; then
> +                             (
> +                             _epatch_draw_line "***** ${patchname} *****"
> +                             echo
> +                             echo "ACTUALLY APPLYING ${patchname} ..."
> +                             echo "PATCH COMMAND:  ${patch_cmd} < 
> '${PATCH_TARGET}'"
> +                             echo
> +                             _epatch_draw_line "***** ${patchname} *****"
> +                             ${patch_cmd} < "${PATCH_TARGET}" 2>&1
> +                             ret=$?
> +                             echo
> +                             echo "patch program exited with status ${ret}"
> +                             exit ${ret}
> +                             ) >> "${STDERR_TARGET}"
> +
> +                             if [ $? -ne 0 ] ; then
> +                                     echo
> +                                     eerror "A dry-run of patch command 
> succeeded, but actually"
> +                                     eerror "applying the patch failed!"
> +                                     #die "Real world sux compared to the 
> dreamworld!"
> +                                     count=5
> +                             fi
> +                             break
> +                     fi
> +
> +                     : $(( count++ ))
> +             done
> +
> +             (( EPATCH_N_APPLIED_PATCHES++ ))
> +
> +             # if we had to decompress the patch, delete the temp one
> +             if [[ -n ${PIPE_CMD} ]] ; then
> +                     rm -f "${PATCH_TARGET}"
> +             fi
> +
> +             if [[ ${count} -ge 5 ]] ; then
> +                     echo
> +                     eerror "Failed Patch: ${patchname} !"
> +                     eerror " ( ${PATCH_TARGET} )"
> +                     eerror
> +                     eerror "Include in your bugreport the contents of:"
> +                     eerror
> +                     eerror "  ${STDERR_TARGET}"
> +                     echo
> +                     die "Failed Patch: ${patchname}!"
> +             fi
> +
> +             # if everything worked, delete the full debug patch log
> +             rm -f "${STDERR_TARGET}"
> +
> +             # then log away the exact stuff for people to review later
> +             cat <<-EOF >> "${T}/epatch.log"
> +             PATCH: ${x}
> +             CMD: ${patch_cmd}
> +             PWD: ${PWD}
> +
> +             EOF
> +             eend 0
> +     done
> +
> +     [[ ${SINGLE_PATCH} == "no" ]] && einfo "Done with patching"
> +     : # everything worked
> +}
> +
> +case ${EAPI:-0} in
> +0|1|2|3|4|5)
> +
> +# @VARIABLE: EPATCH_USER_SOURCE
> +# @DESCRIPTION:
> +# Location for user patches, see the epatch_user function.
> +# Should be set by the user. Don't set this in ebuilds.
> +: ${EPATCH_USER_SOURCE:=${PORTAGE_CONFIGROOT%/}/etc/portage/patches}
> +
> +# @FUNCTION: epatch_user
> +# @USAGE:
> +# @DESCRIPTION:
> +# Applies user-provided patches to the source tree. The patches are
> +# taken from /etc/portage/patches/<CATEGORY>/<P-PR|P|PN>[:SLOT]/, where the 
> first
> +# of these three directories to exist will be the one to use, ignoring
> +# any more general directories which might exist as well. They must end
> +# in ".patch" to be applied.
> +#
> +# User patches are intended for quick testing of patches without ebuild
> +# modifications, as well as for permanent customizations a user might
> +# desire. Obviously, there can be no official support for arbitrarily
> +# patched ebuilds. So whenever a build log in a bug report mentions that
> +# user patches were applied, the user should be asked to reproduce the
> +# problem without these.
> +#
> +# Not all ebuilds do call this function, so placing patches in the
> +# stated directory might or might not work, depending on the package and
> +# the eclasses it inherits and uses. It is safe to call the function
> +# repeatedly, so it is always possible to add a call at the ebuild
> +# level. The first call is the time when the patches will be
> +# applied.
> +#
> +# Ideally, this function should be called after gentoo-specific patches
> +# have been applied, so that their code can be modified as well, but
> +# before calls to e.g. eautoreconf, as the user patches might affect
> +# autotool input files as well.
> +epatch_user() {
> +     [[ $# -ne 0 ]] && die "epatch_user takes no options"
> +
> +     # Allow multiple calls to this function; ignore all but the first
> +     local applied="${T}/epatch_user.log"
> +     [[ -e ${applied} ]] && return 2
> +
> +     # don't clobber any EPATCH vars that the parent might want
> +     local EPATCH_SOURCE check
> +     for check in ${CATEGORY}/{${P}-${PR},${P},${PN}}{,:${SLOT%/*}}; do
> +             EPATCH_SOURCE=${EPATCH_USER_SOURCE}/${CTARGET}/${check}
> +             [[ -r ${EPATCH_SOURCE} ]] || 
> EPATCH_SOURCE=${EPATCH_USER_SOURCE}/${CHOST}/${check}
> +             [[ -r ${EPATCH_SOURCE} ]] || 
> EPATCH_SOURCE=${EPATCH_USER_SOURCE}/${check}
> +             if [[ -d ${EPATCH_SOURCE} ]] ; then
> +                     local 
> old_n_applied_patches=${EPATCH_N_APPLIED_PATCHES:-0}
> +                     EPATCH_SOURCE=${EPATCH_SOURCE} \
> +                     EPATCH_SUFFIX="patch" \
> +                     EPATCH_FORCE="yes" \
> +                     EPATCH_MULTI_MSG="Applying user patches from 
> ${EPATCH_SOURCE} ..." \
> +                     epatch
> +                     echo "${EPATCH_SOURCE}" > "${applied}"
> +                     if [[ ${old_n_applied_patches} -lt 
> ${EPATCH_N_APPLIED_PATCHES} ]]; then
> +                             has epatch_user_death_notice 
> ${EBUILD_DEATH_HOOKS} || \
> +                                     EBUILD_DEATH_HOOKS+=" 
> epatch_user_death_notice"
> +                     fi
> +                     return 0
> +             fi
> +     done
> +     echo "none" > "${applied}"
> +     return 1
> +}
> +
> +# @FUNCTION: epatch_user_death_notice
> +# @INTERNAL
> +# @DESCRIPTION:
> +# Include an explicit notice in the die message itself that user patches were
> +# applied to this build.
> +epatch_user_death_notice() {
> +     ewarn "!!! User patches were applied to this build!"
> +}
> +
> +esac
> +
> +_EPATCH_ECLASS=1
> +fi #_EPATCH_ECLASS
> diff --git a/eclass/eutils.eclass b/eclass/eutils.eclass
> index 79ec00042a3f..724a310b3000 100644
> --- a/eclass/eutils.eclass
> +++ b/eclass/eutils.eclass
> @@ -22,7 +22,7 @@ inherit multilib toolchain-funcs
>  # implicitly inherited (now split) eclasses
>  case ${EAPI:-0} in
>  0|1|2|3|4|5|6)
> -     inherit estack
> +     inherit epatch estack
>       ;;
>  esac
>  
> @@ -70,370 +70,6 @@ egit_clean() {
>       find "$@" -type d -name '.git*' -prune -print0 | xargs -0 rm -rf
>  }
>  
> -# @VARIABLE: EPATCH_SOURCE
> -# @DESCRIPTION:
> -# Default directory to search for patches.
> -EPATCH_SOURCE="${WORKDIR}/patch"
> -# @VARIABLE: EPATCH_SUFFIX
> -# @DESCRIPTION:
> -# Default extension for patches (do not prefix the period yourself).
> -EPATCH_SUFFIX="patch.bz2"
> -# @VARIABLE: EPATCH_OPTS
> -# @DESCRIPTION:
> -# Options to pass to patch.  Meant for ebuild/package-specific tweaking
> -# such as forcing the patch level (-p#) or fuzz (-F#) factor.  Note that
> -# for single patch tweaking, you can also pass flags directly to epatch.
> -EPATCH_OPTS=""
> -# @VARIABLE: EPATCH_COMMON_OPTS
> -# @DESCRIPTION:
> -# Common options to pass to `patch`.  You probably should never need to
> -# change these.  If you do, please discuss it with base-system first to
> -# be sure.
> -# @CODE
> -#    -g0 - keep RCS, ClearCase, Perforce and SCCS happy #24571
> -#    --no-backup-if-mismatch - do not leave .orig files behind
> -#    -E - automatically remove empty files
> -# @CODE
> -EPATCH_COMMON_OPTS="-g0 -E --no-backup-if-mismatch"
> -# @VARIABLE: EPATCH_EXCLUDE
> -# @DESCRIPTION:
> -# List of patches not to apply.       Note this is only file names,
> -# and not the full path.  Globs accepted.
> -EPATCH_EXCLUDE=""
> -# @VARIABLE: EPATCH_SINGLE_MSG
> -# @DESCRIPTION:
> -# Change the printed message for a single patch.
> -EPATCH_SINGLE_MSG=""
> -# @VARIABLE: EPATCH_MULTI_MSG
> -# @DESCRIPTION:
> -# Change the printed message for multiple patches.
> -EPATCH_MULTI_MSG="Applying various patches (bugfixes/updates) ..."
> -# @VARIABLE: EPATCH_FORCE
> -# @DESCRIPTION:
> -# Only require patches to match EPATCH_SUFFIX rather than the extended
> -# arch naming style.
> -EPATCH_FORCE="no"
> -# @VARIABLE: EPATCH_USER_EXCLUDE
> -# @DEFAULT_UNSET
> -# @DESCRIPTION:
> -# List of patches not to apply.       Note this is only file names,
> -# and not the full path.  Globs accepted.
> -
> -# @FUNCTION: epatch
> -# @USAGE: [options] [patches] [dirs of patches]
> -# @DESCRIPTION:
> -# epatch is designed to greatly simplify the application of patches.  It can
> -# process patch files directly, or directories of patches.  The patches may 
> be
> -# compressed (bzip/gzip/etc...) or plain text.  You generally need not 
> specify
> -# the -p option as epatch will automatically attempt -p0 to -p4 until things
> -# apply successfully.
> -#
> -# If you do not specify any patches/dirs, then epatch will default to the
> -# directory specified by EPATCH_SOURCE.
> -#
> -# Any options specified that start with a dash will be passed down to patch
> -# for this specific invocation.  As soon as an arg w/out a dash is found, 
> then
> -# arg processing stops.
> -#
> -# When processing directories, epatch will apply all patches that match:
> -# @CODE
> -#    if ${EPATCH_FORCE} != "yes"
> -#            ??_${ARCH}_foo.${EPATCH_SUFFIX}
> -#    else
> -#            *.${EPATCH_SUFFIX}
> -# @CODE
> -# The leading ?? are typically numbers used to force consistent patch 
> ordering.
> -# The arch field is used to apply patches only for the host architecture with
> -# the special value of "all" means apply for everyone.  Note that using 
> values
> -# other than "all" is highly discouraged -- you should apply patches all the
> -# time and let architecture details be detected at configure/compile time.
> -#
> -# If EPATCH_SUFFIX is empty, then no period before it is implied when 
> searching
> -# for patches to apply.
> -#
> -# Refer to the other EPATCH_xxx variables for more customization of behavior.
> -epatch() {
> -     _epatch_draw_line() {
> -             # create a line of same length as input string
> -             [[ -z $1 ]] && set "$(printf "%65s" '')"
> -             echo "${1//?/=}"
> -     }
> -
> -     unset P4CONFIG P4PORT P4USER # keep perforce at bay #56402
> -
> -     # First process options.  We localize the EPATCH_OPTS setting
> -     # from above so that we can pass it on in the loop below with
> -     # any additional values the user has specified.
> -     local EPATCH_OPTS=( ${EPATCH_OPTS[*]} )
> -     while [[ $# -gt 0 ]] ; do
> -             case $1 in
> -             -*) EPATCH_OPTS+=( "$1" ) ;;
> -             *) break ;;
> -             esac
> -             shift
> -     done
> -
> -     # Let the rest of the code process one user arg at a time --
> -     # each arg may expand into multiple patches, and each arg may
> -     # need to start off with the default global EPATCH_xxx values
> -     if [[ $# -gt 1 ]] ; then
> -             local m
> -             for m in "$@" ; do
> -                     epatch "${m}"
> -             done
> -             return 0
> -     fi
> -
> -     local SINGLE_PATCH="no"
> -     # no args means process ${EPATCH_SOURCE}
> -     [[ $# -eq 0 ]] && set -- "${EPATCH_SOURCE}"
> -
> -     if [[ -f $1 ]] ; then
> -             SINGLE_PATCH="yes"
> -             set -- "$1"
> -             # Use the suffix from the single patch (localize it); the code
> -             # below will find the suffix for us
> -             local EPATCH_SUFFIX=$1
> -
> -     elif [[ -d $1 ]] ; then
> -             # We have to force sorting to C so that the wildcard expansion 
> is consistent #471666.
> -             evar_push_set LC_COLLATE C
> -             # Some people like to make dirs of patches w/out suffixes (vim).
> -             set -- "$1"/*${EPATCH_SUFFIX:+."${EPATCH_SUFFIX}"}
> -             evar_pop
> -
> -     elif [[ -f ${EPATCH_SOURCE}/$1 ]] ; then
> -             # Re-use EPATCH_SOURCE as a search dir
> -             epatch "${EPATCH_SOURCE}/$1"
> -             return $?
> -
> -     else
> -             # sanity check ... if it isn't a dir or file, wtf man ?
> -             [[ $# -ne 0 ]] && EPATCH_SOURCE=$1
> -             echo
> -             eerror "Cannot find \$EPATCH_SOURCE!  Value for \$EPATCH_SOURCE 
> is:"
> -             eerror
> -             eerror "  ${EPATCH_SOURCE}"
> -             eerror "  ( ${EPATCH_SOURCE##*/} )"
> -             echo
> -             die "Cannot find \$EPATCH_SOURCE!"
> -     fi
> -
> -     # Now that we know we're actually going to apply something, merge
> -     # all of the patch options back in to a single variable for below.
> -     EPATCH_OPTS="${EPATCH_COMMON_OPTS} ${EPATCH_OPTS[*]}"
> -
> -     local PIPE_CMD
> -     case ${EPATCH_SUFFIX##*\.} in
> -             xz)      PIPE_CMD="xz -dc"    ;;
> -             lzma)    PIPE_CMD="lzma -dc"  ;;
> -             bz2)     PIPE_CMD="bzip2 -dc" ;;
> -             gz|Z|z)  PIPE_CMD="gzip -dc"  ;;
> -             ZIP|zip) PIPE_CMD="unzip -p"  ;;
> -             *)       ;;
> -     esac
> -
> -     [[ ${SINGLE_PATCH} == "no" ]] && einfo "${EPATCH_MULTI_MSG}"
> -
> -     local x
> -     for x in "$@" ; do
> -             # If the patch dir given contains subdirs, or our EPATCH_SUFFIX
> -             # didn't match anything, ignore continue on
> -             [[ ! -f ${x} ]] && continue
> -
> -             local patchname=${x##*/}
> -
> -             # Apply single patches, or forced sets of patches, or
> -             # patches with ARCH dependant names.
> -             #       ???_arch_foo.patch
> -             # Else, skip this input altogether
> -             local a=${patchname#*_} # strip the ???_
> -             a=${a%%_*}              # strip the _foo.patch
> -             if ! [[ ${SINGLE_PATCH} == "yes" || \
> -                             ${EPATCH_FORCE} == "yes" || \
> -                             ${a} == all     || \
> -                             ${a} == ${ARCH} ]]
> -             then
> -                     continue
> -             fi
> -
> -             # Let people filter things dynamically
> -             if [[ -n ${EPATCH_EXCLUDE}${EPATCH_USER_EXCLUDE} ]] ; then
> -                     # let people use globs in the exclude
> -                     eshopts_push -o noglob
> -
> -                     local ex
> -                     for ex in ${EPATCH_EXCLUDE} ; do
> -                             if [[ ${patchname} == ${ex} ]] ; then
> -                                     einfo "  Skipping ${patchname} due to 
> EPATCH_EXCLUDE ..."
> -                                     eshopts_pop
> -                                     continue 2
> -                             fi
> -                     done
> -
> -                     for ex in ${EPATCH_USER_EXCLUDE} ; do
> -                             if [[ ${patchname} == ${ex} ]] ; then
> -                                     einfo "  Skipping ${patchname} due to 
> EPATCH_USER_EXCLUDE ..."
> -                                     eshopts_pop
> -                                     continue 2
> -                             fi
> -                     done
> -
> -                     eshopts_pop
> -             fi
> -
> -             if [[ ${SINGLE_PATCH} == "yes" ]] ; then
> -                     if [[ -n ${EPATCH_SINGLE_MSG} ]] ; then
> -                             einfo "${EPATCH_SINGLE_MSG}"
> -                     else
> -                             einfo "Applying ${patchname} ..."
> -                     fi
> -             else
> -                     einfo "  ${patchname} ..."
> -             fi
> -
> -             # Handle aliased patch command #404447 #461568
> -             local patch="patch"
> -             eval $(alias patch 2>/dev/null | sed 's:^alias ::')
> -
> -             # most of the time, there will only be one run per unique name,
> -             # but if there are more, make sure we get unique log filenames
> -             local STDERR_TARGET="${T}/${patchname}.out"
> -             if [[ -e ${STDERR_TARGET} ]] ; then
> -                     STDERR_TARGET="${T}/${patchname}-$$.out"
> -             fi
> -
> -             printf "***** %s *****\nPWD: %s\nPATCH TOOL: %s -> %s\nVERSION 
> INFO:\n%s\n\n" \
> -                     "${patchname}" \
> -                     "${PWD}" \
> -                     "${patch}" \
> -                     "$(type -P "${patch}")" \
> -                     "$(${patch} --version)" \
> -                     > "${STDERR_TARGET}"
> -
> -             # Decompress the patch if need be
> -             local count=0
> -             local PATCH_TARGET
> -             if [[ -n ${PIPE_CMD} ]] ; then
> -                     PATCH_TARGET="${T}/$$.patch"
> -                     echo "PIPE_COMMAND:  ${PIPE_CMD} ${x} > 
> ${PATCH_TARGET}" >> "${STDERR_TARGET}"
> -
> -                     if ! (${PIPE_CMD} "${x}" > "${PATCH_TARGET}") >> 
> "${STDERR_TARGET}" 2>&1 ; then
> -                             echo
> -                             eerror "Could not extract patch!"
> -                             #die "Could not extract patch!"
> -                             count=5
> -                             break
> -                     fi
> -             else
> -                     PATCH_TARGET=${x}
> -             fi
> -
> -             # Check for absolute paths in patches.  If sandbox is disabled,
> -             # people could (accidently) patch files in the root filesystem.
> -             # Or trigger other unpleasantries #237667.  So disallow -p0 on
> -             # such patches.
> -             local abs_paths=$(egrep -n '^[-+]{3} /' "${PATCH_TARGET}" | awk 
> '$2 != "/dev/null" { print }')
> -             if [[ -n ${abs_paths} ]] ; then
> -                     count=1
> -                     printf "NOTE: skipping -p0 due to absolute paths in 
> patch:\n%s\n" "${abs_paths}" >> "${STDERR_TARGET}"
> -             fi
> -             # Similar reason, but with relative paths.
> -             local rel_paths=$(egrep -n '^[-+]{3} [^ ]*[.][.]/' 
> "${PATCH_TARGET}")
> -             if [[ -n ${rel_paths} ]] ; then
> -                     echo
> -                     eerror "Rejected Patch: ${patchname} !"
> -                     eerror " ( ${PATCH_TARGET} )"
> -                     eerror
> -                     eerror "Your patch uses relative paths '../':"
> -                     eerror "${rel_paths}"
> -                     echo
> -                     die "you need to fix the relative paths in patch"
> -             fi
> -
> -             # Dynamically detect the correct -p# ... i'm lazy, so shoot me 
> :/
> -             local patch_cmd
> -             while [[ ${count} -lt 5 ]] ; do
> -                     patch_cmd="${patch} -p${count} ${EPATCH_OPTS}"
> -
> -                     # Generate some useful debug info ...
> -                     (
> -                     _epatch_draw_line "***** ${patchname} *****"
> -                     echo
> -                     echo "PATCH COMMAND:  ${patch_cmd} --dry-run -f < 
> '${PATCH_TARGET}'"
> -                     echo
> -                     _epatch_draw_line "***** ${patchname} *****"
> -                     ${patch_cmd} --dry-run -f < "${PATCH_TARGET}" 2>&1
> -                     ret=$?
> -                     echo
> -                     echo "patch program exited with status ${ret}"
> -                     exit ${ret}
> -                     ) >> "${STDERR_TARGET}"
> -
> -                     if [ $? -eq 0 ] ; then
> -                             (
> -                             _epatch_draw_line "***** ${patchname} *****"
> -                             echo
> -                             echo "ACTUALLY APPLYING ${patchname} ..."
> -                             echo "PATCH COMMAND:  ${patch_cmd} < 
> '${PATCH_TARGET}'"
> -                             echo
> -                             _epatch_draw_line "***** ${patchname} *****"
> -                             ${patch_cmd} < "${PATCH_TARGET}" 2>&1
> -                             ret=$?
> -                             echo
> -                             echo "patch program exited with status ${ret}"
> -                             exit ${ret}
> -                             ) >> "${STDERR_TARGET}"
> -
> -                             if [ $? -ne 0 ] ; then
> -                                     echo
> -                                     eerror "A dry-run of patch command 
> succeeded, but actually"
> -                                     eerror "applying the patch failed!"
> -                                     #die "Real world sux compared to the 
> dreamworld!"
> -                                     count=5
> -                             fi
> -                             break
> -                     fi
> -
> -                     : $(( count++ ))
> -             done
> -
> -             (( EPATCH_N_APPLIED_PATCHES++ ))
> -
> -             # if we had to decompress the patch, delete the temp one
> -             if [[ -n ${PIPE_CMD} ]] ; then
> -                     rm -f "${PATCH_TARGET}"
> -             fi
> -
> -             if [[ ${count} -ge 5 ]] ; then
> -                     echo
> -                     eerror "Failed Patch: ${patchname} !"
> -                     eerror " ( ${PATCH_TARGET} )"
> -                     eerror
> -                     eerror "Include in your bugreport the contents of:"
> -                     eerror
> -                     eerror "  ${STDERR_TARGET}"
> -                     echo
> -                     die "Failed Patch: ${patchname}!"
> -             fi
> -
> -             # if everything worked, delete the full debug patch log
> -             rm -f "${STDERR_TARGET}"
> -
> -             # then log away the exact stuff for people to review later
> -             cat <<-EOF >> "${T}/epatch.log"
> -             PATCH: ${x}
> -             CMD: ${patch_cmd}
> -             PWD: ${PWD}
> -
> -             EOF
> -             eend 0
> -     done
> -
> -     [[ ${SINGLE_PATCH} == "no" ]] && einfo "Done with patching"
> -     : # everything worked
> -}
> -
>  # @FUNCTION: emktemp
>  # @USAGE: [temp dir]
>  # @DESCRIPTION:
> @@ -1493,80 +1129,6 @@ esac
>  case ${EAPI:-0} in
>  0|1|2|3|4|5)
>  
> -# @VARIABLE: EPATCH_USER_SOURCE
> -# @DESCRIPTION:
> -# Location for user patches, see the epatch_user function.
> -# Should be set by the user. Don't set this in ebuilds.
> -: ${EPATCH_USER_SOURCE:=${PORTAGE_CONFIGROOT%/}/etc/portage/patches}
> -
> -# @FUNCTION: epatch_user
> -# @USAGE:
> -# @DESCRIPTION:
> -# Applies user-provided patches to the source tree. The patches are
> -# taken from /etc/portage/patches/<CATEGORY>/<P-PR|P|PN>[:SLOT]/, where the 
> first
> -# of these three directories to exist will be the one to use, ignoring
> -# any more general directories which might exist as well. They must end
> -# in ".patch" to be applied.
> -#
> -# User patches are intended for quick testing of patches without ebuild
> -# modifications, as well as for permanent customizations a user might
> -# desire. Obviously, there can be no official support for arbitrarily
> -# patched ebuilds. So whenever a build log in a bug report mentions that
> -# user patches were applied, the user should be asked to reproduce the
> -# problem without these.
> -#
> -# Not all ebuilds do call this function, so placing patches in the
> -# stated directory might or might not work, depending on the package and
> -# the eclasses it inherits and uses. It is safe to call the function
> -# repeatedly, so it is always possible to add a call at the ebuild
> -# level. The first call is the time when the patches will be
> -# applied.
> -#
> -# Ideally, this function should be called after gentoo-specific patches
> -# have been applied, so that their code can be modified as well, but
> -# before calls to e.g. eautoreconf, as the user patches might affect
> -# autotool input files as well.
> -epatch_user() {
> -     [[ $# -ne 0 ]] && die "epatch_user takes no options"
> -
> -     # Allow multiple calls to this function; ignore all but the first
> -     local applied="${T}/epatch_user.log"
> -     [[ -e ${applied} ]] && return 2
> -
> -     # don't clobber any EPATCH vars that the parent might want
> -     local EPATCH_SOURCE check
> -     for check in ${CATEGORY}/{${P}-${PR},${P},${PN}}{,:${SLOT%/*}}; do
> -             EPATCH_SOURCE=${EPATCH_USER_SOURCE}/${CTARGET}/${check}
> -             [[ -r ${EPATCH_SOURCE} ]] || 
> EPATCH_SOURCE=${EPATCH_USER_SOURCE}/${CHOST}/${check}
> -             [[ -r ${EPATCH_SOURCE} ]] || 
> EPATCH_SOURCE=${EPATCH_USER_SOURCE}/${check}
> -             if [[ -d ${EPATCH_SOURCE} ]] ; then
> -                     local 
> old_n_applied_patches=${EPATCH_N_APPLIED_PATCHES:-0}
> -                     EPATCH_SOURCE=${EPATCH_SOURCE} \
> -                     EPATCH_SUFFIX="patch" \
> -                     EPATCH_FORCE="yes" \
> -                     EPATCH_MULTI_MSG="Applying user patches from 
> ${EPATCH_SOURCE} ..." \
> -                     epatch
> -                     echo "${EPATCH_SOURCE}" > "${applied}"
> -                     if [[ ${old_n_applied_patches} -lt 
> ${EPATCH_N_APPLIED_PATCHES} ]]; then
> -                             has epatch_user_death_notice 
> ${EBUILD_DEATH_HOOKS} || \
> -                                     EBUILD_DEATH_HOOKS+=" 
> epatch_user_death_notice"
> -                     fi
> -                     return 0
> -             fi
> -     done
> -     echo "none" > "${applied}"
> -     return 1
> -}
> -
> -# @FUNCTION: epatch_user_death_notice
> -# @INTERNAL
> -# @DESCRIPTION:
> -# Include an explicit notice in the die message itself that user patches were
> -# applied to this build.
> -epatch_user_death_notice() {
> -     ewarn "!!! User patches were applied to this build!"
> -}
> -
>  # @FUNCTION: einstalldocs
>  # @DESCRIPTION:
>  # Install documentation using DOCS and HTML_DOCS.

Merged.
-- 
Best regards,
Michał Górny

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to