Bug 168222

Summary: [bsd.port.mk] [patch] Allowing to specify per-file PATCH_DIST_STRIP in PATCHFILES
Product: Ports & Packages Reporter: Akinori MUSHA <knu>
Component: Individual Port(s)Assignee: Bryan Drewery <bdrewery>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Latest   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description Akinori MUSHA freebsd_committer freebsd_triage 2012-05-22 09:50:02 UTC
When trying to integrate multiple external patches, you are lucky if all of them have a common base directory, but if any of them has a different base directory, your head starts to ache thinking you'll have to do:

- move the PATCHFILES/PATCH_SITES entry to DISTFILES/MASTER_SITES
- add the patch file to EXTRACT_ONLY
- write a custom pre- or post-patch target by hand to apply it

You can alternatively download the patch files and put them under PATCHDIR, which means we duplicate a patch file that's available on the Internet and host it in our ports tree.  It is waste of space and we might lose the chance to notice when the patch file is withdrawn or updated by the author.

Fix: Apply the attached patch that enables per-file patch flags in PATCHFILES.

Patch attached with submission follows:
How-To-Repeat: A simple search only found three ports that call patch with -p# against a distfile:

/usr/ports/graphics/xv/Makefile
/usr/ports/mail/qmail/Makefile
/usr/ports/www/squidguard/Makefile

But I'm sure there are a lot of hidden third party patches in PATCHDIR's.
Comment 1 Akinori MUSHA freebsd_committer freebsd_triage 2012-05-22 09:51:23 UTC
Responsible Changed
From-To: freebsd-ports-bugs->portmgr

This is a patch for bsd.port.mk.
Comment 2 Bryan Drewery freebsd_committer freebsd_triage 2013-04-22 13:55:31 UTC
Responsible Changed
From-To: portmgr->bdrewery

I'll take it.
Comment 3 Akinori MUSHA 2013-07-18 18:04:31 UTC
Just in case someone is still interested, here's an updated patch.

Index: bsd.port.mk
===================================================================
--- bsd.port.mk	(revision 321718)
+++ bsd.port.mk	(working copy)
@@ -107,6 +107,9 @@ FreeBSD_MAINTAINER=	portmgr@FreeBSD.org
 #				  patches. Make will look for them at PATCH_SITES (see below).
 #				  They will automatically be uncompressed before patching if
 #				  the names end with ".gz", ".bz2" or ".Z".
+#				  For each file you can optionally specify a strip
+#				  flag of patch(1) after a colon if it has a different
+#				  base directory, e.g. "file1 file2:-p1 file3".
 #				  Default: not set.
 # PATCH_SITES	- Primary location(s) for distribution patch files
 #				  if not found locally.
@@ -2677,9 +2680,12 @@ _DISTFILES+=	${_D}
 .endfor
 _G_TEMP=	DEFAULT
 .for _P in ${PATCHFILES}
-_P_TEMP=	${_P:S/^${_P:C/:[^:]+$//}//}
-.	if !empty(_P_TEMP)
-.		for _group in ${_P_TEMP:S/^://:S/,/ /g}
+_P_TEMP=	${_P:C/:[^-:][^:]*$//}
+_P_groups=	${_P:S/^${_P:C/:[^:]+$//}//:S/^://}
+_P_file=	${_P_TEMP:C/:-[^:]+$//}
+_P_strip=	${_P_TEMP:S/^${_P_TEMP:C/:-[^:]*$//}//:S/^://}
+.	if !empty(_P_groups)
+.		for _group in ${_P_groups:S/,/ /g}
 .			if !defined(_PATCH_SITES_${_group})
 _G_TEMP_TEMP=	${_G_TEMP:M/${_group}/}
 .				if empty(_G_TEMP_TEMP)
@@ -2688,11 +2694,15 @@ _PATCH_SITES_ALL+=	${_PATCH_SITES_${_gro
 .				endif
 .			endif
 .		endfor
-_PATCHFILES+=	${_P:C/:[^:]+$//}
-.	else
-_PATCHFILES+=	${_P}
+.	endif
+_PATCHFILES:=	${_PATCHFILES} ${_P_file}
+.	if !empty(_P_strip)
+_PATCH_DIST_STRIP_CASES:=	${_PATCH_DIST_STRIP_CASES} ("${_P_file}") printf %s "${_P_strip}" ;;
 .	endif
 .endfor
+_P_groups=
+_P_file=
+_P_strip=
 _G_TEMP=
 _G_TEMP_TEMP=
 ALLFILES?=	${_DISTFILES} ${_PATCHFILES}
@@ -2761,7 +2771,7 @@ _MASTER_SITES_ENV+=	_MASTER_SITES_${_gro
 .endfor
 _PATCH_SITES_ENV=	_PATCH_SITES_DEFAULT="${_PATCH_SITES_DEFAULT}"
 .for _F in ${PATCHFILES}
-_F_TEMP=	${_F:S/^${_F:C/:[^:]+$//}//:S/^://}
+_F_TEMP=	${_F:S/^${_F:C/:[^-:][^:]*$//}//:S/^://}
 .	if !empty(_F_TEMP)
 .		for _group in ${_F_TEMP:S/,/ /g}
 .			if defined(_PATCH_SITES_${_group})
@@ -3488,8 +3498,9 @@ do-fetch:
 	@cd ${_DISTDIR};\
 	${_PATCH_SITES_ENV} ; \
 	for _file in ${PATCHFILES}; do \
-		file=`${ECHO_CMD} $$_file | ${SED} -E -e 's/:[^:]+$$//'` ; \
+		file=`${ECHO_CMD} $$_file | ${SED} -E -e 's/:[^-:][^:]*$$//'` ; \
 		select=`${ECHO_CMD} $${_file#$${file}} | ${SED} -e 's/^://' -e 's/,/ /g'` ; \
+		file=`${ECHO_CMD} $$file | ${SED} -E -e 's/:-[^:]+$$//'` ; \
 		force_fetch=false; \
 		filebasename=$${file##*/}; \
 		for afile in ${FORCE_FETCH}; do \
@@ -3590,9 +3601,13 @@ patch-dos2unix:
 do-patch:
 .if defined(PATCHFILES)
 	@${ECHO_MSG} "===>  Applying distribution patches for ${PKGNAME}"
-	@set -e ; \
-	(cd ${_DISTDIR} ; \
-	for i  in ${_PATCHFILES}; do \
+	@(cd ${_DISTDIR}; \
+	patch_dist_strip () { \
+		case "$$1" in \
+		${_PATCH_DIST_STRIP_CASES} \
+		esac; \
+	}; \
+	for i in ${_PATCHFILES}; do \
 		if [ ${PATCH_DEBUG_TMP} = yes ]; then \
 			${ECHO_MSG} "===>   Applying distribution patch $$i" ; \
 		fi ; \
@@ -3601,7 +3616,7 @@ do-patch:
 		*.bz2) ${BZCAT} $$i ;; \
 		*.xz) ${XZCAT} $$i ;; \
 		*) ${CAT} $$i ;; \
-		esac | ${PATCH} ${PATCH_DIST_ARGS} ; \
+		esac | ${PATCH} ${PATCH_DIST_ARGS} `patch_dist_strip $$i` ; \
 	done )
 .endif
 .if defined(EXTRA_PATCHES)
@@ -4635,8 +4650,9 @@ fetch-list:
 	@(cd ${_DISTDIR}; \
 	 ${_PATCH_SITES_ENV} ; \
 	 for _file in ${PATCHFILES}; do \
-		file=`${ECHO_CMD} $$_file | ${SED} -E -e 's/:[^:]+$$//'` ; \
+		file=`${ECHO_CMD} $$_file | ${SED} -E -e 's/:[^-:][^:]*$$//'` ; \
 		select=`${ECHO_CMD} $${_file#$${file}} | ${SED} -e 's/^://' -e 's/,/ /g'` ; \
+		file=`${ECHO_CMD} $$file | ${SED} -E -e 's/:-[^:]+$$//'` ; \
 		if [ ! -f $$file -a ! -f $${file##*/} ]; then \
 			if [ ! -z "$$select" ] ; then \
 				__PATCH_SITES_TMP= ; \
@@ -4701,9 +4717,10 @@ fetch-url-list-int:
 	@(cd ${_DISTDIR}; \
 	${_PATCH_SITES_ENV} ; \
 	for _file in ${PATCHFILES}; do \
-		file=`${ECHO_CMD} $$_file | ${SED} -E -e 's/:[^:]+$$//'` ; \
-			fileptn=`${ECHO_CMD} $$file | ${SED} 's|/|\\\\/|g;s/\./\\\\./g;s/\+/\\\\+/g;s/\?/\\\\?/g'` ; \
+		file=`${ECHO_CMD} $$_file | ${SED} -E -e 's/:[^-:][^:]*$$//'` ; \
 		select=`${ECHO_CMD} $${_file#$${file}} | ${SED} -e 's/^://' -e 's/,/ /g'` ; \
+		file=`${ECHO_CMD} $$file | ${SED} -E -e 's/:-[^:]+$$//'` ; \
+		fileptn=`${ECHO_CMD} $$file | ${SED} 's|/|\\\\/|g;s/\./\\\\./g;s/\+/\\\\+/g;s/\?/\\\\?/g'` ; \
 		if [ ! -z "${LISTALL}" -o ! -f $$file -a ! -f $${file##*/} ]; then \
 			if [ ! -z "$$select" ] ; then \
 				__PATCH_SITES_TMP= ; \
Comment 4 Bryan Drewery freebsd_committer freebsd_triage 2013-07-23 12:03:25 UTC
On 7/18/2013 12:04 PM, Akinori MUSHA wrote:
> Just in case someone is still interested, here's an updated patch.


Thanks. I do plan to exp-run this soon.


-- 
Regards,
Bryan Drewery
Comment 5 Bryan Drewery freebsd_committer freebsd_triage 2013-10-05 11:20:23 UTC
State Changed
From-To: open->closed

Committed. Thanks!
Comment 6 dfilter service freebsd_committer freebsd_triage 2013-10-05 11:20:29 UTC
Author: bdrewery
Date: Sat Oct  5 10:20:15 2013
New Revision: 329434
URL: http://svnweb.freebsd.org/changeset/ports/329434

Log:
  - PATCHFILES now support an optional :-pX flag that notes which patch strip
    level to use. This allows multiple patches in 1 port to use different
    PATCH_DIST_STRIP values without changing PATCH_DIST_STRIP.
  
    Syntax: PATCHFILES= patch[:-pX][:distgroup]
  
  PR:		ports/168222
  Submitted by:	knu
  With hat:	portmgr

Modified:
  head/CHANGES
  head/Mk/bsd.port.mk

Modified: head/CHANGES
==============================================================================
--- head/CHANGES	Sat Oct  5 10:18:20 2013	(r329433)
+++ head/CHANGES	Sat Oct  5 10:20:15 2013	(r329434)
@@ -10,6 +10,15 @@ in the release notes and/or placed into 
 
 All ports committers are allowed to commit to this file.
 
+20131005:
+AUTHOR: bdrewery@FreeBSD.org
+
+  PATCHFILES now support an optional :-pX flag that notes which patch strip
+  level to use. This allows multiple patches in 1 port to use different
+  PATCH_DIST_STRIP values without changing PATCH_DIST_STRIP.
+
+  Syntax: PATCHFILES= patch[:-pX][:distgroup]
+
 20131003:
 AUTHOR: bapt@FreeBSD.org
 

Modified: head/Mk/bsd.port.mk
==============================================================================
--- head/Mk/bsd.port.mk	Sat Oct  5 10:18:20 2013	(r329433)
+++ head/Mk/bsd.port.mk	Sat Oct  5 10:20:15 2013	(r329434)
@@ -107,6 +107,12 @@ FreeBSD_MAINTAINER=	portmgr@FreeBSD.org
 #				  patches. Make will look for them at PATCH_SITES (see below).
 #				  They will automatically be uncompressed before patching if
 #				  the names end with ".gz", ".bz2" or ".Z".
+#				  For each file you can optionally specify a strip
+#				  flag of patch(1) after a colon if it has a different
+#				  base directory, e.g. "file1 file2:-p1 file3".
+#				  You can also use a :group at the end for matching up to
+#				  dist file groups. See Porters Handbook for more information.
+#				  Syntax: PATCHFILES= patch[:-pX][:group]
 #				  Default: not set.
 # PATCH_SITES	- Primary location(s) for distribution patch files
 #				  if not found locally.
@@ -2650,9 +2656,12 @@ _DISTFILES+=	${_D}
 .endfor
 _G_TEMP=	DEFAULT
 .for _P in ${PATCHFILES}
-_P_TEMP=	${_P:S/^${_P:C/:[^:]+$//}//}
-.	if !empty(_P_TEMP)
-.		for _group in ${_P_TEMP:S/^://:S/,/ /g}
+_P_TEMP=	${_P:C/:[^-:][^:]*$//}
+_P_groups=	${_P:S/^${_P:C/:[^:]+$//}//:S/^://}
+_P_file=	${_P_TEMP:C/:-[^:]+$//}
+_P_strip=	${_P_TEMP:S/^${_P_TEMP:C/:-[^:]*$//}//:S/^://}
+.	if !empty(_P_groups)
+.		for _group in ${_P_groups:S/,/ /g}
 .			if !defined(_PATCH_SITES_${_group})
 _G_TEMP_TEMP=	${_G_TEMP:M/${_group}/}
 .				if empty(_G_TEMP_TEMP)
@@ -2661,11 +2670,15 @@ _PATCH_SITES_ALL+=	${_PATCH_SITES_${_gro
 .				endif
 .			endif
 .		endfor
-_PATCHFILES+=	${_P:C/:[^:]+$//}
-.	else
-_PATCHFILES+=	${_P}
+.	endif
+_PATCHFILES:=	${_PATCHFILES} ${_P_file}
+.	if !empty(_P_strip)
+_PATCH_DIST_STRIP_CASES:=	${_PATCH_DIST_STRIP_CASES} ("${_P_file}") printf %s "${_P_strip}" ;;
 .	endif
 .endfor
+_P_groups=
+_P_file=
+_P_strip=
 _G_TEMP=
 _G_TEMP_TEMP=
 ALLFILES?=	${_DISTFILES} ${_PATCHFILES}
@@ -2734,7 +2747,7 @@ _MASTER_SITES_ENV+=	_MASTER_SITES_${_gro
 .endfor
 _PATCH_SITES_ENV=	_PATCH_SITES_DEFAULT="${_PATCH_SITES_DEFAULT}"
 .for _F in ${PATCHFILES}
-_F_TEMP=	${_F:S/^${_F:C/:[^:]+$//}//:S/^://}
+_F_TEMP=	${_F:S/^${_F:C/:[^-:][^:]*$//}//:S/^://}
 .	if !empty(_F_TEMP)
 .		for _group in ${_F_TEMP:S/,/ /g}
 .			if defined(_PATCH_SITES_${_group})
@@ -3487,8 +3500,9 @@ do-fetch:
 	@cd ${_DISTDIR};\
 	${_PATCH_SITES_ENV} ; \
 	for _file in ${PATCHFILES}; do \
-		file=`${ECHO_CMD} $$_file | ${SED} -E -e 's/:[^:]+$$//'` ; \
+		file=`${ECHO_CMD} $$_file | ${SED} -E -e 's/:[^-:][^:]*$$//'` ; \
 		select=`${ECHO_CMD} $${_file#$${file}} | ${SED} -e 's/^://' -e 's/,/ /g'` ; \
+		file=`${ECHO_CMD} $$file | ${SED} -E -e 's/:-[^:]+$$//'` ; \
 		force_fetch=false; \
 		filebasename=$${file##*/}; \
 		for afile in ${FORCE_FETCH}; do \
@@ -3589,9 +3603,13 @@ patch-dos2unix:
 do-patch:
 .if defined(PATCHFILES)
 	@${ECHO_MSG} "===>  Applying distribution patches for ${PKGNAME}"
-	@set -e ; \
-	(cd ${_DISTDIR} ; \
-	for i  in ${_PATCHFILES}; do \
+	@(cd ${_DISTDIR}; \
+	patch_dist_strip () { \
+		case "$$1" in \
+		${_PATCH_DIST_STRIP_CASES} \
+		esac; \
+	}; \
+	for i in ${_PATCHFILES}; do \
 		if [ ${PATCH_DEBUG_TMP} = yes ]; then \
 			${ECHO_MSG} "===>   Applying distribution patch $$i" ; \
 		fi ; \
@@ -3600,7 +3618,7 @@ do-patch:
 		*.bz2) ${BZCAT} $$i ;; \
 		*.xz) ${XZCAT} $$i ;; \
 		*) ${CAT} $$i ;; \
-		esac | ${PATCH} ${PATCH_DIST_ARGS} ; \
+		esac | ${PATCH} ${PATCH_DIST_ARGS} `patch_dist_strip $$i` ; \
 	done )
 .endif
 .if defined(EXTRA_PATCHES)
@@ -4718,8 +4736,9 @@ fetch-list:
 	@(cd ${_DISTDIR}; \
 	 ${_PATCH_SITES_ENV} ; \
 	 for _file in ${PATCHFILES}; do \
-		file=`${ECHO_CMD} $$_file | ${SED} -E -e 's/:[^:]+$$//'` ; \
+		file=`${ECHO_CMD} $$_file | ${SED} -E -e 's/:[^-:][^:]*$$//'` ; \
 		select=`${ECHO_CMD} $${_file#$${file}} | ${SED} -e 's/^://' -e 's/,/ /g'` ; \
+		file=`${ECHO_CMD} $$file | ${SED} -E -e 's/:-[^:]+$$//'` ; \
 		if [ ! -f $$file -a ! -f $${file##*/} ]; then \
 			if [ ! -z "$$select" ] ; then \
 				__PATCH_SITES_TMP= ; \
@@ -4784,9 +4803,10 @@ fetch-url-list-int:
 	@(cd ${_DISTDIR}; \
 	${_PATCH_SITES_ENV} ; \
 	for _file in ${PATCHFILES}; do \
-		file=`${ECHO_CMD} $$_file | ${SED} -E -e 's/:[^:]+$$//'` ; \
-			fileptn=`${ECHO_CMD} $$file | ${SED} 's|/|\\\\/|g;s/\./\\\\./g;s/\+/\\\\+/g;s/\?/\\\\?/g'` ; \
+		file=`${ECHO_CMD} $$_file | ${SED} -E -e 's/:[^-:][^:]*$$//'` ; \
 		select=`${ECHO_CMD} $${_file#$${file}} | ${SED} -e 's/^://' -e 's/,/ /g'` ; \
+		file=`${ECHO_CMD} $$file | ${SED} -E -e 's/:-[^:]+$$//'` ; \
+		fileptn=`${ECHO_CMD} $$file | ${SED} 's|/|\\\\/|g;s/\./\\\\./g;s/\+/\\\\+/g;s/\?/\\\\?/g'` ; \
 		if [ ! -z "${LISTALL}" -o ! -f $$file -a ! -f $${file##*/} ]; then \
 			if [ ! -z "$$select" ] ; then \
 				__PATCH_SITES_TMP= ; \
_______________________________________________
svn-ports-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-ports-all
To unsubscribe, send any mail to "svn-ports-all-unsubscribe@freebsd.org"