#!/usr/bin/env bash # SPDX-License-Identifier: GPL-2.0-or-later # Copyright (C) 2026 Bryan Joshua Pedini # discovery/pacman/aur.sh - verify the output formats and exit codes of paru and yay that the # AUR support of skeptical-updater relies on (-Qua, -Si/-Sia, -Sua --ignore, devel packages, # [ignored], root refusal, AUR unreachable). NEEDS NETWORK (Arch mirrors, aur.archlinux.org, # github.com for pfetch-git). Run as root in a throwaway container: # docker run --rm -i -v "$PWD/discovery/pacman:/d:ro" archlinux:latest bash /d/aur.sh set -uo pipefail export LC_ALL=C U=bob H=/home/$U step() { printf '\n######## %s\n' "$*"; } # as_user CMD...: run CMD as the unprivileged user, from its home, with its HOME as_user() { (cd "$H" && runuser -u "$U" -- env HOME="$H" "$@"); } # show [-r] CMD...: print the command, its stdout, its stderr (prefixed "2> ") and its exit status; # as the user unless -r; escape sequences are made visible (cat -v) show() { local root=0 rc=0 o e [[ $1 == -r ]] && { root=1; shift; } o=$(mktemp) e=$(mktemp) printf '$ %s%s\n' "$( ((root)) && echo '(root) ')" "$*" if ((root)); then "$@" >"$o" 2>"$e" "$o" 2>"$e" /' "$e" | cat -v printf '[exit %s]\n' "$rc" rm -f "$o" "$e" } step "setup: base-devel git sudo, user $U (wheel, NOPASSWD)" pacman -Syu --noconfirm --needed base-devel git sudo >/dev/null 2>&1 || { echo "pacman -Syu failed"; exit 1; } useradd -m -G wheel "$U" echo "$U ALL=(ALL:ALL) NOPASSWD: ALL" >/etc/sudoers.d/$U chmod 0440 /etc/sudoers.d/$U # aur_build NAME [older]: clone NAME from the AUR and makepkg -si it; "older" checks out the newest # commit whose .SRCINFO pkgver differs from the current one first (an outdated install) aur_build() { as_user bash -c ' set -e cd ~ && git clone -q "https://aur.archlinux.org/$1.git" && cd "$1" if [ "${2:-}" = older ]; then cur=$(sed -n "s/^\tpkgver = //p" .SRCINFO) for c in $(git log --format=%h -- .SRCINFO); do v=$(git show "$c:.SRCINFO" | sed -n "s/^\tpkgver = //p") if [ "$v" != "$cur" ]; then git checkout -q "$c"; break; fi done fi makepkg -si --noconfirm >/dev/null 2>&1 ' _ "$@" || { echo "aur_build $* failed"; exit 1; } } # paru-bin 2.1.0 links libalpm.so.15 and does not start with pacman 7.1 (libalpm.so.16): # "error while loading shared libraries: libalpm.so.15" (verified) - build paru from source aur_build "${PARU_PKG:-paru}" aur_build yay-bin aur_build pfetch older show paru --version show yay --version show -r pacman -Qm step "runuser -u: the environment it sets" show -r runuser -u "$U" -- env show -r runuser -u "$U" -- id step "a foreign package that is not in the AUR (local build)" w=$(mktemp -d) mkdir -p "$w/usr/share/su-local-only" echo 1.0 >"$w/usr/share/su-local-only/VERSION" printf 'pkgname = su-local-only\npkgbase = su-local-only\npkgver = 1.0-1\npkgdesc = local only\narch = any\nsize = 4\n' >"$w/.PKGINFO" (cd "$w" && bsdtar --zstd -cf /tmp/su-local-only-1.0-1-any.pkg.tar.zst .PKGINFO usr) pacman -U --noconfirm /tmp/su-local-only-1.0-1-any.pkg.tar.zst >/dev/null 2>&1 show -r pacman -Qm step "-Qua (piped, stdin /dev/null)" show paru -Qua show yay -Qua show paru -Qu show yay -Qu step "-Qua with IgnorePkg = pfetch" sed -i '0,/^\[options\]/s||[options]\nIgnorePkg = pfetch|' /etc/pacman.conf show paru -Qua show yay -Qua sed -i '/^IgnorePkg = pfetch$/d' /etc/pacman.conf step "-Si / -Sia of an AUR package, compared with -Qi" show -r env COLUMNS=0 pacman -Qi pfetch show paru -Si pfetch show paru -Sia pfetch show paru -Si --aur pfetch show yay -Si pfetch show yay -Sia pfetch show paru -Sia no-such-package-zzz show yay -Sia no-such-package-zzz show paru -Si bash step "-Qua as root" show -r paru -Qua show -r yay -Qua step "AUR unreachable (aur.archlinux.org -> 127.0.0.1)" cp /etc/hosts /tmp/hosts.orig echo '127.0.0.1 aur.archlinux.org' >>/etc/hosts show paru -Qua show yay -Qua show paru -Sia pfetch show yay -Sia pfetch cat /tmp/hosts.orig >/etc/hosts # reset_pfetch: back to the outdated pfetch built at the start (makepkg left the package file) reset_pfetch() { pacman -U --noconfirm "$H"/pfetch/pfetch-[0-9]*.pkg.tar.zst >/dev/null 2>&1; pacman -Q pfetch; } step "-Sua as root (pfetch outdated)" show -r paru -Sua --noconfirm show -r yay -Sua --noconfirm show -r pacman -Q pfetch step "-Sua without --noconfirm, stdin /dev/null (no terminal)" show paru -Sua show -r pacman -Q pfetch reset_pfetch show yay -Sua show -r pacman -Q pfetch reset_pfetch step "-Sua --ignore (non-interactive: --noconfirm, stdin /dev/null)" show paru -Sua --noconfirm --ignore pfetch show -r pacman -Q pfetch show yay -Sua --noconfirm --ignore pfetch show -r pacman -Q pfetch show paru -Sua --noconfirm --ignore su-dummy-x,su-dummy-y show -r pacman -Q pfetch reset_pfetch show yay -Sua --noconfirm show -r pacman -Q pfetch step "devel (-git) packages: pfetch-git (conflicts with pfetch, which goes first)" show -r pacman -Rns --noconfirm pfetch show paru -S --noconfirm pfetch-git show -r pacman -Q pfetch-git show paru --gendb show yay -Y --gendb for f in "$H/.local/state/paru/devel.toml" "$H/.cache/yay/vcs.json"; do echo "--- $f"; cat "$f"; echo sed -i -E 's/[0-9a-f]{40}/0000000000000000000000000000000000000000/g' "$f" echo "--- $f with every commit id replaced by zeros (an older upstream state)"; cat "$f"; echo done show paru -Qua show paru -Qua --devel show yay -Qua show yay -Qua --devel show paru -Sua --noconfirm show -r pacman -Q pfetch-git show paru -Sua --noconfirm --devel show -r pacman -Q pfetch-git step "-Qua with nothing to upgrade" show paru -Qua show yay -Qua show paru -Qua --devel show yay -Qua --devel echo "ALL DONE"