for various reasons/limitations/bugs/whatever, i rewrote epatch. seems to work for me, but in case someone wants to check before i release: 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 # 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 # Some people like to make dirs of patches w/out suffixes (vim) set -- "$1"/*${EPATCH_SUFFIX:+."${EPATCH_SUFFIX}"} 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 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} ]] ; then # let people use globs in the exclude eshopts_push -o noglob local ex for ex in ${EPATCH_EXCLUDE} ; do if [[ ${patchname} == ${ex} ]] ; then eshopts_pop continue 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 # 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 *****\n\n" "${patchname}" > "${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 # Dynamically detect the correct -p# ... i'm lazy, so shoot me :/ while [[ ${count} -lt 5 ]] ; do # Generate some useful debug info ... ( _epatch_draw_line "***** ${patchname} *****" echo echo "PATCH COMMAND: patch -p${count} ${EPATCH_OPTS} < '${PATCH_TARGET}'" echo _epatch_draw_line "***** ${patchname} *****" ) >> "${STDERR_TARGET}" if (patch -p${count} ${EPATCH_OPTS} --dry-run -f < "${PATCH_TARGET}") >> "${STDERR_TARGET}" 2>&1 ; then ( _epatch_draw_line "***** ${patchname} *****" echo echo "ACTUALLY APPLYING ${patchname} ..." echo _epatch_draw_line "***** ${patchname} *****" patch -p${count} ${EPATCH_OPTS} < "${PATCH_TARGET}" 2>&1 ) >> "${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 # 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 patch log rm -f "${STDERR_TARGET}" eend 0 done [[ ${SINGLE_PATCH} == "no" ]] && einfo "Done with patching" : # everything worked } -mike
signature.asc
Description: This is a digitally signed message part.