pullup 3232
[pkgsrc.git] / mk / check / check-files.mk
1 # $NetBSD: check-files.mk,v 1.24 2009/05/08 20:46:29 minskim Exp $
2 #
3 # This file checks that the list of installed files matches the PLIST.
4 # For that purpose it records the file list of LOCALBASE before and
5 # after the installation of the package and compares these lists with
6 # the PLIST.
7 #
8 # User-settable variables:
9 #
10 # CHECK_FILES
11 #       "yes" to enable the check, "no" to disable it.
12 #
13 #       Default value: "yes" for PKG_DEVELOPERs, "no" otherwise.
14 #
15 # CHECK_FILES_STRICT
16 #       When set to "yes", VARBASE and PKG_SYSCONFDIR are checked in
17 #       addition to LOCALBASE.
18 #
19 # Package-settable variables:
20 #
21 # CHECK_FILES_SKIP
22 #       A list of regular expressions (FIXME: all other checks use shell
23 #       patterns) that names files to be skipped. This is useful to
24 #       avoid getting errors triggered by changes in directories not
25 #       really handled by pkgsrc.
26 #
27
28 _VARGROUPS+=            check-files
29 _USER_VARS.check-files= CHECK_FILES CHECK_FILES_STRICT
30 _PKG_VARS.check-files=  CHECK_FILES_SKIP
31
32 .if defined(PKG_DEVELOPER)
33 CHECK_FILES?=           yes
34 .endif
35 CHECK_FILES?=           no
36 CHECK_FILES_STRICT?=    no
37
38 # Info index files updated when a new info file is added.
39 .if defined(INFO_FILES)
40 CHECK_FILES_SKIP+=      ${PREFIX}/.*/dir
41 .endif
42
43 # Perl's perllocal.pod index that is regenerated when a local module
44 # is added.
45 #
46 CHECK_FILES_SKIP+=      ${PERL5_INSTALLARCHLIB}/perllocal.pod
47
48 # R's index files that are regenerated when a local module
49 # is added.
50 #
51 CHECK_FILES_SKIP+=      ${PREFIX}/lib/R/doc/html/packages.html
52 CHECK_FILES_SKIP+=      ${PREFIX}/lib/R/doc/html/search/index.txt
53
54 CHECK_FILES_SKIP+=      ${PKG_DBDIR}/.*
55
56 # We don't care about what's under linux/proc and linux32/proc in Linux 
57 # emulation, which just holds run-time generated data.
58 #
59 CHECK_FILES_SKIP+=      ${PREFIX}/emul/linux/proc.*
60 CHECK_FILES_SKIP+=      ${PREFIX}/emul/linux32/proc.*
61
62 # The reference-count meta-data directory used by the pkginstall framework.
63 CHECK_FILES_SKIP+=      ${PKG_DBDIR}.refcount.*
64
65 # Some people have their distfiles and binary packages below ${LOCALBASE}.
66 CHECK_FILES_SKIP+=      ${PACKAGES}/.*
67 CHECK_FILES_SKIP+=      ${DISTDIR}/.*
68
69 # For unprivileged builds, VARBASE is below LOCALBASE.
70 .if !empty(CHECK_FILES_STRICT:M[Nn][Oo])
71 CHECK_FILES_SKIP+=      ${VARBASE}/.*
72 .endif
73
74 # File that are outside of ${PREFIX} in directories we already know we'll
75 # be using for mutable data.
76 #
77 .for d in ${MAKE_DIRS} ${OWN_DIRS}
78 CHECK_FILES_SKIP+=      ${d:C/^([^\/])/${PREFIX}\/\1/}.*
79 .endfor
80 .for d o g m in ${MAKE_DIRS_PERMS} ${OWN_DIRS_PERMS}
81 CHECK_FILES_SKIP+=      ${d:C/^([^\/])/${PREFIX}\/\1/}.*
82 .endfor
83
84 # Mutable X11 font database files
85 .if (defined(FONTS_DIRS.x11) && !empty(FONTS_DIRS.x11:M*))
86 CHECK_FILES_SKIP+=      ${PREFIX}/.*/encodings.dir
87 CHECK_FILES_SKIP+=      ${PREFIX}/.*/fonts.dir
88 .endif
89 .if (defined(FONTS_DIRS.ttf) && !empty(FONTS_DIRS.ttf:M*)) || \
90     (defined(FONTS_DIRS.type1) && !empty(FONTS_DIRS.type1:M*))
91 CHECK_FILES_SKIP+=      ${PREFIX}/.*/fonts.scale
92 .endif
93 .if (defined(FONTS_DIRS.ttf) && !empty(FONTS_DIRS.ttf:M*)) || \
94     (defined(FONTS_DIRS.type1) && !empty(FONTS_DIRS.type1:M*)) || \
95     (defined(FONTS_DIRS.x11) && !empty(FONTS_DIRS.x11:M*))
96 CHECK_FILES_SKIP+=      ${PREFIX}/.*/fonts.cache-1
97 .endif
98
99 # Mutable charset.alias file
100 CHECK_FILES_SKIP+=      ${PREFIX}/lib/charset.alias
101
102 _CHECK_FILES_SKIP_FILTER=       ${GREP} -vx ${CHECK_FILES_SKIP:@f@-e ${DESTDIR:Q}${f:Q}@}
103
104 ###########################################################################
105 # These are the files generated and used by the check-files implementation
106 # used across several check-files targets.
107 #
108 #    _CHECK_FILES_ERRMSG.* are the files that contain the error
109 #       messages discovered during each stage of file-checking.
110 #
111 #    _CHECK_FILES_PRE.* are the file lists generated before any files
112 #       from the package are installed.
113 #
114 #    _CHECK_FILES_POST.* are the file lists generated after all files
115 #       from the package are installed.
116 #
117 # The "pre" and "post" file lists are compared against each other to
118 # determine if the package is installing files where it shouldn't be.
119 #
120 _CHECK_FILES_ERRMSG.prefix=     ${ERROR_DIR}/check-files-prefix
121 _CHECK_FILES_PRE.prefix=        ${WRKDIR}/.prefix.pre
122 _CHECK_FILES_POST.prefix=       ${WRKDIR}/.prefix.post
123
124 _CHECK_FILES_ERRMSG.sysconfdir= ${ERROR_DIR}/.check-files-sysconfdir
125 _CHECK_FILES_PRE.sysconfdir=    ${WRKDIR}/.sysconfdir.pre
126 _CHECK_FILES_POST.sysconfdir=   ${WRKDIR}/.sysconfdir.post
127
128 _CHECK_FILES_ERRMSG.varbase=    ${ERROR_DIR}/.check-files-varbase
129 _CHECK_FILES_PRE.varbase=       ${WRKDIR}/.varbase.pre
130 _CHECK_FILES_POST.varbase=      ${WRKDIR}/.varbase.post
131
132 _CHECK_FILES_ERRMSGS=           # empty
133 _CHECK_FILES_ERRMSGS+=          ${_CHECK_FILES_ERRMSG.prefix}
134 .if empty(CHECK_FILES_STRICT:M[nN][oO])
135 _CHECK_FILES_ERRMSGS+=          ${_CHECK_FILES_ERRMSG.sysconfdir}
136 _CHECK_FILES_ERRMSGS+=          ${_CHECK_FILES_ERRMSG.varbase}
137 .endif
138
139 ###########################################################################
140 # _CHECK_FILES_PRE holds the list of targets that are built as part of
141 # building the check-files-pre target.  These targets should cause the
142 # "pre" file lists to be generated.
143 #
144 _CHECK_FILES_PRE=               check-files-pre-message
145 _CHECK_FILES_PRE+=              ${_CHECK_FILES_PRE.prefix}
146 .if empty(CHECK_FILES_STRICT:M[nN][oO])
147 _CHECK_FILES_PRE+=              ${_CHECK_FILES_PRE.sysconfdir}
148 _CHECK_FILES_PRE+=              ${_CHECK_FILES_PRE.varbase}
149 .endif
150
151 ###########################################################################
152 # _CHECK_FILES_POST holds the list of targets that are built as part of
153 # building the check-files-post target.  These targets should cause the
154 # "post" file lists to be generated.
155 #
156 _CHECK_FILES_POST=              check-files-post-message
157 _CHECK_FILES_POST+=             ${_CHECK_FILES_POST.prefix}
158 .if empty(CHECK_FILES_STRICT:M[nN][oO])
159 _CHECK_FILES_POST+=             ${_CHECK_FILES_POST.sysconfdir}
160 _CHECK_FILES_POST+=             ${_CHECK_FILES_POST.varbase}
161 .endif
162
163 .if empty(CHECK_FILES:M[nN][oO])
164 privileged-install-hook: check-files
165 .endif
166
167 ###########################################################################
168 # check-files-pre and check-files-post targets and subtargets
169 #
170 .PHONY: check-files-pre check-files-post
171 check-files-pre: ${_CHECK_FILES_PRE}
172 check-files-post: ${_CHECK_FILES_POST}
173
174 .PHONY: check-files-pre-message check-files-post-message
175 check-files-pre-message:
176         @${STEP_MSG} "Generating pre-install file lists"
177
178 check-files-post-message:
179         @${STEP_MSG} "Generating post-install file lists"
180
181 ${_CHECK_FILES_PRE.prefix} ${_CHECK_FILES_POST.prefix}:
182         ${RUN}                                  \
183         ${FIND} ${DESTDIR}${PREFIX}/. \( -type f -o -type l \) -print 2>/dev/null \
184                 | ${SED} -e 's,/\./,/,'                                 \
185                 | ${_CHECK_FILES_SKIP_FILTER}                           \
186                 | ${SORT} > ${.TARGET}                                  \
187                 || ${TRUE}
188
189 ${_CHECK_FILES_PRE.sysconfdir} ${_CHECK_FILES_POST.sysconfdir}:
190         ${RUN}                                  \
191         ${FIND} ${DESTDIR}${PKG_SYSCONFDIR}/. -print 2>/dev/null        \
192                 | ${SED} -e 's,/\./,/,'                                 \
193                 | ${_CHECK_FILES_SKIP_FILTER}                           \
194                 | ${SORT} > ${.TARGET}                                  \
195                 || ${TRUE}
196
197 ${_CHECK_FILES_PRE.varbase} ${_CHECK_FILES_POST.varbase}:
198         ${RUN}                                  \
199         ${FIND} ${DESTDIR}${VARBASE}/. -print 2>/dev/null               \
200                 | ${SED} -e 's,/\./,/,'                                 \
201                 | ${_CHECK_FILES_SKIP_FILTER}                           \
202                 | ${SORT} > ${.TARGET}                                  \
203                 || ${TRUE}
204
205 ###########################################################################
206 # check-files targets and subtargets
207 #
208 .PHONY: check-files-prefix check-files-sysconfdir check-files-varbase
209 check-files-prefix: ${_CHECK_FILES_ERRMSG.prefix}
210 check-files-sysconfdir: ${_CHECK_FILES_ERRMSG.sysconfdir}
211 check-files-varbase: ${_CHECK_FILES_ERRMSG.varbase}
212
213 # The check-files target looks at the cookie files generated by the
214 # check-files-* subtargets, and if they are non-empty, then they
215 # contain the error messages collected during the build of each
216 # subtarget.
217 #
218 .PHONY: check-files
219 .if !empty(CHECK_FILES_SUPPORTED:M[nN][oO])
220 check-files:
221         @${DO_NADA}
222 .else
223 check-files: check-files-message ${_CHECK_FILES_ERRMSGS} error-check
224 .endif
225
226 .PHONY: check-files-message
227 check-files-message:
228         @${STEP_MSG} "Checking file-check results for ${PKGNAME}"
229
230 # Check ${PREFIX} for files which are not listed in the generated ${PLIST}
231 # and vice-versa.
232 #
233 _CHECK_FILES_DIFF=              ${WRKDIR}/.check_files_diff
234 _CHECK_FILES_ADDED=             ${WRKDIR}/.check_files_added
235 _CHECK_FILES_DELETED=           ${WRKDIR}/.check_files_deleted
236 _CHECK_FILES_EXPECTED=          ${WRKDIR}/.check_files_expected
237 _CHECK_FILES_MISSING=           ${WRKDIR}/.check_files_missing
238 _CHECK_FILES_MISSING_SKIP=      ${WRKDIR}/.check_files_missing_skip
239 _CHECK_FILES_MISSING_REAL=      ${WRKDIR}/.check_files_missing_real
240 _CHECK_FILES_EXTRA=             ${WRKDIR}/.check_files_extra
241
242 ${_CHECK_FILES_DIFF}: ${_CHECK_FILES_PRE.prefix} ${_CHECK_FILES_POST.prefix}
243         ${RUN}                                  \
244         ${DIFF} -u ${_CHECK_FILES_PRE.prefix}                           \
245                   ${_CHECK_FILES_POST.prefix}                           \
246                 > ${.TARGET} || ${TRUE}
247
248 ${_CHECK_FILES_ADDED}: ${_CHECK_FILES_DIFF}
249         ${RUN}                                  \
250         ${GREP} '^+/' ${_CHECK_FILES_DIFF} | ${SED} "s|^+||" | ${SORT}  \
251                 > ${.TARGET}
252
253 ${_CHECK_FILES_DELETED}: ${_CHECK_FILES_DIFF}
254         ${RUN}                                  \
255         ${GREP} '^-/' ${_CHECK_FILES_DIFF} | ${SED} "s|^-||" | ${SORT}  \
256                 > ${.TARGET}
257
258 ${_CHECK_FILES_EXPECTED}: plist
259         ${RUN}                                  \
260         ${GREP} '^[^@]' ${PLIST} | ${SED} "s|^|${DESTDIR}${PREFIX}/|" | ${SORT} \
261                 > ${.TARGET}
262
263 ${_CHECK_FILES_MISSING}: ${_CHECK_FILES_EXPECTED} ${_CHECK_FILES_ADDED}
264         ${RUN}                                  \
265         ${DIFF} -u ${_CHECK_FILES_EXPECTED} ${_CHECK_FILES_ADDED} |     \
266         ${GREP} '^-[^-]' | ${SED} "s|^-||" |                            \
267         while read file; do                                             \
268                 ${TEST} -f "$$file" -o -h "$$file" || ${ECHO} "$$file"; \
269         done > ${.TARGET}
270
271 ${_CHECK_FILES_MISSING_REAL}: ${_CHECK_FILES_MISSING}
272         ${RUN}                                  \
273         ${CAT} ${_CHECK_FILES_MISSING} | ${_CHECK_FILES_SKIP_FILTER}    \
274                 > ${.TARGET} || ${TRUE}
275
276 ${_CHECK_FILES_MISSING_SKIP}:                                           \
277                 ${_CHECK_FILES_MISSING}                                 \
278                 ${_CHECK_FILES_MISSING_REAL}
279         ${RUN}                                  \
280         ${DIFF} -u ${_CHECK_FILES_MISSING}                              \
281                    ${_CHECK_FILES_MISSING_REAL} |                       \
282         ${GREP} '^-[^-]' | ${SED} "s|^-||"                              \
283                 > ${.TARGET}
284
285 ${_CHECK_FILES_EXTRA}: ${_CHECK_FILES_EXPECTED} ${_CHECK_FILES_ADDED}
286         ${RUN}                                  \
287         ${DIFF} -u  ${_CHECK_FILES_EXPECTED} ${_CHECK_FILES_ADDED} |    \
288         ${GREP} '^+[^+]' | ${SED} "s|^+||" |                            \
289         while read file; do                                             \
290                 ${TEST} ! -f "$$file" -a ! -h "$$file" || ${ECHO} "$$file"; \
291         done > ${.TARGET}
292
293 ${_CHECK_FILES_ERRMSG.prefix}:                                          \
294                 ${_CHECK_FILES_DELETED}                                 \
295                 ${_CHECK_FILES_MISSING}                                 \
296                 ${_CHECK_FILES_MISSING_REAL}                            \
297                 ${_CHECK_FILES_MISSING_SKIP}                            \
298                 ${_CHECK_FILES_EXTRA}
299         ${RUN}${RM} -f ${.TARGET}
300         ${RUN}                                  \
301         if ${_NONZERO_FILESIZE_P} ${_CHECK_FILES_DELETED}; then         \
302                 ${ECHO} "The following files have been deleted"         \
303                         "from ${PREFIX}!";                              \
304                 ${SED} "s|^|        |" ${_CHECK_FILES_DELETED};         \
305         fi >> ${.TARGET}
306         ${RUN}                                  \
307         if ${_NONZERO_FILESIZE_P} ${_CHECK_FILES_MISSING_REAL}; then    \
308                 ${ECHO} "************************************************************"; \
309                 ${ECHO} "The following files are in the"                \
310                         "PLIST but not in ${PREFIX}:";                  \
311                 ${SED} "s|^|        |" ${_CHECK_FILES_MISSING_REAL};    \
312         fi >> ${.TARGET}
313         ${RUN}                                  \
314         if ${_NONZERO_FILESIZE_P} ${_CHECK_FILES_EXTRA}; then           \
315                 ${ECHO} "************************************************************"; \
316                 ${ECHO} "The following files are in"                    \
317                         "${PREFIX} but not in the PLIST:";              \
318                 ${SED} "s|^|        |" ${_CHECK_FILES_EXTRA};           \
319         fi >> ${.TARGET}
320         ${RUN}                                  \
321         if ${_NONZERO_FILESIZE_P} ${_CHECK_FILES_MISSING_SKIP}; then    \
322                 ${ECHO} "************************************************************"; \
323                 ${ECHO} "The following files are in both the"           \
324                         "PLIST and CHECK_FILES_SKIP:";                  \
325                 ${SED} "s|^|        |" ${_CHECK_FILES_MISSING_SKIP};    \
326         fi >> ${.TARGET}
327
328 # Check ${SYSCONFDIR} for files which are not in the PLIST and are also
329 # not copied into place by the INSTALL scripts.
330 #
331 ${_CHECK_FILES_ERRMSG.sysconfdir}:                                      \
332                 ${_CHECK_FILES_PRE.sysconfdir}                          \
333                 ${_CHECK_FILES_POST.sysconfdir}
334         ${RUN}                                  \
335         if ${CMP} -s ${_CHECK_FILES_PRE.sysconfdir}                     \
336                      ${_CHECK_FILES_POST.sysconfdir}; then              \
337                 ${DO_NADA};                                             \
338         else                                                            \
339                 ${ECHO} "************************************************************"; \
340                 ${ECHO} "The package has modified ${PKG_SYSCONFDIR}"    \
341                         "contents directly!";                           \
342                 ${ECHO} "    The offending files/directories are:";     \
343                 ${DIFF} -u ${_CHECK_FILES_PRE.sysconfdir}               \
344                            ${_CHECK_FILES_POST.sysconfdir} |            \
345                 ${GREP} '^+[^+]' | ${SED} "s|^+|        |";             \
346         fi > ${.TARGET}
347
348 # Check ${VARBASE} for files which are not in the PLIST and are also
349 # not created by the INSTALL scripts.
350 #
351 ${_CHECK_FILES_ERRMSG.varbase}:                                         \
352                 ${_CHECK_FILES_PRE.varbase}                             \
353                 ${_CHECK_FILES_POST.varbase}
354         ${RUN}                                  \
355         if ${CMP} -s ${_CHECK_FILES_PRE.varbase}                        \
356                        ${_CHECK_FILES_POST.varbase}; then               \
357                 ${DO_NADA};                                             \
358         else                                                            \
359                 ${ECHO} "************************************************************"; \
360                 ${ECHO} "The package has modified ${VARBASE}"           \
361                         "contents directly!";                           \
362                 ${ECHO} "    The offending files/directories are:";     \
363                 ${DIFF} -u ${_CHECK_FILES_PRE.varbase}                  \
364                            ${_CHECK_FILES_POST.varbase} |               \
365                 ${GREP} '^+[^+]' | ${SED} "s|^+|        |";             \
366         fi > ${.TARGET}
367
368 ###########################################################################
369 # check-files-clean removes the state files related to the "check-files"
370 # target so that the check-files-{pre,post} targets may be re-run.
371 #
372 .PHONY: check-files-clean
373 check-clean: check-files-clean
374 check-files-clean:
375         ${RUN}                                  \
376         ${RM} -f ${_CHECK_FILES_ERRMSGS}                                \
377                 ${_CHECK_FILES_PRE} ${_CHECK_FILES_POST}                \
378                 ${_CHECK_FILES_DIFF} ${_CHECK_FILES_ADDED}              \
379                 ${_CHECK_FILES_DELETED} ${_CHECK_FILES_EXPECTED}        \
380                 ${_CHECK_FILES_MISSING} ${_CHECK_FILES_MISSING_SKIP}    \
381                 ${_CHECK_FILES_MISSING_REAL} ${_CHECK_FILES_EXTRA}