#!/usr/bin/env bash # Copyright (c) 2006 # Thorsten Glaser <tg@freewrt.org> # # Derived from the MirPorts Framework "update-patches" script: # # Copyright (c) 2003, 2004, 2005 # Thorsten "mirabile" Glaser <tg@MirBSD.de> # Based upon code and idea (c) 2000 # Marc Espie for the OpenBSD project. All rights reserved. # # Provided that these terms and disclaimer and all copyright notices # are retained or reproduced in an accompanying document, permission # is granted to deal in this work without restriction, including un- # limited rights to use, publicly perform, distribute, sell, modify, # merge, give away, or sublicence. # # This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to # the utmost extent permitted by applicable law, neither express nor # implied; without malicious intent or gross negligence. In no event # may a licensor, author or contributor be held liable for indirect, # direct, other damage, loss, or other issues arising in any way out # of dealing in the work, even if advised of the possibility of such # damage or existence of a defect, except proven that it results out # of said person's immediate fault when using the work as intended. [[ -n $BASH_VERSION ]] && shopt -s extglob do_diff() { local f1=$2/$1 local f2=$3/$1 if [[ ! -e $f1 ]]; then [[ -d ${f1%/*}/. ]] || mkdir -p ${f1%/*} if [[ ! -s $f2 ]]; then cat <<EOF --- $f1 (non-existant) +++ $f2 (empty) @@ -0,0 +0,0 @@ EOF return 0 fi touch -t 197001010000.00 "$f1" fi diff -adup "$f1" "$f2" return $? } TRANSFORM='sed s/[.+]/\\\\&/g' PATCHDIR=$CURDIR/patches EXTRADIR=$CURDIR/extra mkdir -p $PATCHDIR SUBDIST=${WRKDIST##${WRKDIR1}?(/)} if [[ -n $SUBDIST ]]; then mv ${WRKDIR1}.orig/${SUBDIST} ${WRKDIR1}/${SUBDIST}.orig D_BASE=${WRKDIR1} D_SUB=${SUBDIST} # D_SUBP=$D_SUB D_SUBP='[^/]*' D_CMP=$D_SUBP else # WRKSRC == WRKDIR D_BASE=$(dirname ${WRKDIR1}) D_SUB=$(basename ${WRKDIR1}) D_SUBP=$D_SUB D_CMP= fi ORGDIST=${D_BASE}/${D_SUB}.orig if [[ -e $WRKDIST/.patched-newfiles ]]; then touch $ORGDIST/.patched-newfiles patch_newfiles=1 else patch_newfiles=0 fi if [[ -e $WRKDIST/../.autoreconf_done ]]; then touch $ORGDIST/.autoreconf_done ignore_autoconf=1 else ignore_autoconf=0 fi DIFF_FLAGS="-adu -I \"^--- $(echo $D_SUBP.orig/ | $TRANSFORM)@@ .*\"" DIFF_FLAGS="$DIFF_FLAGS -I \"^\+\+\+ $(echo $D_SUBP/ | $TRANSFORM)@@ .*\"" for file in $(cd ${WRKDIST}; find . -type f | sed 's#^\./##'); do echo "DEBUG: $file" >> /tmp/debug [[ ! -e $ORGDIST/$file && $patch_newfiles = 0 ]] && continue [[ $file = configure && $ignore_autoconf = 1 ]] && continue [[ $file = missing && $ignore_autoconf = 1 ]] && continue [[ $file = depcomp && $ignore_autoconf = 1 ]] && continue [[ $file = install-sh && $ignore_autoconf = 1 ]] && continue [[ $file = aclocal.m4 && $ignore_autoconf = 1 ]] && continue [[ $file = INSTALL && $ignore_autoconf = 1 ]] && continue [[ $file = config.h.in && $ignore_autoconf = 1 ]] && continue [[ $(basename $file) = Makefile.in && $ignore_autoconf = 1 ]] && continue cmp -s "$ORGDIST/$file" "$WRKDIST/$file" && continue echo "Processing ${file}..." >&2 # look in patchdir for an existing patchfile matching this cd $PATCHDIR for i in $PATCH_LIST; do # Ignore non-files, or old backup [[ ! -f $i || $i = *@(.orig|.rej|~) ]] && continue # Patch found. Is this the one? if grep "^[+-][+-][+-] $D_CMP[^/]*/$file " "$i" >/dev/null; then # Multiple files in the diff? if [ $(grep -c "^--- $D_CMP" "$i") -gt 1 -o \ $(grep -c "^+++ $D_CMP" "$i") -gt 1 ]; then echo "Cannot process, $i contains patches" >&2 echo "to multiple files! Aborting." >&2 echo FAIL [[ -n $SUBDIST ]] && mv \ ${WRKDIR1}/${SUBDIST}.orig \ ${WRKDIR1}.orig/${SUBDIST} exit 0 fi # Multiple diffs with this file? let n=0 pflst= for j in $PATCH_LIST; do [[ ! -f $j || $j = *@(.orig|.rej|~) ]] && \ continue grep "^[+-][+-][+-] $D_CMP[^/]*/$file " \ "$j" >/dev/null || continue let n++ pflst="$pflst '$j'" done if (( n != 1 )); then echo "Cannot process, file $file" >&2 echo "is contained in multiple patches:" >&2 echo "$pflst" >&2 echo FAIL [[ -n $SUBDIST ]] && mv \ ${WRKDIR1}/${SUBDIST}.orig \ ${WRKDIR1}.orig/${SUBDIST} exit 0 fi # No, process this patch accounted="$accounted $i" # found it, copy preamble before comparision ( sed -e "/^--- /,\$d" <$i; \ cd $D_BASE && do_diff "$file" "$D_SUB.orig" "$D_SUB" \ ) >"$i.new" # did it change ? mark it as changed tfile="$(echo "$file" | $TRANSFORM)" if eval diff "$(echo "${DIFF_FLAGS}" \ | sed "s#@@#${tfile}#g")" \ "$i" "$i.new" 1>&2; then rm "$i.new" else echo "Patch $i for $file updated" >&2 mv "$i" "$i.orig" mv "$i.new" "$i" edit="$edit $i" fi continue 2 fi done # Build a sensible name for the new patch file patchname=patch-$(echo "$file" | sed -e 's#[/. ]#_#g') echo "No patch-* found for $file, creating $patchname" >&2 ( cd $D_BASE && do_diff "$file" "$D_SUB.orig" "$D_SUB" ) >$patchname edit="$edit $patchname" accounted="$accounted $patchname" done # Verify all patches accounted for cd $PATCHDIR for i in *; do [[ ! -f $i || $i = *@(.orig|.rej|~) ]] && continue grep '^\\ No newline at end of file' $i >/dev/null \ && echo "*** Patch $i needs manual intervention" >&2 [[ $accounted != *@($i)* ]] \ && echo "*** Patch $i not accounted for" >&2 done echo $edit [[ -n $SUBDIST ]] && mv ${WRKDIR1}/${SUBDIST}.orig ${WRKDIR1}.orig/${SUBDIST} exit 0