Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148559980
D4136.id10133.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D4136.id10133.diff
View Options
Index: Mk/Scripts/smart_makepatch.sh
===================================================================
--- /dev/null
+++ Mk/Scripts/smart_makepatch.sh
@@ -0,0 +1,201 @@
+#!/bin/sh
+# MAINTAINER: portmgr@FreeBSD.org
+# $FreeBSD$
+
+# This script regenerates patches. It conserves existing comments and
+# file names, even if the file name does not meet any current or
+# previous convention. It will keep multiple patches in the same file
+# rather than splitting them into individual files.
+#
+# If a generated patch was not present before, it will create a file
+# name where forward slashes are replaced with an underscore and
+# underscores are appended by another underscore.
+#
+# Limitations:
+# 1) If a file is modified by multiple patches, it will be regenerated
+# as a single patch. That means if two multi-patch files modified
+# the same source file, when regenerated, the source file's patch
+# will only appear in one of patch file.
+# 2) It's possible that trailing garbage at the end of a patch in a
+# multipatch file might corrupt the comment (or be interpreted as
+# a comment) of the following patch. (garbage in, garbage out)
+#
+# Reminder
+# Don't forget to disable post-patch targets before regenerating patches
+# if those targets modify source files (e.g. with sed). You may also
+# want to disable EXTRA_PATCHES as well if that is being used.
+
+
+if [ -z "${PATCHDIR}" -o -z "${PATCH_WRKSRC}" -o -z "${WRKDIR}" ]; then
+ echo "WRKDIR, PATCHDIR, and PATCH_WRKSRC required in environment." >&2
+ exit 1
+fi
+
+WORKAREA=${WRKDIR}/makepatch-tmp
+PATCHMAP=${WORKAREA}/pregen.map
+COMMENTS=${WORKAREA}/comments
+REGENNED=${WORKAREA}/regenerated
+DESTDIR=${WORKAREA}/staged
+SAVEDIR=${WORKAREA}/archived-patches
+
+case "${STRIP_COMPONENTS}" in
+ [123456789]) ;;
+ 1[0123456789]) ;;
+ *) STRIP_COMPONENTS=0
+esac
+
+strip_path() {
+ raw_name=$1
+ if [ "${STRIP_COMPONENTS}" = "0" ]; then
+ echo ${raw_name}
+ else
+ echo ${raw_name} | awk -v sc=${STRIP_COMPONENTS} -F "/" \
+ '{ for (x = sc + 1; x <= NF; x++) { \
+ slash = (x>sc+1) ? "/" : ""; \
+ printf ("%s%s", slash, $x); \
+ }}'
+ fi
+}
+
+std_patch_filename() {
+ raw_name=$(strip_path $1)
+ echo patch-$(echo ${raw_name} | sed -e 's|_|&&|g; s|/|_|g')
+}
+
+patchdir_files_list() {
+ if [ -d "${PATCHDIR}" ]; then
+ (cd ${PATCHDIR} && \
+ find * -type f -name "patch-*" -maxdepth 0 \
+ 2>/dev/null | sed -e '/\.orig$/d'
+ )
+ fi;
+}
+
+map_existing_patches() {
+ mkdir -p ${WORKAREA}
+ : > ${PATCHMAP}
+ for P in ${old_patch_list}; do
+ target=$(cd ${PATCHDIR} && \
+ grep "^+++ " ${P} | awk '{print $2}'
+ )
+ for t in ${target}; do
+ std_target=$(std_patch_filename ${t})
+ echo "${P} ${std_target}" >> ${PATCHMAP}
+ done
+ done
+}
+
+extract_comment_from_patch() {
+ existing_patch=${PATCHDIR}/$1
+ contains=$(grep "^+++ " ${existing_patch} | awk '{x++; print x }')
+ for num in ${contains}; do
+ rawname=$(grep "^+++ " ${existing_patch} | \
+ awk -v num=${num} '{x++; if (x==num) print $2}')
+ fname=$(std_patch_filename $rawname)
+ awk -v num=${num} '\
+ BEGIN { done=0; x=0; hunk=0; looking=(num==1) } \
+ { \
+ if (!done) { \
+ if ($1 == "@@") { \
+ split ($3,a,","); \
+ hc = a[2]; \
+ hunk = 1;
+ } else if (hunk) { \
+ first=substr($1,1,1); \
+ if (first == "-") { hc++ } else { hc-- } \
+ if (hc == 0) {hunk = 0} \
+ } \
+ if ($1 == "---") { \
+ x++; \
+ if (x == num) { done = 1 } \
+ if (x + 1 == num) { looking = 1 } \
+ } else if (!hunk && looking) { \
+ if ($1!="diff" && $1!="index" && $1!="+++") {\
+ print $0 \
+ } \
+ } \
+ } \
+ }' ${existing_patch} > ${COMMENTS}/${fname}
+ done
+}
+
+extract_comments() {
+ mkdir -p ${COMMENTS}
+ rm -f ${COMMENTS}/*
+ for P in ${old_patch_list}; do
+ extract_comment_from_patch ${P}
+ done
+}
+
+regenerate_patches() {
+ mkdir -p ${REGENNED}
+ rm -f ${REGENNED}/*
+ new_list=
+ [ ! -d "${PATCH_WRKSRC}" ] && return
+
+ new_list=$(cd ${PATCH_WRKSRC} && \
+ find -s * -type f -name '*.orig' 2>/dev/null)
+ (cd ${PATCH_WRKSRC} && for F in ${new_list}; do
+ ORIG=${F#./}
+ NEW=${ORIG%.orig}
+ cmp -s ${ORIG} ${NEW} && continue
+ OUT=${REGENNED}/$(std_patch_filename ${NEW})
+ TZ=UTC diff -udp ${ORIG} ${NEW} | sed \
+ -e '/^---/s|\.[0-9]* +0000$| UTC|' \
+ -e '/^+++/s|\([[:blank:]][-0-9:.+]*\)*$||' \
+ > ${OUT} || true
+ done)
+}
+
+get_patch_name() {
+ awk -v name=$1 '\
+ { if ($2 == name) \
+ { \
+ if (!done) { print $1 }; \
+ done = 1; \
+ } \
+ } \
+ END { if (!done) print name }' ${PATCHMAP}
+}
+
+stage_patches() {
+ mkdir -p ${DESTDIR}
+ rm -f ${DESTDIR}/*
+ patch_list=$(cd ${REGENNED} && find * -name "patch-*" 2>/dev/null)
+ for P in ${patch_list}; do
+ name=$(get_patch_name ${P})
+ [ -e ${COMMENTS}/${P} ] && cat ${COMMENTS}/${P} \
+ >> ${DESTDIR}/${name}
+ echo "Transfer ${P} '>>' ${name}"
+ cat ${REGENNED}/${P} >> ${DESTDIR}/${name}
+ done
+}
+
+conserve_old_patches() {
+ mkdir -p ${SAVEDIR}
+ rm -f ${SAVEDIR}/*
+ [ -z "${old_patch_list}" ] && return
+
+ for P in ${old_patch_list}; do
+ mv ${PATCHDIR}/${P} ${SAVEDIR}/${P}
+ done
+ echo "The previous patches have been placed here:"
+ echo ${SAVEDIR}
+}
+
+install_regenerated_patches() {
+ testdir=$(find ${DESTDIR} -empty)
+ if [ -z "${testdir}" ]; then
+ mkdir -p ${PATCHDIR}
+ find ${DESTDIR} -type f -exec mv {} ${PATCHDIR}/ \;
+ fi
+}
+
+old_patch_list=$(patchdir_files_list)
+
+map_existing_patches
+extract_comments
+regenerate_patches
+stage_patches
+conserve_old_patches
+install_regenerated_patches
Index: Mk/bsd.port.mk
===================================================================
--- Mk/bsd.port.mk
+++ Mk/bsd.port.mk
@@ -1114,44 +1114,12 @@
.else
-# Look for files named "*.orig" under ${PATCH_WRKSRC} and (re-)generate
-# ${PATCHDIR}/patch-* files from them. By popular demand, we currently
-# use '_' (underscore) to replace path separators in patch file names.
-#
-# If a file name happens to contain character which is also a separator
-# replacement character, it will be doubled in the resulting patch name.
-#
-# To minimize gratuitous patch renames, newly generated patches will be
-# written under existing file names when they use any of the previously
-# common path separators ([-+_]) or legacy double underscore (__).
-
.if !target(makepatch)
-PATCH_PATH_SEPARATOR= _
makepatch:
- @${MKDIR} ${PATCHDIR}
- @(cd ${PATCH_WRKSRC}; \
- for f in `${FIND} -s . -type f -name '*.orig'`; do \
- ORIG=$${f#./}; \
- NEW=$${ORIG%.orig}; \
- cmp -s $${ORIG} $${NEW} && continue; \
- ! for _lps in `${ECHO} _ - + | ${SED} -e \
- 's|${PATCH_PATH_SEPARATOR}|__|'`; do \
- PATCH=`${ECHO} $${NEW} | ${SED} -e "s|/|$${_lps}|g"`; \
- test -f "${PATCHDIR}/patch-$${PATCH}" && break; \
- done || ${ECHO} $${_SEEN} | ${GREP} -q /$${PATCH} && { \
- PATCH=`${ECHO} $${NEW} | ${SED} -e \
- 's|${PATCH_PATH_SEPARATOR}|&&|g' -e \
- 's|/|${PATCH_PATH_SEPARATOR}|g'`; \
- _SEEN=$${_SEEN}/$${PATCH}; \
- }; \
- OUT=${PATCHDIR}/patch-$${PATCH}; \
- ${ECHO} ${DIFF} -udp $${ORIG} $${NEW} '>' $${OUT}; \
- TZ=UTC ${DIFF} -udp $${ORIG} $${NEW} | ${SED} -e \
- '/^---/s|\.[0-9]* +0000$$| UTC|' -e \
- '/^+++/s|\([[:blank:]][-0-9:.+]*\)*$$||' \
- > $${OUT} || ${TRUE}; \
- done \
- )
+ @${SETENV} WRKDIR=${WRKDIR} PATCHDIR=${PATCHDIR} \
+ PATCH_WRKSRC=${PATCH_WRKSRC} \
+ STRIP_COMPONENTS="${PATCH_STRIP:S/-p//}" \
+ ${SH} ${SCRIPTSDIR}/smart_makepatch.sh
.endif
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 19, 6:18 PM (22 h, 7 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29973393
Default Alt Text
D4136.id10133.diff (7 KB)
Attached To
Mode
D4136: Greatly enhance "make makepatch" (address 2 major deficiencies)
Attached
Detach File
Event Timeline
Log In to Comment