diffpkg: support comparing two given package archives

This adds support similar to diffpkg from the infrastructure repo
that is based on the assumption that two archives can be passed
to the tooling in order to compare them.
This commit is contained in:
Levente Polyak 2022-04-28 01:13:02 +02:00
parent c339536a37
commit c2f163b640
No known key found for this signature in database
GPG Key ID: FC1B547C8D8172C8
3 changed files with 105 additions and 69 deletions

View File

@ -8,12 +8,19 @@ m4_include(lib/common.sh)
usage() { usage() {
cat <<- _EOF_ cat <<- _EOF_
Usage: ${BASH_SOURCE[0]##*/} [OPTIONS] [MODES] Usage: ${BASH_SOURCE[0]##*/} [OPTIONS] [MODES] [FILE|PKGNAME...]
Searches for a locally built package corresponding to the PKGBUILD, and Searches for a locally built package corresponding to the PKGBUILD, and
downloads the last version of that package from the Pacman repositories. downloads the last version of that package from the Pacman repositories.
It then compares them using different modes while using simple tar It then compares the package archives using different modes while using
content list by default. simple tar content list by default.
When given one package, use it to diff against the locally built one.
When given two packages, diff both packages against each other.
In either case, a package name will be converted to a filename from the
cache, and diffpkg will proceed as though this filename was initially
specified.
OPTIONS OPTIONS
-M, --makepkg-config Set an alternate makepkg configuration file -M, --makepkg-config Set an alternate makepkg configuration file
@ -100,19 +107,10 @@ elif [[ -r "$HOME/.makepkg.conf" ]]; then
source "$HOME/.makepkg.conf" source "$HOME/.makepkg.conf"
fi fi
if [[ ! -f PKGBUILD ]]; then
die 'This must be run in the directory of a built package.'
fi
# shellcheck source=PKGBUILD.proto
. ./PKGBUILD
if [[ ${arch[0]} == 'any' ]]; then
CARCH='any'
fi
STARTDIR=$(pwd) STARTDIR=$(pwd)
trap 'rm -rf $TEMPDIR' EXIT INT TERM QUIT trap 'rm -rf $TMPDIR' EXIT INT TERM QUIT
TEMPDIR=$(mktemp -d --tmpdir diffpkg-script.XXXXXXXX) TMPDIR=$(mktemp -d --tmpdir diffpkg-script.XXXXXXXX)
export TMPDIR
tar_list() { tar_list() {
bsdtar tf "$*" | if (( VERBOSE )); then bsdtar tf "$*" | if (( VERBOSE )); then
@ -123,78 +121,108 @@ tar_list() {
} }
diff_pkgs() { diff_pkgs() {
local oldpkg=$1 local oldpkg newpkg
local newpkg=$2 oldpkg=$(readlink -m "$1")
newpkg=$(readlink -m "$2")
[[ -f $oldpkg ]] || die "No such file: %s" "${oldpkg}"
[[ -f $newpkg ]] || die "No such file: %s" "${newpkg}"
if (( TARLIST )); then if (( TARLIST )); then
tar_list "$oldpkg" > "$TEMPDIR/filelist-old" tar_list "$oldpkg" > "$TMPDIR/filelist-old"
tar_list "$newpkg" > "$TEMPDIR/filelist" tar_list "$newpkg" > "$TMPDIR/filelist"
sdiff -s "$TEMPDIR/filelist-old" "$TEMPDIR/filelist" sdiff -s "$TMPDIR/filelist-old" "$TMPDIR/filelist"
fi fi
if (( PKGINFO )); then if (( PKGINFO )); then
bsdtar xOqf "$oldpkg" .PKGINFO > "$TEMPDIR/pkginfo-old" bsdtar xOqf "$oldpkg" .PKGINFO > "$TMPDIR/pkginfo-old"
bsdtar xOqf "$newpkg" .PKGINFO > "$TEMPDIR/pkginfo" bsdtar xOqf "$newpkg" .PKGINFO > "$TMPDIR/pkginfo"
sdiff -s "$TEMPDIR/pkginfo-old" "$TEMPDIR/pkginfo" sdiff -s "$TMPDIR/pkginfo-old" "$TMPDIR/pkginfo"
fi fi
if (( BUILDINFO )); then if (( BUILDINFO )); then
bsdtar xOqf "$oldpkg" .BUILDINFO > "$TEMPDIR/buildinfo-old" bsdtar xOqf "$oldpkg" .BUILDINFO > "$TMPDIR/buildinfo-old"
bsdtar xOqf "$newpkg" .BUILDINFO > "$TEMPDIR/buildinfo" bsdtar xOqf "$newpkg" .BUILDINFO > "$TMPDIR/buildinfo"
sdiff -s "$TEMPDIR/buildinfo-old" "$TEMPDIR/buildinfo" sdiff -s "$TMPDIR/buildinfo-old" "$TMPDIR/buildinfo"
fi fi
if (( DIFFOSCOPE )); then if (( DIFFOSCOPE )); then
diffoscope "$(readlink -e "$oldpkg")" "$(readlink -e "$newpkg")" diffoscope "$oldpkg" "$newpkg"
fi fi
} }
for _pkgname in "${pkgname[@]}"; do fetch_pkg() {
comparepkg=$_pkgname local pkg pkgdest pkgurl
pkgurl= case $1 in
target_pkgver=$(get_full_version "$_pkgname") *://*)
if ! pkgfile=$(find_cached_package "$_pkgname" "$target_pkgver" "$CARCH"); then pkgurl=$1 ;;
die 'tarball not found for package: %s' "${_pkgname}-$target_pkgver" /*|*/*)
fi pkgurl=$(readlink -m "$1") ;;
*.pkg.tar*)
pkgurl=$1 ;;
'')
;;
*)
pkg=$1 ;;
esac
ln -s "$pkgfile" "$TEMPDIR" [[ -n $pkgurl ]] || pkgurl=$(pacman -Spdd --print-format '%l' --noconfirm "$pkg") ||
die "Couldn't download previous package for %s." "$pkg"
if (( $# )); then pkg=${pkgurl##*/}
case $1 in pkgdest=$(mktemp -t -d "${pkg}-XXXXXX")/${pkg}
*://*)
pkgurl=$1 ;;
/*|*/*)
pkgurl=$(readlink -m "$1") ;;
*.pkg.tar*)
pkgurl=$1 ;;
'')
;;
*)
comparepkg=$1 ;;
esac
shift
fi
[[ -n $pkgurl ]] || pkgurl=$(pacman -Spdd --print-format '%l' --noconfirm "$comparepkg") ||
die "Couldn't download previous package for %s." "$comparepkg"
oldpkg=${pkgurl##*/}
if [[ ${oldpkg} = "${pkgfile##*/}" ]]; then
die "The built package (%s) is the one in the repo right now!" "$_pkgname"
fi
if [[ $pkgurl = file://* || ( $pkgurl = /* && -f $pkgurl ) ]]; then if [[ $pkgurl = file://* || ( $pkgurl = /* && -f $pkgurl ) ]]; then
ln -s "${pkgurl#file://}" "$TEMPDIR/$oldpkg" ln -sf "${pkgurl#file://}" "$pkgdest"
elif [[ -f "$PKGDEST/$oldpkg" ]]; then elif [[ -f "$PKGDEST/$pkg" ]]; then
ln -s "$PKGDEST/$oldpkg" "$TEMPDIR/$oldpkg" ln -sf "$PKGDEST/$pkg" "$pkgdest"
elif [[ -f "$STARTDIR/$oldpkg" ]]; then elif [[ -f "$STARTDIR/$pkg" ]]; then
ln -s "$STARTDIR/$oldpkg" "$TEMPDIR/$oldpkg" ln -sf "$STARTDIR/$pkg" "$pkgdest"
elif [[ $pkgurl = *://* ]]; then
curl -fsLC - --retry 3 --retry-delay 3 -o "$pkgdest" "$pkgurl" || \
die "Couldn't download %s" "$pkgurl"
else else
curl -fsLC - --retry 3 --retry-delay 3 -o "$TEMPDIR/$oldpkg" "$pkgurl" die "File not found: %s" "$pkgurl"
fi fi
diff_pkgs "$TEMPDIR/$oldpkg" "$pkgfile" echo "$pkgdest"
done }
if (( $# < 2 )); then
if [[ ! -f PKGBUILD ]]; then
die "This must be run in the directory of a built package.\nTry '$(basename "$0") --help' for more information."
fi
# shellcheck source=PKGBUILD.proto
. ./PKGBUILD
if [[ ${arch[0]} == 'any' ]]; then
CARCH='any'
fi
for _pkgname in "${pkgname[@]}"; do
comparepkg=$_pkgname
pkgurl=
target_pkgver=$(get_full_version "$_pkgname")
if ! pkgfile=$(find_cached_package "$_pkgname" "$target_pkgver" "$CARCH"); then
die 'tarball not found for package: %s' "${_pkgname}-$target_pkgver"
fi
ln -s "$pkgfile" "$TMPDIR"
if (( $# )); then
comparepkg="$1"
fi
oldpkg=$(fetch_pkg "$comparepkg") || exit 1
diff_pkgs "$oldpkg" "$pkgfile"
done
else
file1=$(fetch_pkg "$1") || exit 1
file2=$(fetch_pkg "$2") || exit 1
diff_pkgs "$file1" "$file2"
fi

View File

@ -7,15 +7,22 @@ diffpkg - Compare package files using different modes.
Synopsis Synopsis
-------- --------
diffpkg [OPTIONS] [MODES] diffpkg [OPTIONS] [MODES] [FILE|PKGNAME...]
Description Description
----------- -----------
Searches for a locally built package corresponding to the PKGBUILD, and Searches for a locally built package corresponding to the PKGBUILD, and
downloads the last version of that package from the Pacman repositories. downloads the last version of that package from the Pacman repositories.
It then compares them using different modes while using simple tar It then compares the package archives using different modes while using
content list by default. simple tar content list by default.
When given one package, use it to diff against the locally built one.
When given two packages, diff both packages against each other.
In either case, a package name will be converted to a filename from the
cache, and diffpkg will proceed as though this filename was initially
specified.
Options Options
------- -------

View File

@ -49,6 +49,7 @@ _diffpkg_args=(
'(-m --makepkg-config)'{-m,--makepkg-config}'[Location of a makepkg config file]:makepkg_config:_files -g "*.conf(.)"' '(-m --makepkg-config)'{-m,--makepkg-config}'[Location of a makepkg config file]:makepkg_config:_files -g "*.conf(.)"'
'(-v --verbose)'{-v,--verbose}'[Provide more detailed/unfiltered output]' '(-v --verbose)'{-v,--verbose}'[Provide more detailed/unfiltered output]'
'(-h --help)'{-h,--help}'[Display usage]' '(-h --help)'{-h,--help}'[Display usage]'
'*:packages:_devtools_completions_all_packages'
) )
_finddeps_args=( _finddeps_args=(