[devtools] makerepropkg: allow specifying the package in pacman -S format

Message ID 20200608191341.2064852-1-eschwartz@archlinux.org
State New
Headers show
Series
  • [devtools] makerepropkg: allow specifying the package in pacman -S format
Related show

Commit Message

Eli Schwartz via arch-projects June 8, 2020, 7:13 p.m. UTC
We now accept:

1) # nothing

    in which case we'll use the PKGBUILD to retrieve...

2) name, or repo/name

    in which case we'll use pacman to cache the package and retrieve...

3) a filename

Signed-off-by: Eli Schwartz <eschwartz@archlinux.org>
---
 doc/makerepropkg.1.asciidoc | 11 +++++++-
 makerepropkg.in             | 54 +++++++++++++++++++++++++++----------
 2 files changed, 50 insertions(+), 15 deletions(-)

Patch

diff --git a/doc/makerepropkg.1.asciidoc b/doc/makerepropkg.1.asciidoc
index 0d7ddcb..e9f4c24 100644
--- a/doc/makerepropkg.1.asciidoc
+++ b/doc/makerepropkg.1.asciidoc
@@ -7,7 +7,7 @@  makerepropkg - Rebuild a package to see if it is reproducible
 
 Synopsis
 --------
-makerepropkg [OPTIONS] <package_file>...
+makerepropkg [OPTIONS] [<package_file|pkgname>...]
 
 Description
 -----------
@@ -24,6 +24,15 @@  When given multiple packages, additional package files are assumed to be split
 packages and will be treated as additional artifacts to compare during the
 verification step.
 
+A valid target(s) for pacman -S can be specified instead, and makerepropkg will
+download it to the cache if needed. This is mostly useful to specify which
+repository to retrieve from. If no positional arguments are specified, the
+targets will be sourced from the PKGBUILD.
+
+In either case, the package name will be converted to a filename from the
+cache, and makerepropkg will proceed as though this filename was initially
+specified.
+
 This implements a verifier for pacman/libalpm packages in accordance with the
 link:https://reproducible-builds.org/[Reproducible Builds] project.
 
diff --git a/makerepropkg.in b/makerepropkg.in
index c609ff6..051fe40 100755
--- a/makerepropkg.in
+++ b/makerepropkg.in
@@ -124,20 +124,46 @@  shift $((OPTIND - 1))
 
 check_root
 
-if [[ -n $1 ]]; then
-    pkgfile="$1"
-    splitpkgs=("$@")
-    for f in "${splitpkgs[@]}"; do
-        if ! bsdtar -tqf "${f}" .BUILDINFO >/dev/null 2>&1; then
-            error "file is not a valid pacman package: '%s'" "${f}"
-            exit 1
-        fi
-    done
-else
-    error "no package file specified. Try '${BASH_SOURCE[0]##*/} -h' for more information. "
-    exit 1
+[[ -f PKGBUILD ]] || { error "No PKGBUILD in current directory."; exit 1; }
+
+# without arguments, get list of packages from PKGBUILD
+if [[ -z $1 ]]; then
+    mapfile -t pkgnames < <(source PKGBUILD; pacman -Sddp --print-format '%r/%n' "${pkgname[@]}")
+    wait $! || {
+        error "No package file specified and failed to retrieve package names from './PKGBUILD'."
+        plain "Try '${BASH_SOURCE[0]##*/} -h' for more information." >&2
+        exit 1
+    }
+    msg "Reproducing all pkgnames listed in ./PKGBUILD"
+    set -- "${pkgnames[@]}"
 fi
 
+# check each package to see if it's a file, and if not, try to download it
+# using pacman -Sw, and get the filename from there
+splitpkgs=()
+for p in "$@"; do
+    if [[ -f ${p} ]]; then
+        splitpkgs+=("${p}")
+    else
+        pkgfile_remote=$(pacman -Sddp "${p}" 2>/dev/null) || { error "package name '%s' not in repos" "${p}"; exit 1; }
+        pkgfile=${pkgfile_remote#file://}
+        if [[ ! -f ${pkgfile} ]]; then
+            msg "Downloading package '%s' into pacman's cache" "${pkgfile}"
+            sudo pacman -Swdd --noconfirm --logfile /dev/null "${p}" || exit 1
+            pkgfile_remote=$(pacman -Sddp "${p}" 2>/dev/null)
+            pkgfile="${pkgfile_remote#file://}"
+        fi
+        splitpkgs+=("${pkgfile}")
+    fi
+done
+
+for f in "${splitpkgs[@]}"; do
+    if ! bsdtar -tqf "${f}" .BUILDINFO >/dev/null 2>&1; then
+        error "file is not a valid pacman package: '%s'" "${f}"
+        exit 1
+    fi
+done
+
 if (( ${#cache_dirs[@]} == 0 )); then
 	mapfile -t cache_dirs < <(pacman-conf CacheDir)
 fi
@@ -148,11 +174,11 @@  load_makepkg_config
 HOME=${ORIG_HOME}
 [[ -d ${SRCDEST} ]] || SRCDEST=${PWD}
 
-parse_buildinfo < <(bsdtar -xOqf "${pkgfile}" .BUILDINFO)
+parse_buildinfo < <(bsdtar -xOqf "${splitpkgs[0]}" .BUILDINFO)
 export SOURCE_DATE_EPOCH="${buildinfo[builddate]}"
 PACKAGER="${buildinfo[packager]}"
 BUILDDIR="${buildinfo[builddir]}"
-PKGEXT=${pkgfile#${pkgfile%.pkg.tar*}}
+PKGEXT=${splitpkgs[0]#${splitpkgs[0]%.pkg.tar*}}
 
 # nuke and restore reproducible testenv
 for copy in "${buildroot}"/*/; do