N?? / show marks the upstream candidate with "*" instead of ">" (the
prompt, which read as a command in logs), and every line but the note
gets a two-character gutter: " " for the installed record, "* " for the
candidate, so keys and colons line up. The plain native fallback (zypper,
unmergeable records) and the not-installed candidate use the same gutter.
pacman records (-Qi with -Si or the AUR helper's -Sia) are now compared
the way they are meant:
- values unwrapped (continuation lines joined, runs of blanks as one):
yay wraps Depends On / Optional Deps at 80 columns even without a
terminal unless COLUMNS=0, which the helper now gets for -Qua and -Sia
- Depends On, Provides, Conflicts With, Make/Check Deps and the other
lists as sets of exact tokens in any order (a constraint is a change)
- Optional Deps by package names ("name: description [installed]" in
-Qi, bare names from the AUR)
- a differing value is one line like -Qi, Optional Deps one entry per
line; candidate-only fields sit next to their counterpart (Repository
after Version, AUR URL after URL, Maintainer after Packager, ...)
Verified on recorded claude-desktop records (paru 2.1.0, yay 13.0.1, the
installed 2.9939.4-1 from the AUR's own .SRCINFO); discovery/pacman.md
section 15.2.
664 lines
27 KiB
Bash
664 lines
27 KiB
Bash
#!/usr/bin/env bats
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
# Copyright (C) 2026 Bryan Joshua Pedini
|
|
|
|
# AUR packages on the pacman backend, through the fake paru/yay (tests/unit/fakes/paru) replaying
|
|
# the output recorded in discovery/pacman.md section 15: helper detection and overrides, the user
|
|
# the helper runs as (runuser/sudo -u, SUDO_USER, a root login), the "*" marker column, -Qua
|
|
# parsing and failures, N? / N?? / N- / N+ / Nx on an AUR row, and the upgrade (repository
|
|
# packages with pacman first, then `-Sua --ignore ...`; --noconfirm only without a terminal).
|
|
# Rows with the fake paru: [1]* pfetch [2] su-dummy-a [3]* su-dummy-aur [4] su-dummy-b
|
|
# [5] su-dummy-c (pfetch and su-dummy-aur are foreign: in no repository).
|
|
|
|
# each @test runs in its own subshell: per-test exports are intended
|
|
# shellcheck disable=SC2030,SC2031
|
|
|
|
load test_helper
|
|
|
|
setup() {
|
|
common_setup
|
|
use_fakes paru pacman runuser getent
|
|
export SKEPTICAL_UPDATER_OS_RELEASE=$FAKE_DATA/os-release-arch
|
|
# root through our sudo re-exec, invoked by alice (fake getent: uid 1000, home below)
|
|
export SUDO_USER=alice
|
|
ALICE_HOME=$FAKE_DIR/home/alice
|
|
mkdir -p "$ALICE_HOME"
|
|
AS_ALICE="runuser -u alice -- env HOME=$ALICE_HOME"
|
|
}
|
|
|
|
ROW1=' [1]* pfetch 1.10.0-1 -> 1.11.0-1 aur'
|
|
ROW2=' [2] su-dummy-a 1.0-1 -> 2.0-1 su-dummy'
|
|
ROW3=' [3]* su-dummy-aur 1.0-1 -> 2.0-1 aur'
|
|
ROW4=' [4] su-dummy-b 1.0-1 -> 2.0-1 su-dummy'
|
|
ROW5=' [5] su-dummy-c 1.0-1 -> 2.0-1 su-dummy'
|
|
|
|
# upgrade_steps: the upgrade's steps from the fake log, in order (throwaway --dbpath normalised)
|
|
upgrade_steps() {
|
|
grep -E '^(pacman -Sup --noconfirm|pacman -Su |real sync at -Su|(runuser|sudo) -u .* -Sua|paru -Sua|yay -Sua)' "$FAKE_LOG" |
|
|
sed -E 's#--dbpath /tmp/skeptical-updater-db\.[^ ]+#--dbpath DB#'
|
|
}
|
|
|
|
# ---- detection and overrides -------------------------------------------------------------------
|
|
|
|
@test "detection: paru first; the banner names the helper" {
|
|
use_fakes paru yay pacman runuser getent
|
|
run skup list --no-refresh
|
|
assert_success
|
|
assert_line --index 0 'Backend: pacman (Arch Linux) + AUR via paru'
|
|
log_has 'paru -Qua'
|
|
log_lacks '^yay'
|
|
}
|
|
|
|
@test "detection: yay when paru is not installed" {
|
|
use_fakes yay pacman runuser getent
|
|
run skup list --no-refresh
|
|
assert_success
|
|
assert_line --index 0 'Backend: pacman (Arch Linux) + AUR via yay'
|
|
log_has "$AS_ALICE yay -Qua"
|
|
assert_line "$ROW1"
|
|
assert_line "$ROW3"
|
|
}
|
|
|
|
@test "pman: the banner reads pman (Arch Linux) + AUR via paru" {
|
|
use_fakes pman paru pacman runuser getent
|
|
run skup list --no-refresh
|
|
assert_success
|
|
assert_line --index 0 'Backend: pman (Arch Linux) + AUR via paru'
|
|
}
|
|
|
|
@test "--aur-helper=yay picks yay although paru is installed" {
|
|
use_fakes paru yay pacman runuser getent
|
|
run skup --aur-helper=yay list --no-refresh
|
|
assert_success
|
|
assert_line --index 0 'Backend: pacman (Arch Linux) + AUR via yay'
|
|
log_has 'yay -Qua'
|
|
log_lacks '^paru'
|
|
run skup --aur-helper yay list --no-refresh
|
|
assert_success
|
|
assert_line --index 0 'Backend: pacman (Arch Linux) + AUR via yay'
|
|
}
|
|
|
|
@test "--no-aur and --aur-helper=none: no helper runs, no AUR row, plain banner" {
|
|
for opt in --no-aur --aur-helper=none; do
|
|
: >"$FAKE_LOG"
|
|
run skup "$opt" list --no-refresh
|
|
assert_success
|
|
assert_line --index 0 'Backend: pacman (Arch Linux)'
|
|
assert_line '3 upgradable, 0 trusted (hidden, use --all to show), 3 to review:'
|
|
assert_line ' [1] su-dummy-a 1.0-1 -> 2.0-1 su-dummy'
|
|
refute_output --partial 'pfetch'
|
|
log_lacks '^(paru|yay|runuser)'
|
|
done
|
|
}
|
|
|
|
@test "no helper installed: no AUR, plain banner, every row still has the marker column" {
|
|
use_fakes pacman runuser getent
|
|
run skup list --no-refresh
|
|
assert_success
|
|
assert_line --index 0 'Backend: pacman (Arch Linux)'
|
|
assert_line ' [1] su-dummy-a 1.0-1 -> 2.0-1 su-dummy'
|
|
log_lacks '^runuser'
|
|
}
|
|
|
|
@test "--aur-helper names a helper that is not installed: error (exit 1), nothing runs" {
|
|
use_fakes paru pacman runuser getent
|
|
run skup --aur-helper=yay list --no-refresh
|
|
assert_failure 1
|
|
assert_output --partial 'error: --aur-helper=yay: yay not found in PATH'
|
|
[[ -z $(cat "$FAKE_LOG") ]]
|
|
}
|
|
|
|
@test "--aur-helper: an unknown or empty value is a usage error" {
|
|
run skup --aur-helper=trizen list
|
|
assert_failure 1
|
|
assert_output --partial "unknown AUR helper 'trizen' (expected paru, yay or none)"
|
|
run skup --aur-helper= list
|
|
assert_failure 1
|
|
assert_output --partial '--aur-helper needs a value'
|
|
run skup list --aur-helper
|
|
assert_failure 1
|
|
assert_output --partial '--aur-helper needs a value'
|
|
[[ -z $(cat "$FAKE_LOG") ]]
|
|
}
|
|
|
|
@test "apt: no helper is ever run, even with paru in PATH; --aur-helper is ignored with a warning" {
|
|
use_fakes apt paru runuser getent
|
|
export SKEPTICAL_UPDATER_OS_RELEASE=$FAKE_DATA/os-release-debian12
|
|
run skup list --no-refresh
|
|
assert_success
|
|
assert_line --index 0 'Backend: apt (Debian GNU/Linux 12 (bookworm))'
|
|
assert_line ' [1] su-dummy-a 1.0 -> 2.0 su-fixture:su-repo'
|
|
refute_output --partial 'aur'
|
|
run skup --aur-helper=paru list --no-refresh
|
|
assert_success
|
|
assert_output --partial 'warning: --aur-helper=paru is ignored: AUR helpers only apply to the pacman backend (Arch Linux and derivatives)'
|
|
run skup --no-aur list --no-refresh
|
|
assert_success
|
|
refute_output --partial 'warning'
|
|
log_lacks '^(paru|yay|runuser)'
|
|
}
|
|
|
|
# ---- the user the helper runs as ---------------------------------------------------------------
|
|
|
|
@test "root through sudo: the helper runs as SUDO_USER with runuser -u, that user's HOME, from that home" {
|
|
run skup list --no-refresh
|
|
assert_success
|
|
log_has "$AS_ALICE paru -Qua"
|
|
log_has "paru as: HOME=$ALICE_HOME PWD=$ALICE_HOME stdin=notty"
|
|
}
|
|
|
|
@test "root through sudo without runuser: sudo -u USER -- env HOME=..." {
|
|
use_fakes paru pacman sudo getent
|
|
run skup list --no-refresh
|
|
assert_success
|
|
log_has "sudo -u alice -- env HOME=$ALICE_HOME paru -Qua"
|
|
log_has "paru as: HOME=$ALICE_HOME PWD=$ALICE_HOME stdin=notty"
|
|
assert_line "$ROW1"
|
|
}
|
|
|
|
@test "unprivileged (list --no-refresh): the helper runs directly, as we are" {
|
|
export SKEPTICAL_UPDATER_EUID=1000
|
|
unset SUDO_USER
|
|
run skup list --no-refresh
|
|
assert_success
|
|
assert_line --index 0 'Backend: pacman (Arch Linux) + AUR via paru'
|
|
log_has 'paru -Qua'
|
|
log_lacks '^(runuser|sudo)'
|
|
assert_line "$ROW1"
|
|
}
|
|
|
|
@test "a root login (no SUDO_USER): AUR skipped with a warning after the banner; repository rows listed" {
|
|
unset SUDO_USER
|
|
run skup list --no-refresh
|
|
assert_success
|
|
assert_line --index 0 'Backend: pacman (Arch Linux)'
|
|
assert_line --index 1 'skeptical-updater: warning: aur: paru is never run as root and there is no invoking user (SUDO_USER is not set): AUR packages are neither listed nor upgraded (run skeptical-updater through sudo from your own account, or use --no-aur)'
|
|
assert_line '3 upgradable, 0 trusted (hidden, use --all to show), 3 to review:'
|
|
[[ $(grep -c 'warning: aur:' <<<"$output") -eq 1 ]]
|
|
log_lacks '^(paru|runuser)'
|
|
}
|
|
|
|
@test "SUDO_USER root (or another uid 0 name) or an unknown user: AUR skipped with a warning" {
|
|
for u in root toor; do
|
|
SUDO_USER=$u run skup list --no-refresh
|
|
assert_success
|
|
assert_line --index 0 'Backend: pacman (Arch Linux)'
|
|
assert_output --partial "warning: aur: paru is never run as root and the invoking user ($u) is root"
|
|
done
|
|
SUDO_USER=nosuchuser run skup list --no-refresh
|
|
assert_success
|
|
assert_output --partial "warning: aur: the invoking user 'nosuchuser' (SUDO_USER) is unknown"
|
|
log_lacks '^(paru|runuser)'
|
|
}
|
|
|
|
@test "a root login: the interactive upgrade runs pacman only, no helper" {
|
|
unset SUDO_USER
|
|
run skup --no-refresh <<<''
|
|
assert_success
|
|
log_has 'pacman -Su --noconfirm'
|
|
log_lacks '^(paru|runuser)'
|
|
}
|
|
|
|
# ---- listing ------------------------------------------------------------------------------------
|
|
|
|
@test "the * marker: right after the bracket of AUR rows, a space there on the others; columns aligned" {
|
|
run skup list --no-refresh
|
|
assert_success
|
|
assert_line '5 upgradable, 0 trusted (hidden, use --all to show), 5 to review:'
|
|
assert_output --partial "$(printf '%s\n' "$ROW1" "$ROW2" "$ROW3" "$ROW4" "$ROW5")"
|
|
}
|
|
|
|
@test "the marker column stays aligned with the - and = markers" {
|
|
write_state "$HEADER" "pacman${T}su-dummy-aur${T}user${T}2026-10-09T09:40:12Z"
|
|
run skup --all --no-refresh <<<$'1-\nl\nq'
|
|
assert_success
|
|
assert_line '-[1]* pfetch 1.10.0-1 -> 1.11.0-1 aur'
|
|
assert_line '=[3]* su-dummy-aur 1.0-1 -> 2.0-1 aur'
|
|
assert_line ' [2] su-dummy-a 1.0-1 -> 2.0-1 su-dummy'
|
|
}
|
|
|
|
@test "--no-refresh still lists the AUR rows (the helper always asks the AUR)" {
|
|
run skup list --no-refresh
|
|
assert_success
|
|
log_lacks '^pacman -Sy'
|
|
log_has "$AS_ALICE paru -Qua"
|
|
assert_line "$ROW3"
|
|
}
|
|
|
|
@test "with a refresh too: AUR rows next to the rows of the reviewed databases" {
|
|
run skup list
|
|
assert_success
|
|
assert_line 'Refreshing package lists... done.'
|
|
assert_line "$ROW1"
|
|
assert_line "$ROW2"
|
|
}
|
|
|
|
@test "-Qua failing (AUR unreachable): the helper's message and a warning; repository rows listed" {
|
|
FAKE_AUR_QUA=fail run skup list --no-refresh
|
|
assert_success
|
|
assert_line --index 0 'Backend: pacman (Arch Linux) + AUR via paru'
|
|
assert_output --partial 'warning: paru: error: error sending request for url (https://aur.archlinux.org/rpc): error trying to connect'
|
|
assert_output --partial 'warning: aur: paru -Qua failed, AUR packages not listed'
|
|
assert_line '3 upgradable, 0 trusted (hidden, use --all to show), 3 to review:'
|
|
refute_output --partial '*'
|
|
}
|
|
|
|
@test "yay -Qua failing: its multi-line message is shown without the blank lines" {
|
|
use_fakes yay pacman runuser getent
|
|
FAKE_AUR_QUA=fail run skup list --no-refresh
|
|
assert_success
|
|
assert_output --partial 'warning: yay: -> 1 error occurred:'
|
|
assert_output --partial 'dial tcp 127.0.0.1:443: connect: connection refused'
|
|
assert_output --partial 'warning: aur: yay -Qua failed, AUR packages not listed'
|
|
refute_line 'skeptical-updater: warning: yay: '
|
|
}
|
|
|
|
@test "-Qua with nothing to upgrade (exit 1, silent) is not a failure" {
|
|
FAKE_AUR_QUA=none run skup list --no-refresh
|
|
assert_success
|
|
refute_output --partial 'warning'
|
|
assert_line '3 upgradable, 0 trusted (hidden, use --all to show), 3 to review:'
|
|
}
|
|
|
|
@test "paru marks IgnorePkg packages [ignored] (shown [held]); yay leaves them out" {
|
|
FAKE_AUR_QUA=ignored run skup list --no-refresh
|
|
assert_success
|
|
assert_line ' [1]* pfetch 1.10.0-1 -> 1.11.0-1 aur [held]'
|
|
use_fakes yay pacman runuser getent
|
|
FAKE_AUR_QUA=ignored run skup list --no-refresh
|
|
assert_success
|
|
refute_output --partial 'pfetch'
|
|
assert_line ' [2]* su-dummy-aur 1.0-1 -> 2.0-1 aur'
|
|
}
|
|
|
|
@test "yay: the age suffix ([122d13h]) is no flag; its colored root warning on stdout is no row" {
|
|
use_fakes yay pacman runuser getent
|
|
for q in fixture noise; do
|
|
FAKE_AUR_QUA=$q run skup list --no-refresh
|
|
assert_success
|
|
assert_output --partial "$(printf '%s\n' "$ROW1" "$ROW2" "$ROW3")"
|
|
refute_output --partial 'Avoid'
|
|
refute_output --partial '122d13h'
|
|
done
|
|
}
|
|
|
|
@test "devel packages: the new version is latest-commit (paru by default, yay with --devel)" {
|
|
for h in paru yay; do
|
|
use_fakes "$h" pacman runuser getent
|
|
FAKE_AUR_QUA=devel run skup list --no-refresh
|
|
assert_success
|
|
assert_line --regexp '^ \[1\]\* pfetch-git +r432\.a906ff8-1 +-> +latest-commit +aur$'
|
|
done
|
|
}
|
|
|
|
@test "a name a repository lists wins over the AUR row (moved from the AUR into a repository)" {
|
|
FAKE_AUR_QUA=dup run skup list --no-refresh
|
|
assert_success
|
|
assert_line --regexp '^ \[3\] su-dummy-b +1\.0-1 +-> +2\.0-1 +su-dummy$'
|
|
refute_output --partial '9.0-1'
|
|
}
|
|
|
|
# ---- N? N?? N+ Nx on an AUR row ---------------------------------------------------------------
|
|
|
|
@test "N? on an AUR row: description, install reason and dependents from pacman -Qi" {
|
|
run skup --no-refresh <<<$'1?\nq'
|
|
assert_success
|
|
assert_output --partial "$(printf '%s\n' '> 1?' \
|
|
'pfetch: A pretty system information tool written in POSIX sh.' \
|
|
'reason: explicitly installed' \
|
|
'required by: nothing')"
|
|
log_lacks 'paru -Si'
|
|
}
|
|
|
|
@test "N?? on an AUR row: pacman -Qi merged with paru -Sia (same key column)" {
|
|
run skup --no-refresh <<<$'1??\nq'
|
|
assert_success
|
|
log_has "$AS_ALICE paru -Sia pfetch"
|
|
assert_line '# lines starting with * come from the upstream candidate: a differing value, or a field the installed record lacks'
|
|
assert_output --partial "$(printf '%s\n' ' Version : 1.10.0-1' '* Version : 1.11.0-1' '* Repository : aur')"
|
|
assert_line ' Install Reason : Explicitly installed'
|
|
assert_line ' Description : A pretty system information tool written in POSIX sh.'
|
|
[[ $(grep -c 'Description : A pretty system' <<<"$output") -eq 1 ]]
|
|
# the AUR-only fields next to their installed counterparts, the rest at the end
|
|
assert_output --partial "$(printf '%s\n' \
|
|
' URL : https://github.com/Un1q32/pfetch' \
|
|
'* AUR URL : https://aur.archlinux.org/packages/pfetch')"
|
|
assert_output --partial "$(printf '%s\n' \
|
|
' Optional Deps : None' \
|
|
'* Make Deps : None' \
|
|
'* Check Deps : None')"
|
|
assert_output --partial "$(printf '%s\n' \
|
|
' Packager : Unknown Packager' \
|
|
'* Maintainer : yigits' \
|
|
' Build Date : Sat Oct 10 12:42:02 2026' \
|
|
'* Last Modified : Tue, 9 Jun 2026 22:43:50' \
|
|
'* First Submitted : Sat, 16 Jan 2021 09:13:08')"
|
|
assert_output --partial "$(printf '%s\n' \
|
|
' Validated By : None' \
|
|
'* Votes : 48' \
|
|
'* Popularity : 0.10344' \
|
|
'* Out Of Date : No')"
|
|
}
|
|
|
|
@test "N?? with yay: its wider key column is re-padded to pacman's" {
|
|
use_fakes yay pacman runuser getent
|
|
run skup --no-refresh <<<$'1??\nq'
|
|
assert_success
|
|
log_has "$AS_ALICE yay -Sia pfetch"
|
|
assert_output --partial "$(printf '%s\n' ' Version : 1.10.0-1' '* Version : 1.11.0-1' '* Repository : aur')"
|
|
assert_output --partial "$(printf '%s\n' ' Groups : None' '* Keywords : fetch')"
|
|
assert_line '* First Submitted : Sat 16 Jan 2021 09:13:08 AM UTC'
|
|
assert_output --partial "$(printf '%s\n' ' Validated By : None' '* Popularity : 0.103440' '* Votes : 48' '* Out-of-date : No')"
|
|
refute_output --regexp 'Repository {10,}:'
|
|
}
|
|
|
|
@test "N?? when the AUR has no record of it: the installed record alone" {
|
|
run skup --no-refresh <<<$'3??\nq'
|
|
assert_success
|
|
assert_line ' Name : su-dummy-aur'
|
|
assert_line ' Install Reason : Explicitly installed'
|
|
refute_line --regexp '^\* '
|
|
log_has "$AS_ALICE paru -Sia su-dummy-aur"
|
|
}
|
|
|
|
@test "N?? claude-desktop (recorded): yay's wrapped record unwrapped, one-line lists, Optional Deps per entry, AUR fields in place" {
|
|
# real records: the installed 2.9939.4-1 (pacman -Qi of a stand-in built from the AUR's own
|
|
# .SRCINFO of that version) and yay 13.0.1's -Sia of 2.31226.1-1, wrapped at 80 columns as yay
|
|
# prints it without COLUMNS=0 (discovery/pacman.md section 15.2)
|
|
use_fakes yay pacman runuser getent
|
|
run skup show claude-desktop
|
|
assert_success
|
|
assert_output "$(cat <<'EOF'
|
|
# lines starting with * come from the upstream candidate: a differing value, or a field the installed record lacks
|
|
Name : claude-desktop
|
|
Version : 2.9939.4-1
|
|
* Version : 2.31226.1-1
|
|
* Repository : aur
|
|
Description : Official Claude AI desktop app from Anthropic — Chat, Cowork, and Claude Code
|
|
Architecture : x86_64
|
|
URL : https://claude.com/download
|
|
* AUR URL : https://aur.archlinux.org/packages/claude-desktop
|
|
Licenses : LicenseRef-Proprietary
|
|
Groups : None
|
|
* Keywords : None
|
|
Provides : None
|
|
Depends On : alsa-lib at-spi2-core cairo dbus expat gcc-libs glib2 glibc gtk3 hicolor-icon-theme libcap-ng libcups libdrm libnotify libseccomp libsecret libx11 libxcb libxcomposite libxdamage libxext libxfixes libxkbcommon libxrandr libxtst mesa nspr nss pango socat systemd-libs util-linux-libs virtiofsd xdg-desktop-portal xdg-utils
|
|
* Depends On : alsa-lib at-spi2-core bubblewrap cairo dbus expat gcc-libs glib2 glibc gtk3 hicolor-icon-theme libcap-ng libcups libdrm libnotify libpipewire libseccomp libsecret libx11 libxcb libxcomposite libxdamage libxext libxfixes libxkbcommon libxrandr libxtst mesa nspr nss pango socat systemd-libs util-linux-libs virtiofsd xdg-desktop-portal xdg-utils qemu-system-x86 edk2-ovmf
|
|
Optional Deps : gnome-keyring: credential storage via Secret Service (GNOME)
|
|
kwallet: credential storage (KDE Plasma) [installed]
|
|
libayatana-appindicator: system tray icon
|
|
xdg-desktop-portal-gtk: portal backend for GTK desktops
|
|
xdg-desktop-portal-kde: portal backend for KDE Plasma
|
|
* Optional Deps : gnome-keyring
|
|
* kwallet
|
|
* libayatana-appindicator
|
|
* xdg-desktop-portal-gtk
|
|
* xdg-desktop-portal-kde
|
|
* qemu-system-aarch64
|
|
* edk2-aarch64
|
|
* Make Deps : None
|
|
* Check Deps : None
|
|
Required By : None
|
|
Optional For : None
|
|
Conflicts With : claude claude-desktop-bin
|
|
Replaces : None
|
|
Installed Size : 117.74 MiB
|
|
Packager : Unknown Packager
|
|
* Maintainer : diazkev314
|
|
Build Date : Sat Oct 3 04:00:00 2026
|
|
* Last Modified : Fri 09 Oct 2026 11:31:19 PM UTC
|
|
* First Submitted : Sun 05 Jul 2026 01:58:02 AM UTC
|
|
Install Date : Sat Oct 10 13:49:52 2026
|
|
Install Reason : Explicitly installed
|
|
Install Script : No
|
|
Validated By : None
|
|
* Popularity : 6.458490
|
|
* Votes : 21
|
|
* Out-of-date : No
|
|
EOF
|
|
)"
|
|
log_has "$AS_ALICE yay -Sia claude-desktop"
|
|
}
|
|
|
|
@test "N?? claude-desktop: paru's unwrapped record merges to the same Depends On and Optional Deps lines" {
|
|
use_fakes yay pacman runuser getent
|
|
run skup show claude-desktop
|
|
yay_out=$output
|
|
use_fakes paru pacman runuser getent
|
|
run skup show claude-desktop
|
|
assert_success
|
|
[[ $(grep -A8 '^ Depends On' <<<"$output") == "$(grep -A8 '^ Depends On' <<<"$yay_out")" ]] ||
|
|
fail "paru and yay merge Depends On / Optional Deps differently"
|
|
assert_line '* Out Of Date : No'
|
|
}
|
|
|
|
@test "N?? pacman lists: a wrapped, reordered Depends On and bare Optional Deps names equal to the installed sets print once" {
|
|
use_fakes yay pacman runuser getent
|
|
FAKE_AUR_SIA=same run skup show claude-desktop
|
|
assert_success
|
|
[[ $(count_lines ' Depends On : alsa-lib at-spi2-core cairo dbus expat gcc-libs glib2 glibc gtk3 hicolor-icon-theme libcap-ng libcups libdrm libnotify libseccomp libsecret libx11 libxcb libxcomposite libxdamage libxext libxfixes libxkbcommon libxrandr libxtst mesa nspr nss pango socat systemd-libs util-linux-libs virtiofsd xdg-desktop-portal xdg-utils') -eq 1 ]]
|
|
refute_line --regexp '^\* +(Depends On|Optional Deps|Conflicts With) *:'
|
|
refute_line --regexp '^\* {18,}'
|
|
assert_output --partial "$(printf '%s\n' \
|
|
' kwallet: credential storage (KDE Plasma) [installed]' \
|
|
' libayatana-appindicator: system tray icon' \
|
|
' xdg-desktop-portal-gtk: portal backend for GTK desktops' \
|
|
' xdg-desktop-portal-kde: portal backend for KDE Plasma' \
|
|
'* Make Deps : None')"
|
|
}
|
|
|
|
@test "N?? pacman lists: an added token or a changed version constraint is a difference (one * line, as -Qi prints it)" {
|
|
use_fakes yay pacman runuser getent
|
|
FAKE_AUR_SIA=constraint run skup show claude-desktop
|
|
assert_success
|
|
assert_line --regexp '^\* Depends On : xdg-utils xdg-desktop-portal virtiofsd .* pango nss>=3\.100 nspr .* at-spi2-core alsa-lib$'
|
|
[[ $(grep -c '^\* Depends On' <<<"$output") -eq 1 ]]
|
|
refute_line --regexp '^\* +(Optional Deps|Conflicts With) *:'
|
|
run skup show claude-desktop
|
|
assert_line --regexp '^\* Depends On : alsa-lib at-spi2-core bubblewrap cairo .* libnotify libpipewire libseccomp .* xdg-utils qemu-system-x86 edk2-ovmf$'
|
|
# an extra upstream name in Optional Deps: the upstream block, one entry per line
|
|
assert_output --partial "$(printf '%s\n' \
|
|
'* Optional Deps : gnome-keyring' \
|
|
'* kwallet' \
|
|
'* libayatana-appindicator' \
|
|
'* xdg-desktop-portal-gtk' \
|
|
'* xdg-desktop-portal-kde' \
|
|
'* qemu-system-aarch64' \
|
|
'* edk2-aarch64')"
|
|
}
|
|
|
|
@test "N?? when the AUR record does not merge: -Qi, then the AUR record with every line marked *" {
|
|
FAKE_AUR_SIA=twice run skup --no-refresh <<<$'1??\nq'
|
|
assert_success
|
|
assert_line '# lines starting with * are the AUR record (paru -Sia) as it prints it'
|
|
refute_line --partial '# lines starting with * come from the upstream candidate'
|
|
assert_line ' Version : 1.10.0-1'
|
|
[[ $(count_lines '* Version : 1.11.0-1') -eq 2 ]]
|
|
[[ $(count_lines '* Repository : aur') -eq 2 ]]
|
|
assert_line ' Install Reason : Explicitly installed'
|
|
}
|
|
|
|
@test "show PKG for an AUR package: the same merge, the helper decided on the spot" {
|
|
run skup show pfetch
|
|
assert_success
|
|
assert_output --partial "$(printf '%s\n' ' Version : 1.10.0-1' '* Version : 1.11.0-1' '* Repository : aur')"
|
|
export SKEPTICAL_UPDATER_EUID=1000
|
|
unset SUDO_USER
|
|
: >"$FAKE_LOG"
|
|
run skup show pfetch
|
|
assert_success
|
|
assert_line '* Maintainer : yigits'
|
|
log_has 'paru -Sia pfetch'
|
|
log_lacks '^runuser'
|
|
}
|
|
|
|
@test "show of an AUR package as a root login: one warning, the installed record" {
|
|
unset SUDO_USER
|
|
run skup show pfetch
|
|
assert_success
|
|
assert_line ' Name : pfetch'
|
|
refute_line --regexp '^\* '
|
|
[[ $(grep -c 'warning: aur:' <<<"$output") -eq 1 ]]
|
|
log_lacks '^paru'
|
|
}
|
|
|
|
@test "N+ on an AUR row trusts it like any installed package (backend pacman)" {
|
|
run skup --no-refresh <<<$'1+\nl\nq'
|
|
assert_success
|
|
assert_line 'trusted pfetch'
|
|
assert_line '5 upgradable, 1 trusted (hidden, use --all to show), 4 to review:'
|
|
run cat "$STATE_FILE"
|
|
assert_line --regexp "^pacman${T}pfetch${T}user${T}${DATE_RE}\$"
|
|
}
|
|
|
|
@test "Nx on an AUR row purges it with pacman -Rns; the row leaves the list" {
|
|
run skup --no-refresh <<<$'1x\ny\nl\nq'
|
|
assert_success
|
|
log_has 'pacman -Rs --print --print-format %n -- pfetch'
|
|
assert_line 'Purge pfetch now? [y/N] y'
|
|
log_has 'pacman -Rns --noconfirm -- pfetch'
|
|
assert_line '4 upgradable, 0 trusted (hidden, use --all to show), 4 to review:'
|
|
[[ $(grep -c '^ \[1\]\* pfetch' <<<"$output") -eq 1 ]] || fail "row 1 is still listed after the purge"
|
|
assert_line ' [3]* su-dummy-aur 1.0-1 -> 2.0-1 aur'
|
|
}
|
|
|
|
# ---- the upgrade --------------------------------------------------------------------------------
|
|
|
|
@test "<enter>: the repository step first (pre-check, databases, -Su), then the helper as the invoking user" {
|
|
run skup <<<''
|
|
assert_success
|
|
assert_line 'Upgrade finished.'
|
|
run upgrade_steps
|
|
assert_output "$(printf '%s\n' \
|
|
'pacman -Sup --noconfirm --dbpath DB --print-format %n %v' \
|
|
'pacman -Su --noconfirm' \
|
|
'real sync at -Su: reviewed 1 / no-sig' \
|
|
"$AS_ALICE paru -Sua --noconfirm" \
|
|
'paru -Sua --noconfirm')"
|
|
log_has "paru as: HOME=$ALICE_HOME PWD=$ALICE_HOME stdin=notty"
|
|
}
|
|
|
|
@test "N- on an AUR row: the helper's --ignore; pacman never sees AUR names" {
|
|
run skup --no-refresh <<<$'1-\n'
|
|
assert_success
|
|
assert_line 'Excluded from this run: pfetch'
|
|
log_has 'pacman -Su --noconfirm'
|
|
assert_line "+ $AS_ALICE paru -Sua --noconfirm --ignore pfetch"
|
|
log_has 'paru -Sua --noconfirm --ignore pfetch'
|
|
log_lacks '^pacman .*--ignore'
|
|
}
|
|
|
|
@test "N- on a repository row: pacman --ignore and the helper's --ignore both get it" {
|
|
run skup --no-refresh <<<$'2-\n1-\n'
|
|
assert_success
|
|
log_has 'pacman -Su --noconfirm --ignore su-dummy-a'
|
|
log_has "$AS_ALICE paru -Sua --noconfirm --ignore pfetch,su-dummy-a"
|
|
}
|
|
|
|
@test "every AUR row excluded: the helper is not run" {
|
|
run skup --no-refresh <<<$'1-\n3-\n'
|
|
assert_success
|
|
log_has 'pacman -Su --noconfirm'
|
|
log_lacks '-Sua'
|
|
}
|
|
|
|
@test "only AUR rows left to upgrade: pacman is not run, only the helper" {
|
|
run skup <<<$'2- 4- 5-\n'
|
|
assert_success
|
|
assert_line 'No repository package to upgrade: pacman is not run, only paru.'
|
|
log_lacks '^pacman -Su'
|
|
log_lacks '^pacman -Sup --noconfirm'
|
|
log_lacks '^real sync'
|
|
log_has "$AS_ALICE paru -Sua --noconfirm --ignore su-dummy-a,su-dummy-b,su-dummy-c"
|
|
assert_line 'Upgrade finished.'
|
|
}
|
|
|
|
@test "no AUR row at all: exactly the repository upgrade as before" {
|
|
FAKE_AUR_QUA=none run skup --no-refresh <<<''
|
|
assert_success
|
|
log_has 'pacman -Su --noconfirm'
|
|
log_lacks '-Sua'
|
|
}
|
|
|
|
@test "trusted (hidden) AUR rows are upgraded by the helper too" {
|
|
write_state "$HEADER" "pacman${T}pfetch${T}user${T}2026-10-09T09:40:12Z" "pacman${T}su-dummy-aur${T}user${T}2026-10-09T09:40:12Z"
|
|
# listed: [1] su-dummy-a [2] su-dummy-b [3] su-dummy-c (both AUR rows trusted: hidden)
|
|
run skup --no-refresh <<<$'1- 2- 3-\n'
|
|
assert_success
|
|
assert_line 'No repository package to upgrade: pacman is not run, only paru.'
|
|
log_has "$AS_ALICE paru -Sua --noconfirm --ignore su-dummy-a,su-dummy-b,su-dummy-c"
|
|
}
|
|
|
|
@test "an [ignored] AUR row alone does not make pacman stand aside" {
|
|
FAKE_AUR_QUA=ignored run skup --no-refresh <<<$'2- 3- 4- 5-\n'
|
|
assert_success
|
|
log_has 'pacman -Su --noconfirm --ignore su-dummy-a,su-dummy-b,su-dummy-c'
|
|
log_lacks '-Sua'
|
|
}
|
|
|
|
@test "the helper failing after a successful repository step: reported, its exit status returned" {
|
|
FAKE_AUR_SUA_RC=1 run skup --no-refresh <<<''
|
|
assert_failure 1
|
|
log_has 'pacman -Su --noconfirm'
|
|
assert_output --partial 'error: the AUR upgrade failed: paru exited with status 1 (the repository packages were upgraded)'
|
|
refute_output --partial 'hint:'
|
|
refute_output --partial 'Upgrade finished.'
|
|
}
|
|
|
|
@test "the helper failing in an AUR-only upgrade: its exit status" {
|
|
FAKE_AUR_SUA_RC=4 run skup --no-refresh <<<$'2- 4- 5-\n'
|
|
assert_failure 4
|
|
assert_output --partial 'error: the AUR upgrade failed: paru exited with status 4'
|
|
refute_output --partial 'repository packages were upgraded'
|
|
}
|
|
|
|
@test "a failing repository step: the helper is not run" {
|
|
FAKE_PACMAN_SU_RC=1 run skup --no-refresh <<<''
|
|
assert_failure 1
|
|
assert_output --partial 'the upgrade failed: pacman exited with status 1'
|
|
log_lacks '-Sua'
|
|
FAKE_PACMAN_SUP_RC=1 run skup <<<'2-'$'\n'
|
|
assert_failure 1
|
|
log_lacks '-Sua'
|
|
}
|
|
|
|
@test "--dry-run prints the helper's command line (root through sudo: as the invoking user)" {
|
|
run skup --dry-run --no-refresh <<<$'1-\n'
|
|
assert_success
|
|
assert_line '+ pacman -Su --noconfirm'
|
|
assert_line "+ $AS_ALICE paru -Sua --noconfirm --ignore pfetch"
|
|
assert_line 'Dry run: nothing was changed.'
|
|
log_lacks '-Sua'
|
|
log_lacks '^pacman -Su '
|
|
}
|
|
|
|
@test "--dry-run unprivileged: the helper's plain command line" {
|
|
export SKEPTICAL_UPDATER_EUID=1000
|
|
unset SUDO_USER
|
|
run skup --dry-run <<<''
|
|
assert_success
|
|
assert_line '+ paru -Sua --noconfirm'
|
|
log_lacks '-Sua'
|
|
log_lacks '^(runuser|sudo)'
|
|
}
|
|
|
|
@test "on a terminal: no --noconfirm, the helper gets the terminal (its PKGBUILD review)" {
|
|
pty_skup $'3-\r\r' --no-refresh
|
|
assert_success
|
|
log_has "$AS_ALICE paru -Sua --ignore su-dummy-aur"
|
|
log_has "paru as: HOME=$ALICE_HOME PWD=$ALICE_HOME stdin=tty"
|
|
log_lacks 'noconfirm --ignore su-dummy-aur'
|
|
log_has 'pacman -Su --noconfirm'
|
|
}
|
|
|
|
@test "help and --help mention the * marker and the options" {
|
|
run skup --no-refresh <<<$'h\nq'
|
|
assert_success
|
|
assert_line " l redraw the list (a '*' after the number marks an AUR package)"
|
|
run skup --help
|
|
assert_success
|
|
assert_line --partial '--aur-helper=NAME pacman backend: list and upgrade AUR packages with paru or yay, or'
|
|
assert_line --partial '--no-aur same as --aur-helper=none'
|
|
assert_output --partial "A '*' right after the number marks an AUR package"
|
|
}
|