Subject: Automatic PLIST verification
To: None <tech-pkg@NetBSD.org>
From: Julio M. Merino Vidal <jmmv@menta.net>
List: tech-pkg
Date: 01/13/2005 17:16:28
--=-yriUXPk67JJ+42u1Z9b7
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hi all,

in a recent discussion in tech-pkg@ (don't remember very well which one
it is), it was suggested that comparing the generated PLIST to the files
that were really installed by the package could be a good idea.

Here is a patch that does this.  For completeness, it also checks that
no files are deleted (something that must never happen, AFAICT).

I've made it print the list of "unknown" files instead of redirecting
them to a file so that this becomes useful in bulk builds.

This is enabled iff PKG_DEVELOPER is set and CHECK_FILES is YES.

What do you think?

Thanks,

-- 
Julio M. Merino Vidal <jmmv@menta.net>
http://www.livejournal.com/users/jmmv/
The NetBSD Project - http://www.NetBSD.org/

--=-yriUXPk67JJ+42u1Z9b7
Content-Disposition: attachment; filename=patch.diff
Content-Type: text/x-patch; name=patch.diff; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

Index: bsd.pkg.mk
===================================================================
RCS file: /cvsroot/pkgsrc/mk/bsd.pkg.mk,v
retrieving revision 1.1557
diff -u -r1.1557 bsd.pkg.mk
--- bsd.pkg.mk	12 Jan 2005 15:32:01 -0000	1.1557
+++ bsd.pkg.mk	13 Jan 2005 16:09:25 -0000
@@ -105,6 +105,7 @@
 CLEANDEPENDS?=		NO
 DEINSTALLDEPENDS?=	NO	# add -R to pkg_delete
 REINSTALL?=		NO	# reinstall upon update
+CHECK_FILES?=		YES	# run check-files after install
 CHECK_SHLIBS?=		YES	# run check-shlibs after install
 SHLIB_HANDLING?=	YES	# do automatic shared lib handling
 NOCLEAN?=		NO	# don't clean up after update
@@ -2574,6 +2575,10 @@
 		${ECHO_MSG} "If this is not desired, set it to an appropriate value (${DEF_UMASK})"; \
 		${ECHO_MSG} "and install this package again by \`\`${MAKE} deinstall reinstall''."; \
 	fi
+.if defined(PKG_DEVELOPER) && (${CHECK_FILES} == "YES")
+	${_PKG_SILENT}${_PKG_DEBUG}${ECHO_MSG} "${_PKGSRC_IN}> Generating pre-install file list"
+	${_PKG_SILENT}${_PKG_DEBUG}${FIND} ${PREFIX} -type f -or -type l >${WRKDIR}/.files.pre 2>/dev/null || ${TRUE}
+.endif
 .if defined(INSTALLATION_DIRS) && !empty(INSTALLATION_DIRS)
 	${_PKG_SILENT}${_PKG_DEBUG}${ECHO_MSG} "${_PKGSRC_IN}> Creating installation directories"
 	${_PKG_SILENT}${_PKG_DEBUG}					\
@@ -2623,6 +2628,10 @@
 		# listed in the PLIST.						\
 		#
 	${_PKG_SILENT}${_PKG_DEBUG}cd ${.CURDIR} && ${MAKE} ${MAKEFLAGS} ${PLIST}
+.if defined(PKG_DEVELOPER) && (${CHECK_FILES} == "YES")
+	${_PKG_SILENT}${_PKG_DEBUG}${ECHO_MSG} "${_PKGSRC_IN}> Generating post-install file list"
+	${_PKG_SILENT}${_PKG_DEBUG}${FIND} ${PREFIX} -type f -or -type l >${WRKDIR}/.files.post 2>/dev/null || ${TRUE}
+.endif
 	${_PKG_SILENT}${_PKG_DEBUG}cd ${.CURDIR} && ${MAKE} ${MAKEFLAGS} post-install-script
 	${_PKG_SILENT}${_PKG_DEBUG}newmanpages=`${EGREP} -h		\
 		'^([^@/]*/)*man/([^/]*/)?(man[1-9ln]/.*\.[1-9ln]|cat[1-9ln]/.*\.0)(\.gz)?$$' \
@@ -2694,6 +2703,9 @@
 .if defined(PKG_DEVELOPER) && (${CHECK_SHLIBS} == "YES")
 	${_PKG_SILENT}${_PKG_DEBUG}${MAKE} ${MAKEFLAGS} check-shlibs
 .endif
+.if defined(PKG_DEVELOPER) && (${CHECK_FILES} == "YES")
+	${_PKG_SILENT}${_PKG_DEBUG}${MAKE} ${MAKEFLAGS} check-files
+.endif
 
 
 
@@ -3013,6 +3025,46 @@
 .  endif   # USE_LANGUAGES
 .endif
 
+CHECK_FILES_SKIP+=	emul/linux/proc
+
+CHECK_FILES_SKIP_CMD=
+.for name in ${CHECK_FILES_SKIP}
+CHECK_FILES_SKIP_CMD+=	| ${GREP} -v ${name}
+.endfor
+.undef name
+
+# Check if the generated PLIST matches the list of really installed files.
+#
+.PHONY: check-files
+check-files:
+.if !defined(NO_PKG_REGISTER)
+	${_PKG_SILENT}${_PKG_DEBUG}					\
+	errors=0;							\
+	diff -u ${WRKDIR}/.files.pre ${WRKDIR}/.files.post		\
+		${CHECK_FILES_SKIP_CMD} >${WRKDIR}/.files.diff;		\
+	${GREP} '^+/' ${WRKDIR}/.files.diff | ${SED} 's|^+${PREFIX}/||'	\
+		| ${SORT} >${WRKDIR}/.files.added;			\
+	${GREP} '^-/' ${WRKDIR}/.files.diff | ${SED} 's|^-${PREFIX}/||'	\
+		| ${SORT} >${WRKDIR}/.files.deleted;			\
+	if ${TEST} `${WC} -l ${WRKDIR}/.files.deleted | 		\
+		${AWK} '{ print $$1; }'` -gt 0;				\
+	then								\
+		echo "*** The following files have been deleted from"	\
+		     "${PREFIX}!";					\
+		${SED} "s|^|        |" <${WRKDIR}/.files.deleted;	\
+		errors=1;						\
+	fi;								\
+	${GREP} '^[A-Za-z]' ${PLIST} | ${SORT} >${WRKDIR}/.files.expected; \
+	if ! ${CMP} -s ${WRKDIR}/.files.expected ${WRKDIR}/.files.added; then \
+		echo "*** The PLIST does not match installed files!";	\
+		echo "    The following files were not expected in ${PREFIX}:";\
+		diff -u ${WRKDIR}/.files.expected ${WRKDIR}/.files.added | \
+			${GREP} '^+[^+]' | ${SED} "s|^+|        |";	\
+		errors=1;						\
+	fi;								\
+	${TEST} $$errors -eq 0
+.endif
+	
 .PHONY: acquire-extract-lock acquire-patch-lock acquire-tools-lock
 .PHONY: acquire-wrapper-lock acquire-configure-lock acquire-build-lock
 .PHONY: acquire-install-lock acquire-package-lock

--=-yriUXPk67JJ+42u1Z9b7--