Really require everything in buildroot to be packaged

Previously we only checked for unpackaged files and symlinks, completely
ignoring eg extra directories that might be there. Just check for everything
instead. Related to #994.

Directories are a little tricky as some of them are almost always unowned
so we need to allow all path components leading to packaged files. This
would be a *lot* of relatively expensive lookups, but we only need to do
the dance when the directory index changes, and we can stop when no new
paths get added to the pool.
This commit is contained in:
Panu Matilainen 2020-11-19 16:29:17 +02:00
parent c223d84fbf
commit 1110c28063
3 changed files with 35 additions and 7 deletions

View File

@ -2794,22 +2794,51 @@ static int checkFiles(const char *buildRoot, Package packages)
StringBuf sb_stdout = NULL;
int rc = -1;
char * s = rpmExpand(av_ckfile[0], NULL);
size_t brlen = strlen(buildRoot);
rpmstrPool dirs = rpmstrPoolCreate();
int prevcount = 0;
if (!(s && *s))
goto exit;
rpmlog(RPMLOG_NOTICE, _("Checking for unpackaged file(s): %s\n"), s);
/* This needs to match with the find call in check-files script */
for (Package pkg = packages; pkg != NULL; pkg = pkg->next) {
int fc = rpmfilesFC(pkg->cpioList);
int prevdix = -1;
for (int i = 0; i < fc; i++) {
mode_t mode = rpmfilesFMode(pkg->cpioList, i);
/* This needs to match with the find call at check-files script */
if (S_ISREG(mode) || S_ISLNK(mode))
appendLineStringBuf(fileList, pkg->dpaths[i]);
const char *dp = pkg->dpaths[i];
size_t dlen = strlen(dp);
int dix = rpmfilesDI(pkg->cpioList, i);
/* Add the disk path itself to the manifest */
appendLineStringBuf(fileList, dp);
/* If dirname is the same as last one, move on */
if (dix == prevdix)
continue;
/* Remember all intermediate directories in added files */
for (const char *s = dp + dlen; s >= dp + brlen; s--) {
if (*s == '/') {
rpmstrPoolIdn(dirs, dp, s-dp, 1);
/* If we've already seen this dir, we can stop here */
int n = rpmstrPoolNumStr(dirs);
if (n == prevcount)
break;
prevcount = n;
}
}
prevdix = dix;
}
}
/* Add all intermediate directories to the manifest */
for (rpmsid id = 1; id <= rpmstrPoolNumStr(dirs); id++)
appendLineStringBuf(fileList, rpmstrPoolStr(dirs, id));
rc = rpmfcExec(av_ckfile, fileList, &sb_stdout, 0, buildRoot);
if (rc < 0)
goto exit;
@ -2828,6 +2857,7 @@ static int checkFiles(const char *buildRoot, Package packages)
exit:
freeStringBuf(sb_stdout);
freeStringBuf(fileList);
rpmstrPoolFree(dirs);
free(s);
return rc;
}

View File

@ -27,6 +27,6 @@ trap "rm -f \"${FILES_DISK}\"" 0 2 3 5 10 13 15
# Find non-directory files in the build root and compare to the manifest.
# TODO: regex chars in last sed(1) expression should be escaped
find "${RPM_BUILD_ROOT}" -type f -o -type l | LC_ALL=C sort > "${FILES_DISK}"
find "${RPM_BUILD_ROOT}" | LC_ALL=C sort > "${FILES_DISK}"
LC_ALL=C sort | diff -d "${FILES_DISK}" - | sed -n 's!^\(-\|< \)'"${RPM_BUILD_ROOT}"'\(.*\)$! \2!gp'

View File

@ -307,10 +307,8 @@ runroot rpmbuild \
])
AT_CLEANUP
# rpm doesn't detect unpackaged directories but should, really
AT_SETUP([rpmbuild unpackaged directories])
AT_KEYWORDS([build])
AT_XFAIL_IF([test $RPM_XFAIL -ne 0])
RPMDB_INIT
AT_CHECK([
RPMDB_INIT