update-patches 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #!/usr/bin/env bash
  2. # Copyright (c) 2006
  3. # Thorsten Glaser <tg@freewrt.org>
  4. #
  5. # Derived from the MirPorts Framework "update-patches" script:
  6. #
  7. # Copyright (c) 2003, 2004, 2005
  8. # Thorsten "mirabile" Glaser <tg@MirBSD.de>
  9. # Based upon code and idea (c) 2000
  10. # Marc Espie for the OpenBSD project. All rights reserved.
  11. #
  12. # Provided that these terms and disclaimer and all copyright notices
  13. # are retained or reproduced in an accompanying document, permission
  14. # is granted to deal in this work without restriction, including un-
  15. # limited rights to use, publicly perform, distribute, sell, modify,
  16. # merge, give away, or sublicence.
  17. #
  18. # This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
  19. # the utmost extent permitted by applicable law, neither express nor
  20. # implied; without malicious intent or gross negligence. In no event
  21. # may a licensor, author or contributor be held liable for indirect,
  22. # direct, other damage, loss, or other issues arising in any way out
  23. # of dealing in the work, even if advised of the possibility of such
  24. # damage or existence of a defect, except proven that it results out
  25. # of said person's immediate fault when using the work as intended.
  26. [[ -n $BASH_VERSION ]] && shopt -s extglob
  27. do_diff()
  28. {
  29. local f1=$2/$1
  30. local f2=$3/$1
  31. if [[ ! -e $f1 ]]; then
  32. [[ -d ${f1%/*}/. ]] || mkdir -p ${f1%/*}
  33. if [[ ! -s $f2 ]]; then
  34. cat <<EOF
  35. --- $f1 (non-existant)
  36. +++ $f2 (empty)
  37. @@ -0,0 +0,0 @@
  38. EOF
  39. return 0
  40. fi
  41. touch -t 197001010000.00 "$f1"
  42. fi
  43. diff -adup "$f1" "$f2"
  44. return $?
  45. }
  46. TRANSFORM='sed s/[.+]/\\\\&/g'
  47. PATCHDIR=$CURDIR/patches
  48. EXTRADIR=$CURDIR/extra
  49. mkdir -p $PATCHDIR
  50. SUBDIST=${WRKDIST##${WRKDIR1}?(/)}
  51. if [[ -n $SUBDIST ]]; then
  52. mv ${WRKDIR1}.orig/${SUBDIST} ${WRKDIR1}/${SUBDIST}.orig
  53. D_BASE=${WRKDIR1}
  54. D_SUB=${SUBDIST}
  55. # D_SUBP=$D_SUB
  56. D_SUBP='[^/]*'
  57. D_CMP=$D_SUBP
  58. else
  59. # WRKSRC == WRKDIR
  60. D_BASE=$(dirname ${WRKDIR1})
  61. D_SUB=$(basename ${WRKDIR1})
  62. D_SUBP=$D_SUB
  63. D_CMP=
  64. fi
  65. ORGDIST=${D_BASE}/${D_SUB}.orig
  66. if [[ -e $WRKDIST/.patched-newfiles ]]; then
  67. touch $ORGDIST/.patched-newfiles
  68. patch_newfiles=1
  69. else
  70. patch_newfiles=0
  71. fi
  72. if [[ -e $WRKDIST/../.autoreconf_done ]]; then
  73. touch $ORGDIST/.autoreconf_done
  74. ignore_autoconf=1
  75. else
  76. ignore_autoconf=0
  77. fi
  78. DIFF_FLAGS="-adu -I \"^--- $(echo $D_SUBP.orig/ | $TRANSFORM)@@ .*\""
  79. DIFF_FLAGS="$DIFF_FLAGS -I \"^\+\+\+ $(echo $D_SUBP/ | $TRANSFORM)@@ .*\""
  80. for file in $(cd ${WRKDIST}; find . -type f | sed 's#^\./##'); do
  81. echo "DEBUG: $file" >> /tmp/debug
  82. [[ ! -e $ORGDIST/$file && $patch_newfiles = 0 ]] && continue
  83. [[ $file = configure && $ignore_autoconf = 1 ]] && continue
  84. [[ $file = missing && $ignore_autoconf = 1 ]] && continue
  85. [[ $file = depcomp && $ignore_autoconf = 1 ]] && continue
  86. [[ $file = install-sh && $ignore_autoconf = 1 ]] && continue
  87. [[ $file = aclocal.m4 && $ignore_autoconf = 1 ]] && continue
  88. [[ $file = INSTALL && $ignore_autoconf = 1 ]] && continue
  89. [[ $file = config.h.in && $ignore_autoconf = 1 ]] && continue
  90. [[ $(basename $file) = Makefile.in && $ignore_autoconf = 1 ]] && continue
  91. cmp -s "$ORGDIST/$file" "$WRKDIST/$file" && continue
  92. echo "Processing ${file}..." >&2
  93. # look in patchdir for an existing patchfile matching this
  94. cd $PATCHDIR
  95. for i in $PATCH_LIST; do
  96. # Ignore non-files, or old backup
  97. [[ ! -f $i || $i = *@(.orig|.rej|~) ]] && continue
  98. # Patch found. Is this the one?
  99. if grep "^[+-][+-][+-] $D_CMP[^/]*/$file " "$i" >/dev/null; then
  100. # Multiple files in the diff?
  101. if [ $(grep -c "^--- $D_CMP" "$i") -gt 1 -o \
  102. $(grep -c "^+++ $D_CMP" "$i") -gt 1 ]; then
  103. echo "Cannot process, $i contains patches" >&2
  104. echo "to multiple files! Aborting." >&2
  105. echo FAIL
  106. [[ -n $SUBDIST ]] && mv \
  107. ${WRKDIR1}/${SUBDIST}.orig \
  108. ${WRKDIR1}.orig/${SUBDIST}
  109. exit 0
  110. fi
  111. # Multiple diffs with this file?
  112. let n=0
  113. pflst=
  114. for j in $PATCH_LIST; do
  115. [[ ! -f $j || $j = *@(.orig|.rej|~) ]] && \
  116. continue
  117. grep "^[+-][+-][+-] $D_CMP[^/]*/$file " \
  118. "$j" >/dev/null || continue
  119. let n++
  120. pflst="$pflst '$j'"
  121. done
  122. if (( n != 1 )); then
  123. echo "Cannot process, file $file" >&2
  124. echo "is contained in multiple patches:" >&2
  125. echo "$pflst" >&2
  126. echo FAIL
  127. [[ -n $SUBDIST ]] && mv \
  128. ${WRKDIR1}/${SUBDIST}.orig \
  129. ${WRKDIR1}.orig/${SUBDIST}
  130. exit 0
  131. fi
  132. # No, process this patch
  133. accounted="$accounted $i"
  134. # found it, copy preamble before comparision
  135. ( sed -e "/^--- /,\$d" <$i; \
  136. cd $D_BASE && do_diff "$file" "$D_SUB.orig" "$D_SUB" \
  137. ) >"$i.new"
  138. # did it change ? mark it as changed
  139. tfile="$(echo "$file" | $TRANSFORM)"
  140. if eval diff "$(echo "${DIFF_FLAGS}" \
  141. | sed "s#@@#${tfile}#g")" \
  142. "$i" "$i.new" 1>&2; then
  143. rm "$i.new"
  144. else
  145. echo "Patch $i for $file updated" >&2
  146. mv "$i" "$i.orig"
  147. mv "$i.new" "$i"
  148. edit="$edit $i"
  149. fi
  150. continue 2
  151. fi
  152. done
  153. # Build a sensible name for the new patch file
  154. patchname=patch-$(echo "$file" | sed -e 's#[/. ]#_#g')
  155. echo "No patch-* found for $file, creating $patchname" >&2
  156. ( cd $D_BASE && do_diff "$file" "$D_SUB.orig" "$D_SUB" ) >$patchname
  157. edit="$edit $patchname"
  158. accounted="$accounted $patchname"
  159. done
  160. # Verify all patches accounted for
  161. cd $PATCHDIR
  162. for i in *; do
  163. [[ ! -f $i || $i = *@(.orig|.rej|~) ]] && continue
  164. grep '^\\ No newline at end of file' $i >/dev/null \
  165. && echo "*** Patch $i needs manual intervention" >&2
  166. [[ $accounted != *@($i)* ]] \
  167. && echo "*** Patch $i not accounted for" >&2
  168. done
  169. echo $edit
  170. [[ -n $SUBDIST ]] && mv ${WRKDIR1}/${SUBDIST}.orig ${WRKDIR1}.orig/${SUBDIST}
  171. exit 0