mirror of
https://github.com/goreleaser/nfpm
synced 2026-08-14 11:04:20 +02:00
User content (scriptlets, %description, summary, file paths and changelog)
was inlined verbatim into the generated .spec file. rpmbuild reinterprets %
when the SRPM is rebuilt: %% collapses to a single %, %{macro} expands, and
%(command) executes at build time. The common longest-suffix-strip idiom
${VAR%%.*} silently became ${VAR%.*} (shortest suffix) in install scriptlets,
with no warning.
Double every % in user-controlled spec text via escapeSpecText so rpmbuild
restores it literally on rebuild. Binary RPMs are unaffected -- their
scriptlets go straight into header tags with no spec parsing -- so this is
scoped to the SRPM path.
Add a unit test asserting the escaped output, and extend the srpm rebuild
acceptance test with a ${host%%.*} scriptlet that must survive the real
rpmbuild --rebuild.
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
49 lines
2.1 KiB
Docker
49 lines
2.1 KiB
Docker
FROM fedora AS test_base
|
|
ARG package
|
|
RUN echo "${package}"
|
|
COPY ${package} /tmp/foo.src.rpm
|
|
|
|
|
|
# ---- rebuild test ----
|
|
# Proves the generated source package is a real, rebuildable .src.rpm:
|
|
# rpmbuild --rebuild reproduces the binary RPM, which then installs cleanly.
|
|
FROM test_base AS rebuild
|
|
RUN dnf install -y rpm-build
|
|
|
|
# The source package is arch "src" and is flagged as a source package.
|
|
RUN test "$(rpm -qp --qf '%{ARCH}' /tmp/foo.src.rpm)" = "src"
|
|
RUN test "$(rpm -qp --qf '%{SOURCEPACKAGE}' /tmp/foo.src.rpm)" = "1"
|
|
RUN test "$(rpm -qp --qf '%{SOURCERPM}' /tmp/foo.src.rpm)" = "(none)"
|
|
|
|
# Its file list is the generated spec plus the bundled source tarball (source
|
|
# packages list flat basenames, not absolute paths).
|
|
RUN rpm -qpl /tmp/foo.src.rpm | grep -E 'foo\.spec$'
|
|
RUN rpm -qpl /tmp/foo.src.rpm | grep -E 'foo-1\.2\.3\.tar\.gz$'
|
|
|
|
# Rebuild the binary RPM from source.
|
|
RUN rpmbuild --rebuild /tmp/foo.src.rpm
|
|
RUN cp "$(find /root/rpmbuild/RPMS -name 'foo-*.rpm' | head -1)" /tmp/foo.rpm
|
|
|
|
# The rebuilt binary RPM carries the expected metadata and file set.
|
|
RUN test "$(rpm -qp --qf '%{EPOCH}:%{NAME}-%{VERSION}-%{RELEASE}' /tmp/foo.rpm)" = "1:foo-1.2.3-4"
|
|
RUN rpm -qp -c /tmp/foo.rpm | grep -E '^/etc/foo/whatever\.conf$'
|
|
RUN rpm -qp -d /tmp/foo.rpm | grep -E '^/usr/share/doc/foo/README$'
|
|
RUN rpm -qp --qf '[%{FILENAMES} %{FILEFLAGS}\n]' /tmp/foo.rpm | grep -E '^/var/lib/foo/state 64$'
|
|
RUN test "$(rpm -qp --provides /tmp/foo.rpm | grep '^foo-tool$')" = "foo-tool"
|
|
RUN rpm -qp --requires /tmp/foo.rpm | grep -E '^bash$'
|
|
RUN rpm -qp --scripts /tmp/foo.rpm | grep -E 'postinstall scriptlet'
|
|
# %-sequences in scriptlets must survive the rebuild literally; without the
|
|
# spec escaping, ${host%%.*} would be silently mangled to ${host%.*}.
|
|
RUN rpm -qp --scripts /tmp/foo.rpm | grep -F '${host%%.*}'
|
|
|
|
# Install it and verify the payload landed on disk.
|
|
RUN rpm -ivh /tmp/foo.rpm
|
|
RUN test -f /usr/bin/fake
|
|
RUN test -f /etc/foo/whatever.conf
|
|
RUN test -d /var/log/whatever
|
|
RUN test -L /usr/bin/fake-link
|
|
RUN test "$(readlink /usr/bin/fake-link)" = "/usr/bin/fake"
|
|
RUN test ! -e /var/lib/foo/state
|
|
RUN rpm -e foo
|
|
RUN test ! -f /usr/bin/fake
|