123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- #!/usr/bin/env mksh
- #-
- # Copyright (c) 2014
- # Thorsten Glaser <tg@mirbsd.org>
- # 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.
- 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 $?
- }
- set -A accounted
- set -A edit
- 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"
- fi
- DIFF_FLAGS="-adu -I \"^--- $(print -r -- "$D_SUBP.orig/" | $TRANSFORM)@@ .*\""
- DIFF_FLAGS="$DIFF_FLAGS -I \"^\+\+\+ $(print -r -- "$D_SUBP/" | $TRANSFORM)@@ .*\""
- (cd "${WRKDIST}"; find . -type f -print0) |&
- while IFS= read -p -d '' -r file; do
- file=${file#./}
- [[ ! -e $ORGDIST/$file && $patch_newfiles = 0 ]] && continue
- for i in $DIFF_IGNOREFILES; do
- [[ $file = $i ]] && continue 2
- done
- cmp -s "$ORGDIST/$file" "$WRKDIST/$file" && continue
- print -ru2 -- "Processing ${file}..."
- # 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 || \
- $(grep -c "^+++ $D_CMP" "$i") -gt 1 ]]; then
- print -ru2 -- "Cannot process, $i contains patches"
- print -ru2 -- "to multiple files! Aborting."
- print -n 'FAIL\0'
- [[ -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
- print -ru2 -- "Cannot process, file $file"
- print -ru2 -- "is contained in multiple patches:"
- print -ru2 -- "$pflst"
- print -n 'FAIL\0'
- [[ -n $SUBDIST ]] && mv \
- "${WRKDIR1}/${SUBDIST}.orig" \
- "${WRKDIR1}.orig/${SUBDIST}"
- exit 0
- fi
- # No, process this patch
- 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=$(print -r -- "$file" | $TRANSFORM)
- if eval diff "$(print -r -- "${DIFF_FLAGS}" | sed \
- "s#@@#${tfile}#g")" '"$i" "$i.new"' 1>&2; then
- rm "$i.new"
- else
- print -ru2 -- "Patch $i for $file updated"
- mv "$i" "$i.orig"
- mv "$i.new" "$i"
- edit+=("$i")
- fi
- continue 2
- fi
- done
- # Build a sensible name for the new patch file
- patchname=patch-${file//[\/.- ]/_}
- print -ru2 -- "No patch-* found for $file, creating $patchname"
- ( cd "$D_BASE" && do_diff "$file" "$D_SUB.orig" "$D_SUB" ) >"$patchname"
- edit+=("$patchname")
- 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 && \
- print -ru2 -- "*** Patch $i needs manual intervention"
- found=0
- for j in "${accounted[@]}"; do
- [[ $i = "$j" ]] || continue
- found=1
- break
- done
- (( found )) || print -ru2 -- "*** Patch $i not accounted for"
- done
- for i in "${edit[@]}"; do
- print -nr -- "$i"
- print -n '\0'
- done
- [[ -n $SUBDIST ]] && mv "${WRKDIR1}/${SUBDIST}.orig" "${WRKDIR1}.orig/${SUBDIST}"
- exit 0
|