Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 5 Jul 2014 12:04:57 +0000
From:      Mikolaj Golub <trociny@FreeBSD.org>
To:        freebsd-ports@freebsd.org
Subject:   COPYTREE_BIN/COPYTREE_SHARE does not work as expected
Message-ID:  <20140705120457.GA1772@gmail.com>

next in thread | raw e-mail | index | archive | help
Hi,

It looks like COPYTREE_BIN/COPYTREE_SHARE does not work as it is documented in
bsd.port.mk:

#                 Example use: 
#                 cd ${WRKSRC}/doc && ${COPYTREE_SHARE} . ${DOCSDIR} "! -name *.bak"
#
#                 Installs all directories and files from ${WRKSRC}/doc
#                 to ${DOCSDIR} except sed backup files.

If there is a "*.bak" file in . directory (e.g. test.bak), "*.bak" is
expanded to this name, the condition "! -name *.bak" becomes "! -name test.bak",
and other *.bak files are ignored.

Worse, if there are several "*.bak" files, "*.bak" is expanded to the
list and COPYTREE_SHARE fails.

Below is a test that demonstrates this:

[golub@zhuzha ~/freebsd/ports/test]$ cat Makefile 
TESTDIR=	/tmp/test_COPYTREE_SHARE

all: test1 test2

test1:
	${RM} -rf ${TESTDIR}
	${MKDIR} ${TESTDIR}/src/1
	${TOUCH} ${TESTDIR}/src/1.bak
	${TOUCH} ${TESTDIR}/src/1/1.bak
	${TOUCH} ${TESTDIR}/src/1/2.bak
	(cd ${TESTDIR}/src && ${COPYTREE_SHARE} . ${TESTDIR}/dst "! -name *.bak")
	@echo "=> Listing destination (no *.bak files are expected):"
	@${FIND} ${TESTDIR}/dst
	@${RM} -rf ${TESTDIR}

test2:
	${RM} -rf ${TESTDIR}
	${MKDIR} ${TESTDIR}/src
	${TOUCH} ${TESTDIR}/src/1.bak
	${TOUCH} ${TESTDIR}/src/2.bak
	-(cd ${TESTDIR}/src && ${COPYTREE_SHARE} . ${TESTDIR}/dst "! -name *.bak")
	@${RM} -rf ${TESTDIR}

.include <bsd.port.mk>
[golub@zhuzha ~/freebsd/ports/test]$ make
/bin/rm -rf /tmp/test_COPYTREE_SHARE
/bin/mkdir -p /tmp/test_COPYTREE_SHARE/src/1
/usr/bin/touch /tmp/test_COPYTREE_SHARE/src/1.bak
/usr/bin/touch /tmp/test_COPYTREE_SHARE/src/1/1.bak
/usr/bin/touch /tmp/test_COPYTREE_SHARE/src/1/2.bak
(cd /tmp/test_COPYTREE_SHARE/src && /bin/sh -c '(/usr/bin/find -d $0 $2 | /usr/bin/cpio -dumpl $1 >/dev/null  2>&1) &&  /usr/bin/find -d $0 $2 -type d -exec chmod 755 $1/{} \; &&  /usr/bin/find -d $0 $2 -type f -exec chmod 444 $1/{} \;' -- . /tmp/test_COPYTREE_SHARE/dst "! -name *.bak")
=> Listing destination (no *.bak files are expected):
/tmp/test_COPYTREE_SHARE/dst
/tmp/test_COPYTREE_SHARE/dst/1
/tmp/test_COPYTREE_SHARE/dst/1/2.bak
/bin/rm -rf /tmp/test_COPYTREE_SHARE
/bin/mkdir -p /tmp/test_COPYTREE_SHARE/src
/usr/bin/touch /tmp/test_COPYTREE_SHARE/src/1.bak
/usr/bin/touch /tmp/test_COPYTREE_SHARE/src/2.bak
(cd /tmp/test_COPYTREE_SHARE/src && /bin/sh -c '(/usr/bin/find -d $0 $2 | /usr/bin/cpio -dumpl $1 >/dev/null  2>&1) &&  /usr/bin/find -d $0 $2 -type d -exec chmod 755 $1/{} \; &&  /usr/bin/find -d $0 $2 -type f -exec chmod 444 $1/{} \;' -- . /tmp/test_COPYTREE_SHARE/dst "! -name *.bak")
find: 2.bak: unknown primary or operator
find: 2.bak: unknown primary or operator
*** Error code 1 (ignored)

In my case I workarounded this by using -regex instead of -name.

One way to fix this is to disable pathname expansion in the find shell:

-COPYTREE_SHARE=        ${SH} -c '(${FIND} -d $$0 $$2 | ${CPIO} -dumpl $$1 >/dev/null \
+COPYTREE_SHARE=        ${SH} -fc '(${FIND} -d $$0 $$2 | ${CPIO} -dumpl $$1 >/dev/null \

But then it will break cases like below, when expansion of the first
argumemt is desirable:

  ${COPYTREE_SHARE} "*" ${TESTDIR}

-- 
Mikolaj Golub



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140705120457.GA1772>