Skip to content

Commit

Permalink
Add repro-build, repro-diff und repro-check commands
Browse files Browse the repository at this point in the history
These commands check for reproducibility of distribution packages.

The repro-build command unpacks the source package from the dist
directory to the temp directory and performs a nested rebuild of the
packages there.

The repro-diff command compares original and rebuild packages. If
different, a report about individual differing files in dist, inst and
spkg directories is printed.

The repro-check command combines both commands.
  • Loading branch information
chrfranke authored and jon-turney committed Mar 10, 2024
1 parent df281c6 commit 8e73ca6
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 1 deletion.
3 changes: 3 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ Other COMMANDs are meant primarily for maintainers:
diff - write a patch file capturing changes to source in the working directory
stage - as upload, but don't request processing of uploaded packages
announce - compose and send a package announcement
repro-build - rebuild from created source package to temp directory
repro-diff - check whether packages from original and rebuild differ
repro-check - run repro-build and repro-diff

The standard arguments --help or --version may also be passed to cygport.

Expand Down
17 changes: 17 additions & 0 deletions bin/cygport.in
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ set -e;
#
################################################################################

# Preserve original environment for repro-check command
declare -r _cygport_orig_env=$(export)
declare -r _cygport_orig_pwd=$(pwd)

# for regexes, sort, etc.
export LC_COLLATE=C

Expand Down Expand Up @@ -784,6 +788,19 @@ do
test ${PIPESTATUS[0]} -eq 0
_status=$?;
;;
repro-build)
__pkg_repro_build
_status=$?
;;
repro-diff)
__pkg_repro_diff
_status=$?
;;
repro-check)
__pkg_repro_build && \
__pkg_repro_diff
_status=$?
;;
help)
__show_help;
exit 0;
Expand Down
3 changes: 3 additions & 0 deletions lib/help.cygpart
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ __show_help() {
finish delete the working directory
all run prep, compile, install and package
all-test run prep, compile, install and package-test
repro-build rebuild from created source package to temp directory
repro-diff check whether packages from original and rebuild differ
repro-check run repro-build and repro-diff

See the included README file for further documentation.

Expand Down
58 changes: 57 additions & 1 deletion lib/pkg_pkg.cygpart
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,62 @@ _EOF
fi
}

__pkg_repro_build() {
local srcpkg=${distdir}/${PN}/${PF}-src.tar.${TAR_COMPRESSION_EXT}
local t_spkgdir=${T}/${spkgdir##*/}
local t_workdir=${t_spkgdir}/${PF}.${ARCH}
local t_cygport="cygport ${cygportfile} finish all"
local rc

__stage "Rebuilding"
__step "Unpacking ${srcpkg}"
[ -f ${srcpkg} ] || error "Packages not built yet"
tar xf ${srcpkg} -C ${T} || error "tar xf ${srcpkg} -C ${T} failed"

__step "Rebuilding in ${t_spkgdir}"
echo "${_cygport_orig_env}" > ${T}/.cygport_orig_env
echo
__step "=== Start: ${t_cygport} ================================="

# Start nested cygport with original environment in temp directory
rc=0
env --chdir=${_cygport_orig_pwd} --ignore-environment /bin/bash -c \
"source ${T}/.cygport_orig_env && cd ${t_spkgdir} && ${t_cygport}" \
|| rc=$?

__step "=== Done: ${t_cygport} (exit $rc) ========================="
echo
[ $rc = 0 ] || error "Rebuild failed"
}

__pkg_repro_diff() {
local t_spkgdir=${T}/${spkgdir##*/}
local t_workdir=${t_spkgdir}/${PF}.${ARCH}
local t_srcpkg=${t_workdir}/dist/${PN}/${PF}-src.tar.${TAR_COMPRESSION_EXT}
local d

__stage "Comparing original and rebuild of"
inform "Rebuild dir: ${t_spkgdir}"
[ -f ${t_srcpkg} ] || error "Packages not rebuilt yet"

if ! diff -qr --no-dereference ${distdir} ${t_workdir}/dist >/dev/null
then
echo "Differing files found:"
for d in dist inst spkg
do
LC_MESSAGES=C \
diff -qr --no-dereference ${workdir}/${d} ${t_workdir}/${d} \
| sed -n -e "s|^Files ${workdir}/\([^ ][^ ]*\) and .* differ\$|! \\1|p" \
-e "s|^Only in ${workdir}/\(${d}/[^:]*\): |- \\1/|p" \
-e "s|^Only in ${t_workdir}/\(${d}/[^:]*\): |+ \\1/|p"
done
echo
error "Rebuild differs from original"
fi
echo
inform "Rebuild produced identical packages"
}

# protect functions
readonly -f __pkg_binpkg __pkg_diff __gpg_sign __pkg_srcpkg __pkg_dist \
__squeeze_whitespace __tar
__pkg_repro_build __pkg_repro_diff __squeeze_whitespace __tar

0 comments on commit 8e73ca6

Please sign in to comment.