summaryrefslogtreecommitdiff
path: root/eclass
diff options
context:
space:
mode:
authorJohn Mylchreest <johnm@gentoo.org>2006-04-24 11:59:50 +0000
committerJohn Mylchreest <johnm@gentoo.org>2006-04-24 11:59:50 +0000
commite2488a5452b0f1c0df3d54a4edba370886213936 (patch)
treef746eb97d1da6ce9509eebcfea54dcb4446a9a46 /eclass
parenthide version.h not existing in make mrproper during unpack (diff)
downloadhistorical-e2488a5452b0f1c0df3d54a4edba370886213936.tar.gz
historical-e2488a5452b0f1c0df3d54a4edba370886213936.tar.bz2
historical-e2488a5452b0f1c0df3d54a4edba370886213936.zip
New standalone, re-written unipatch, requires testing.
Diffstat (limited to 'eclass')
-rw-r--r--eclass/unipatch-001.eclass300
1 files changed, 300 insertions, 0 deletions
diff --git a/eclass/unipatch-001.eclass b/eclass/unipatch-001.eclass
new file mode 100644
index 000000000000..20205f637167
--- /dev/null
+++ b/eclass/unipatch-001.eclass
@@ -0,0 +1,300 @@
+unipatch() {
+ # Behavioural environment variables.
+ # UNIPATCH_STRICTORDER
+ # UNIPATCH_EXCLUDE
+ # KPATCH_DIR
+ # UNIPATCH_POPTS
+ # UNIPATCH_SILENT_DROP
+
+ local myLC_ALL
+ local checkfile checkfile_noext checkfile_ext checkfile_patchlvl
+ local checkfile_meta checkfile_patchdir checkfile_suffix
+ local strictcount i n pipecmd
+ local file_list patch_to_process patch_plevel
+
+ # set to a standard locale to ensure sorts are ordered properly.
+ myLC_ALL="${LC_ALL}"
+ LC_ALL="C"
+
+ # Setup UNIPATCH_POPTS if not set already
+ UNIPATCH_POPTS=${UNIPATCH_POPTS:--g0 -s}
+
+ # Set UNIPATCH_SILENT_DROP if not already set
+ # Please bare in mind these *cannot* start with an asterisk
+ UNIPATCH_SILENT_DROP='000*'
+
+ # We need a temporary directory in which we can stor our patches.
+ KPATCH_DIR="${KPATCH_DIR:-${WORKDIR}/patches/}"
+ mkdir -p ${KPATCH_DIR}
+
+ # We're gonna need it when doing patches with a predefined patchlevel
+ shopt -s extglob
+
+ # lets obtain our patch list
+ # any .diff/.patch/compressed file is added, and if neccessary decompressed.
+ # any tarred file is unpacked and added
+ # anything else is added to the drop pattern
+ UNIPATCH_LIST="${@:-${UNIPATCH_LIST}}"
+
+ n=0
+ strictcount=0
+ for checkfile in ${UNIPATCH_LIST}
+ do
+ # unset parsed vars first
+ unset checkfile_suffix
+ unset checkfile_ext
+ unset checkfile_patchdir
+ checkfile_patchlvl=0
+
+ # did we pass suffix? or a patchlvl?
+ for((i=0; i<=${#checkfile}; i++)); do
+ case ${checkfile:${i}:1} in
+ @) checkfile_suffix="${checkfile:0:${i}}";;
+ :) checkfile_patchlvl="${checkfile:${i}}";;
+ esac
+ done
+
+ # now lets sane up the checkfile var
+ [[ -n ${checkfile_suffix} ]] && checkfile=${checkfile//*@}
+ [[ -n ${checkfile_patchlvl} ]] && checkfile=${checkfile//:*}
+
+ # is this file even valid?
+ if [[ ! -f ${checkfile} ]]; then
+ ewarn "Unable to read file:"
+ ewarn "${checkfile}"
+ ewarn "Please check this file exists, and its permissions."
+ die "unable to locate ${checkfile}"
+ fi
+
+ #if we use strict dir, then lets prepend an order
+ if [[ -n ${UNIPATCH_STRICTORDER} ]]; then
+ checkfile_patchdir=${KPATCH_DIR}/${strictcount}/
+ mkdir -p ${checkfile_patchdir}
+ strictcount=$((${strictcount} + 1))
+ fi
+
+ # Find the directory we are placing this in.
+ checkfile_patchdir="${checkfile_patchdir:-${KPATCH_DIR}}"
+
+ # so now lets get finding patches.
+ # This is a list of patterns to match, and the resulting extention.
+ # you MUST specify the LEAST specific first, if the pattern would match
+ # more than one extension. think, .tar.gz vs. .gz
+ local testvalues test value temp
+ testvalues='*:DROP
+ *README:DOC
+ *.txt:DOC
+ *.gz*:gz
+ *.bz*:bz2
+ *.tar.bz*:tbz
+ *.tbz*:tbz
+ *.tar.gz*:tgz
+ *.tgz*:tgz
+ *.tar:tar
+ *.z*:gz
+ *.zip*:zip
+ *.diff*:diff
+ *.patch*:patch'
+
+ # lets see if we qualify for one of the above
+ for i in $testvalues; do
+ value=${i/*:/}
+ test=${i/:*/}
+ temp=${checkfile/${test}/${value}}
+ if [[ ${temp} == ${value} ]]
+ then
+ # if we do, then set the extention and the filename, minus ext.
+ checkfile_ext="${temp}"
+ checkfile_noext="${checkfile/${test:1}/}"
+ fi
+ done
+
+ # if we specify a suffix, we want to over-ride the above now.
+ [[ -n ${checkfile_suffix} ]] && \
+ checkfile_ext="${checkfile_suffix}" \
+ checkfile_noext="${checkfile/${checkfile_suffix}/}"
+
+ # set metafile
+ checkfile_meta="${checkfile_patchdir}/.meta_${checkfile_noext/*\//}"
+
+ # Debug environment
+ edebug 3 "Debug environment variables"
+ edebug 3 "---------------------------"
+ edebug 3 "checkfile=${checkfile}"
+ edebug 3 "checkfile_ext=${checkfile_ext}"
+ edebug 3 "checkfile_noext=${checkfile_noext}"
+ edebug 3 "checkfile_patchdir=${checkfile_patchdir}"
+ edebug 3 "checkfile_patchlvl=${checkfile_patchlvl}"
+ edebug 3 "checkfile_meta=${checkfile_meta}"
+ edebug 3 "checkfile_suffix=${checkfile_suffix}"
+
+ # and setup the appropriate pipecmd for it.
+ # the outcome of this should leave the file we want in the patch dir
+ case ${checkfile_ext} in
+ tbz) pipecmd="mkdir ${T}/ptmp/;
+ cd ${T}/ptmp/;
+ tar -xjf ${checkfile};
+ find . -type f | sed -e 's:\./::g' \
+ > ${checkfile_meta}_files;
+ cp -Rf ${T}/ptmp/* ${checkfile_patchdir};
+ rm -Rf ${T}/ptmp;
+ cd \${OLDPWD}";;
+ tgz) pipecmd="mkdir ${T}/ptmp/;
+ cd ${T}/ptmp/;
+ tar -xzf ${checkfile};
+ find . -type f | sed -e 's:\./::g' \
+ > ${checkfile_meta}_files;
+ cp -Rf ${T}/ptmp/* ${checkfile_patchdir};
+ rm -Rf ${T}/ptmp;
+ cd \${OLDPWD}";;
+ tar) pipecmd="mkdir ${T}/ptmp/;
+ cd ${T}/ptmp/;
+ tar -xf ${checkfile};
+ find . -type f | sed -e 's:\./::g' \
+ > ${checkfile_meta}_files;
+ cp -Rf ${T}/ptmp/* ${checkfile_patchdir};
+ rm -Rf ${T}/ptmp;
+ cd \${OLDPWD}";;
+ zip) pipecmd="mkdir ${T}/ptmp/;
+ cd ${T}/ptmp/;
+ unzip ${checkfile};
+ find . -type f | sed -e 's:\./::g' \
+ > ${checkfile_meta}_files;
+ cp -Rf ${T}/ptmp/* ${checkfile_patchdir};
+ rm -Rf ${T}/ptmp;
+ cd \${OLDPWD}";;
+ diff) pipecmd="cp ${checkfile} ${checkfile_patchdir};
+ echo ${checkfile/*\//} \
+ > ${checkfile_meta}_files;";;
+ patch) pipecmd="cp ${checkfile} ${checkfile_patchdir};
+ echo ${checkfile/*\//} \
+ > ${checkfile_meta}_files;";;
+ gz) pipecmd="gzip -dc ${checkfile} > ${T}/gunzip;
+ cp ${T}/gunzip ${checkfile_patchdir}${checkfile_noext/*\//}.diff;
+ rm ${T}/gunzip;
+ echo ${checkfile_noext/*\//}.diff \
+ > ${checkfile_meta}_files;";;
+ bz2) pipecmd="bzip2 -dc ${checkfile} > ${T}/bunzip;
+ cp ${T}/bunzip ${checkfile_patchdir}${checkfile_noext/*\//}.diff;
+ rm ${T}/bunzip;
+ echo ${checkfile_noext/*\//}.diff \
+ > ${checkfile_meta}_files;";;
+ DROP) pipecmd="";;
+ DOC) pipecmd="cp ${checkfile} ${checkfile_patchdir}";;
+ esac
+
+ # Debug environment
+ edebug 3 "pipecmd=${pipecmd}"
+
+ if [[ -z ${pipecmd} ]]; then
+ # if we dont know about it, lets drop it and move to the next
+ einfo "Unknown Filetype, Ignoring: ${checkfile/*\//}"
+ else
+ # if we do know about it, prepare it for patching, and
+ # populate metadata
+ ebegin "Preparing ${checkfile/*\//}"
+ eval ${pipecmd}
+ eend $?
+
+ echo "PATCHLVL=${checkfile_patchlvl}" >> ${checkfile_meta}
+ fi
+ done
+
+ # OK so now we got this far, we have everything neatly unpacked.
+ # we should probably build up our patch-list.
+ edebug 2 "Locating .meta_*_files and building patch list"
+
+ for i in $(find ${KPATCH_DIR} -iname ".meta_*_files")
+ do
+ file_list=$(sort -n ${i})
+ patch_plevel=$(sed -e 's:PATCHLVL=\(.*\):\1:' < ${i/_files/} | uniq)
+ edebug 3 "processing: ${i}"
+ edebug 3 "file_list=${file_list}"
+ edebug 3 "patch_plevel=${patch_plevel}"
+
+ # OK, so now we have trhe list of files to process in this metafile
+ # we should process the patch.
+ for patch_to_process in ${file_list}; do
+ edebug 2 "Processing: ${patch_to_process}"
+
+ # if we pass UNIPATCH_EXCLUDE then we scan through that.
+ # if we find a match, we dont bother applying it.
+ # This is done here to catch files within tarballs.
+ local tempname to_patch=1
+
+ tempname="${patch_to_process/*\//}"
+ # Process silent drops
+ for x in ${UNIPATCH_SILENT_DROP}; do
+ edebug 4 "Checking ${x} against ${tempname} = ${tempname//${x}}"
+ if [[ -z ${tempname//${x}} ]]; then
+ to_patch=-1
+ edebug 2 "Dropping ${tempname} based on ${x} match"
+ break;
+ fi
+ done
+
+ # Process excludes
+ for x in ${UNIPATCH_EXCLUDE}; do
+ [[ -z ${tempname/${x}*/} ]] && to_patch=0
+ done
+
+ if [[ ${to_patch} -eq -1 ]]; then
+ # This is something we silently ignore
+ :
+ elif [[ ${to_patch} -eq 1 ]]; then
+ apply_patch ${KPATCH_DIR}/${patch_to_process}
+ else
+ einfo "Excluding: ${tempname}"
+ fi
+ unset tempname to_patch
+ done
+ done
+
+ LC_ALL=${myLC_ALL}
+}
+
+apply_patch() {
+ local plvl patch_log
+ plvl=${patch_plevel}
+ patch_log="${T}/${1/*\//}.log"
+
+ echo "************" > ${patch_log}
+ echo "patch log for file:" >> ${patch_log}
+ echo "${1}" >> ${patch_log}
+ echo "************" >> ${patch_log}
+ while [ ${plvl} -lt 5 ]
+ do
+ edebug 3 "Attempting patch (${1}) with -p${plvl} (${UNIPATCH_POPTS})"
+
+ echo "Attempting:" >> ${patch_log}
+ echo "patch ${UNIPATCH_POPTS} -p${plvl} --dry-run -f" >> ${patch_log}
+ if (patch ${UNIPATCH_POPTS} -p${plvl} --dry-run -f < ${1}) >> ${patch_log}
+ then
+ echo "**** Applying:" >> ${patch_log}
+ ebegin "Applying patch: ${1/*\//} (-p${plvl})"
+ patch ${UNIPATCH_POPTS} -p${plvl} -f < ${1} >> ${patch_log}
+ eend $?
+ plvl=6
+ else
+ plvl=$((${plvl} + 1))
+ fi
+ done
+ if [ ${plvl} -eq 5 ]
+ then
+ ewarn "Unable to apply patch: ${1/*\//}"
+ ewarn "Please attach the following patch log when submitting"
+ ewarn "a bug."
+ ewarn "${patch_log}"
+ die "Unable to apply patch: ${1/*\//}"
+ fi
+}
+
+edebug() {
+ local verbosity msg
+ verbos=${1}
+ shift
+ msg=${@}
+
+ VERBOSITY=${VERBOSITY:-0}
+ [ ${VERBOSITY} -ge ${verbos} ] && echo "(DD): ${msg}"
+}