fix(show): star marker, aligned gutter and smarter AUR merge

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.
This commit is contained in:
bryanpedini committed 2026-10-10 16:01:51 +02:00
1 parent def537af58
commit 3af159e09a
16 files changed
+680 -288

No files matched your search

+147 -35
View File
@@ -314,22 +314,30 @@ upgrade_steps() {
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')"
assert_line 'Install Reason : Explicitly installed'
assert_line 'Description : A pretty system information tool written in POSIX sh.'
[[ $(count_lines 'Description : A pretty system information tool written in POSIX sh.') -eq 1 ]]
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' \
'> Repository : aur' \
'> AUR URL : https://aur.archlinux.org/packages/pfetch' \
'> Make Deps : None' \
'> Check Deps : None' \
'> Maintainer : yigits' \
'> Votes : 48' \
'> Popularity : 0.10344' \
'> First Submitted : Sat, 16 Jan 2021 09:13:08' \
'> Last Modified : Tue, 9 Jun 2026 22:43:50' \
'> Out Of Date : No')"
' 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" {
@@ -337,45 +345,149 @@ upgrade_steps() {
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')"
assert_line '> Repository : aur'
assert_line '> Keywords : fetch'
assert_line '> First Submitted : Sat 16 Jan 2021 09:13:08 AM UTC'
assert_line '> Out-of-date : No'
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 '^> [A-Z#]'
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?? when the AUR record does not merge: -Qi, then the AUR record with every line marked >" {
@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'
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_line '> Repository : aur'
assert_output --partial "$(printf '%s\n' 'Version : 1.10.0-1' '> Version : 1.11.0-1')"
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'
assert_line '* Maintainer : yigits'
log_has 'paru -Sia pfetch'
log_lacks '^runuser'
}
@@ -384,8 +496,8 @@ upgrade_steps() {
unset SUDO_USER
run skup show pfetch
assert_success
assert_line 'Name : pfetch'
refute_line --regexp '^> '
assert_line ' Name : pfetch'
refute_line --regexp '^\* '
[[ $(grep -c 'warning: aur:' <<<"$output") -eq 1 ]]
log_lacks '^paru'
}