From 152a21dfad4c786cff1712e6aa1c33f2db0b6a75 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Fri, 1 Mar 2024 19:46:50 +0100 Subject: [PATCH] Add repro-build, repro-diff und repro-check commands 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. --- README | 3 +++ bin/cygport.in | 17 +++++++++++++ lib/help.cygpart | 3 +++ lib/pkg_pkg.cygpart | 58 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 80 insertions(+), 1 deletion(-) diff --git a/README b/README index fd16df6b..3c9e4d4a 100644 --- a/README +++ b/README @@ -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. diff --git a/bin/cygport.in b/bin/cygport.in index 5fc89eaf..a2c2b5a3 100755 --- a/bin/cygport.in +++ b/bin/cygport.in @@ -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 @@ -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; diff --git a/lib/help.cygpart b/lib/help.cygpart index a7f30f7a..d28fd7bb 100644 --- a/lib/help.cygpart +++ b/lib/help.cygpart @@ -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. diff --git a/lib/pkg_pkg.cygpart b/lib/pkg_pkg.cygpart index 756a687c..3c531c0e 100644 --- a/lib/pkg_pkg.cygpart +++ b/lib/pkg_pkg.cygpart @@ -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 -- 2.43.0