commit:     5df2698b9ea7c3f1ef7c36b6e5927cec15a0f52d
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Fri Jul 22 20:09:20 2022 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jul 22 20:36:46 2022 +0000
URL:        https://gitweb.gentoo.org/proj/toolchain.git/commit/?id=5df2698b

epatch.eclass: add for toolchain-legacy.eclass

We really don't want to rebase a huge number of patches.

Signed-off-by: Sam James <sam <AT> gentoo.org>

 eclass/epatch.eclass | 380 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 380 insertions(+)

diff --git a/eclass/epatch.eclass b/eclass/epatch.eclass
new file mode 100644
index 0000000..ae4a691
--- /dev/null
+++ b/eclass/epatch.eclass
@@ -0,0 +1,380 @@
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: epatch.eclass
+# @MAINTAINER:
+# [email protected]
+# @SUPPORTED_EAPIS: 6
+# @BLURB: easy patch application functions
+# @DEPRECATED: eapply from EAPI 7
+# @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
+
+case ${EAPI} in
+       6|7|8) ;;
+       *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
+esac
+
+inherit estack
+
+# @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_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
+                       ebegin "Applying ${patchname}"
+               else
+                       ebegin "  ${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=$(grep -E -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=$(grep -E -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 bug report 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
+}
+
+_EPATCH_ECLASS=1
+fi #_EPATCH_ECLASS

Reply via email to