diff options
author | John Mylchreest <johnm@gentoo.org> | 2006-04-24 11:59:50 +0000 |
---|---|---|
committer | John Mylchreest <johnm@gentoo.org> | 2006-04-24 11:59:50 +0000 |
commit | e2488a5452b0f1c0df3d54a4edba370886213936 (patch) | |
tree | f746eb97d1da6ce9509eebcfea54dcb4446a9a46 /eclass/unipatch-001.eclass | |
parent | hide version.h not existing in make mrproper during unpack (diff) | |
download | historical-e2488a5452b0f1c0df3d54a4edba370886213936.tar.gz historical-e2488a5452b0f1c0df3d54a4edba370886213936.tar.bz2 historical-e2488a5452b0f1c0df3d54a4edba370886213936.zip |
New standalone, re-written unipatch, requires testing.
Diffstat (limited to 'eclass/unipatch-001.eclass')
-rw-r--r-- | eclass/unipatch-001.eclass | 300 |
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}" +} |