Files
omarchy-pkgs/tests/settings-runtime-profile.sh
T
40ea1555f2 Ship the complete passwordless-sudo lifecycle in settings-dev (#645)
* Move the dev sudo grant lifecycle into omarchy-settings-dev

The hardened omarchy-sudo-passwordless publishes a grant only when its revocation hook is installed and no package transaction has left /run/omarchy-sudo-passwordless-package-removing behind. The hook sets that marker before every settings upgrade, and the settings scriptlets are what clear it, so shipping the hook alone let the first grant work and then refused every grant after the next update until a reboot.

omarchy-settings-dev now ships the command, omarchy-security-functions, the boot cleanup rule and the hook together, with the scriptlets from #257 that revoke before the package changes and clear the marker once no grant remains. omarchy-dev stops shipping the two helpers and requires the settings release that does: without it omarchy-update has no library to source.

Co-authored-by: Afonso Oliveira <afonso.oliveira707@gmail.com>

* Check that settings-dev registers the scriptlet the lifecycle test exercises

The lifecycle test reads the .install file directly, so it kept passing with the recipe's install= line gone, which is the one change that would strand the hook's marker again.

Co-Authored-By: Codex XHigh <noreply@openai.com>

* Keep omarchy-dev's settings dependency unversioned

The dev pair builds each package on its own against the published edge repository, in the PR build and in publish alike, so omarchy-dev cannot require a settings-dev release that only this change produces: the floor failed both omarchy-dev builds on this PR, and an exact pkgver match would fail the same way on every upstream pin bump. Nothing needs it. The upstream watch moves both pins together, publish stops the run before anything is published when one package fails, and a new settings-dev over an old runtime is refused on the files they would both own.

* Refuse settings-dev releases that predate the grant helper move

With the dependency unversioned, a new omarchy-dev could still install over a settings-dev that is held back or not yet published, removing omarchy-security-functions from both, and omarchy-update cannot start without it. A versioned conflict refuses that pairing at install time without constraining the per-package builds, which resolve only depends.

Co-Authored-By: Codex XHigh <noreply@openai.com>

* Require the security library as a capability instead of a version floor

The conflict named the last settings-dev release without the helpers, a version that moves with every upstream pin bump and settings-only pkgrel while this change waits to merge, and a rebase that kept a stale floor still passed the tests while the published release slipped past it. omarchy-settings-dev now provides omarchy-security-functions and omarchy-dev's package() requires it. makepkg checks only the top-level depends before building, so the per-package builds still resolve against the published repository, while pacman refuses a runtime without a settings release that ships the library, and pulls that release in when only the runtime is asked for.

Co-Authored-By: Codex XHigh <noreply@openai.com>

---------

Co-authored-by: Spencer Bull <spencer@omarchy.org>
Co-authored-by: Afonso Oliveira <afonso.oliveira707@gmail.com>
Co-authored-by: Codex XHigh <noreply@openai.com>
2026-10-11 09:56:47 -05:00

218 lines
11 KiB
Bash
Executable File

#!/bin/bash
# Run the omarchy-settings and omarchy-settings-dev recipes' package() against
# synthetic source trees: an older source keeps today's per-architecture
# package, and a source that selects its platform profile at runtime ships the
# same files, backup and optdepends on aarch64 as on x86_64.
set -euo pipefail
export LC_ALL=C
BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/..")
scratch=$(mktemp -d)
trap 'rm -rf "$scratch"' EXIT
fail() {
printf 'FAIL: %s\n' "$@" >&2
exit 1
}
files=(
applications/example.desktop
bin/omarchy-debug
bin/omarchy-debug-idle
bin/omarchy-hw-platform
bin/omarchy-security-functions
bin/omarchy-sudo-passwordless
bin/omarchy-upload-log
config/autostart/limine-snapper-notify.desktop
config/hypr/hyprland.lua
default/applications/mimeapps.list
default/bashrc
default/environment.d/10-omarchy-fcitx.conf
default/fontconfig/conf.avail/50-omarchy.conf
default/fonts/omarchy/omarchy.ttf
default/libalpm/hooks/05-omarchy-passwordless-revoke.hook
default/hypr/toggles/flags.lua
default/libalpm/hooks/00-omarchy-platform-guard.hook
default/libalpm/scripts/omarchy-platform-guard
default/limine/default.conf
default/limine/limine.conf
default/nautilus-python/extensions/localsend.py
default/nautilus-python/extensions/transcode.py
default/plymouth/omarchy.plymouth
default/sddm/hyprland.lua
default/sddm/omarchy/Main.qml
default/snapper/root
default/systemd/system-sleep/unmount-fuse
default/systemd/system/plocate-updatedb.service.d/10-omarchy.conf
default/systemd/user/app.slice.d/10-oomd.conf
default/systemd/user/bt-agent.service
default/systemd/user/omarchy-crash-watch.service
default/systemd/user/omarchy-fcitx5.service
default/systemd/user/omarchy-migrate-notify.service
default/systemd/user/omarchy-recover-internal-monitor.service
default/systemd/user/omarchy-sleep-lock.service
default/systemd/user/omarchy-tailscale-receive.service
default/systemd/zram-generator.conf.d/90-omarchy.conf
default/tensaku/state.toml
default/uwsm/env.d/10-omarchy
default/wayland-sessions/omarchy.desktop
default/xdg-terminal-exec/hyprland-xdg-terminals.list
etc/cups/cups-browsed.conf
etc/cups/cups-files.conf
etc/fastfetch/config.jsonc
etc/limine-entry-tool.d/omarchy-defaults.conf
etc/limine-entry-tool.d/omarchy-uki.conf
etc/mkinitcpio.conf.d/omarchy_hooks.conf
etc/mkinitcpio.conf.d/thunderbolt_module.conf
etc/modprobe.d/omarchy-usb-autosuspend.conf
etc/nsswitch.conf
etc/plymouth/plymouthd.conf
etc/security/faillock.conf
etc/sysctl.d/99-omarchy-sysctl.conf
etc/systemd/oomd.conf.d/10-omarchy.conf
etc/systemd/zram-generator.conf
etc/tmpfiles.d/omarchy-zswap.conf
icon.png
icon.txt
logo.svg
logo.txt
)
# Left out of an older source's aarch64 package, and nothing else is. Its boot
# drop-ins ship on both (omacom/omarchy-pkgs#380).
legacy_aarch64_absent=(
etc/mkinitcpio.conf.d/thunderbolt_module.conf
etc/modprobe.d/omarchy-usb-autosuspend.conf
etc/systemd/oomd.conf.d/10-omarchy.conf
etc/systemd/zram-generator.conf
etc/tmpfiles.d/omarchy-zswap.conf
usr/lib/systemd/user/app.slice.d/10-oomd.conf
usr/lib/systemd/zram-generator.conf.d/90-omarchy.conf
)
x86_backup=(
etc/mkinitcpio.conf.d/thunderbolt_module.conf
etc/modprobe.d/omarchy-usb-autosuspend.conf
etc/systemd/oomd.conf.d/10-omarchy.conf
etc/systemd/zram-generator.conf
)
keyboard_unit=default/systemd/user/omarchy-brightness-keyboard-auto.service
platform_guard=(
usr/share/libalpm/hooks/00-omarchy-platform-guard.hook
usr/share/libalpm/scripts/omarchy-hw-platform
usr/share/libalpm/scripts/omarchy-platform-guard
)
# $1: source tree. Extra arguments are files to add to it.
make_source() {
local tree=$1 path
shift
for path in "${files[@]}" "$@"; do
mkdir -p "$(dirname "$tree/$path")"
printf 'fixture for %s\n' "$path" >"$tree/$path"
done
}
# Runs package() as makepkg would for one architecture (arch-specific arrays
# merged first) and records the package tree and its metadata. $1: recipe,
# $2: source tree, $3: CARCH, $4: output name, $5: "checkout" to build through
# OMARCHY_SRC, "pinned" for the git source.
package_as() {
local recipe=$1 tree=$2 carch=$3 name=$4 mode=$5
(
unset OMARCHY_SRC
[[ $mode == "pinned" ]] || export OMARCHY_SRC=$tree
export CARCH=$carch srcdir=$scratch/$name-src pkgdir=$scratch/$name
mkdir -p "$srcdir" "$pkgdir"
ln -sfn "$tree" "$srcdir/omarchy"
backup=()
# shellcheck disable=SC1090 # Exercise the recipe's own package function.
source "$BUILD_ROOT/pkgbuilds/$recipe/PKGBUILD"
eval "optdepends+=(\"\${optdepends_${carch}[@]}\")"
package
printf '%s\n' "${backup[@]}" | sort >"$scratch/$name.backup"
# shellcheck disable=SC2154 # Set by the recipe.
printf '%s\n' "${optdepends[@]}" >"$scratch/$name.optdepends"
(cd "$pkgdir" && find . \( -type f -o -type l \) | sed 's|^\./||' | sort) >"$scratch/$name.files"
)
}
in_list() {
grep -Fxq -- "$1" "$2"
}
fixtures=$BUILD_ROOT/tests/fixtures/settings-boot
make_source "$scratch/legacy"
cp "$fixtures/omarchy_hooks-v4.0.4.conf" "$scratch/legacy/etc/mkinitcpio.conf.d/omarchy_hooks.conf"
make_source "$scratch/profile" default/settings-runtime-profile "$keyboard_unit"
cp "$fixtures"/omarchy-13362/*.conf "$scratch/profile/etc/mkinitcpio.conf.d/"
for recipe in omarchy-settings omarchy-settings-dev; do
rm -rf "${scratch:?}"/legacy-* "${scratch:?}"/profile-*
# An older source keeps the per-architecture package it has always had.
package_as "$recipe" "$scratch/legacy" x86_64 legacy-x86_64 pinned
package_as "$recipe" "$scratch/legacy" aarch64 legacy-aarch64 pinned
for path in "${legacy_aarch64_absent[@]}"; do
in_list "$path" "$scratch/legacy-x86_64.files" || fail "older source ships $path on x86_64"
! in_list "$path" "$scratch/legacy-aarch64.files" || fail "older source leaves $path out on aarch64"
done
missing=$(comm -23 "$scratch/legacy-x86_64.files" "$scratch/legacy-aarch64.files")
[[ $missing == "$(printf '%s\n' "${legacy_aarch64_absent[@]}" | sort)" ]] ||
fail "older source's aarch64 package differs from x86_64 only by the boot and memory drop-ins" "$missing"
grep -Fxq 'if [[ " ${HOOKS[*]:-} " != *" asahi "* ]]; then' "$scratch/legacy-aarch64/etc/mkinitcpio.conf.d/omarchy_hooks.conf" ||
fail "older source's aarch64 HOOKS line applies only without asahi"
cmp -s "$scratch/legacy/etc/mkinitcpio.conf.d/omarchy_hooks.conf" "$scratch/legacy-x86_64/etc/mkinitcpio.conf.d/omarchy_hooks.conf" ||
fail 'x86_64 ships the source HOOKS line as it is'
cmp -s "$scratch/legacy/etc/sysctl.d/99-omarchy-sysctl.conf" "$scratch/legacy-x86_64/etc/sysctl.d/99-omarchy-sysctl.conf" ||
fail 'x86_64 ships the source sysctl file'
[[ $(grep -v '^#' "$scratch/legacy-aarch64/etc/sysctl.d/99-omarchy-sysctl.conf") == net.ipv4.tcp_mtu_probing=1 ]] ||
fail 'older source keeps only the network tuning on aarch64'
for path in "${x86_backup[@]}"; do
in_list "$path" "$scratch/legacy-x86_64.backup" || fail "x86_64 backs up $path"
! in_list "$path" "$scratch/legacy-aarch64.backup" || fail "older source's aarch64 backup leaves out $path"
done
for path in etc/mkinitcpio.conf.d/omarchy_hooks.conf etc/limine-entry-tool.d/omarchy-defaults.conf; do
in_list "$path" "$scratch/legacy-aarch64.backup" || fail "older source's aarch64 package backs up $path"
done
grep -q '^limine:' "$scratch/legacy-x86_64.optdepends" || fail 'x86_64 suggests the boot stack its drop-ins are for'
! grep -q '^limine:' "$scratch/legacy-aarch64.optdepends" || fail "older source's aarch64 package suggests no boot stack"
! in_list usr/lib/systemd/user/omarchy-brightness-keyboard-auto.service "$scratch/legacy-x86_64.files" ||
fail 'a source without the keyboard unit ships none'
echo "PASS: $recipe: an older source keeps its per-architecture package"
# A runtime-profile source ships the same tree and metadata on both.
package_as "$recipe" "$scratch/profile" x86_64 profile-x86_64 checkout
package_as "$recipe" "$scratch/profile" aarch64 profile-aarch64 pinned
# The pacman platform guard is the profile's one exception: aarch64 only.
for path in "${platform_guard[@]}"; do
in_list "$path" "$scratch/profile-aarch64.files" || fail "aarch64 ships the platform guard's $path"
! in_list "$path" "$scratch/profile-x86_64.files" || fail "x86_64 leaves out the platform guard's $path"
done
grep -Fxv -f <(printf '%s\n' "${platform_guard[@]}") "$scratch/profile-x86_64.files" >"$scratch/profile-x86_64.compared"
grep -Fxv -f <(printf '%s\n' "${platform_guard[@]}") "$scratch/profile-aarch64.files" >"$scratch/profile-aarch64.compared"
cmp -s "$scratch/profile-x86_64.compared" "$scratch/profile-aarch64.compared" ||
fail 'runtime-profile source ships the same files on both architectures' \
"$(diff "$scratch/profile-x86_64.compared" "$scratch/profile-aarch64.compared")"
while IFS= read -r path; do
if [[ -L $scratch/profile-x86_64/$path ]]; then
[[ $(readlink "$scratch/profile-x86_64/$path") == "$(readlink "$scratch/profile-aarch64/$path")" ]]
else
cmp -s "$scratch/profile-x86_64/$path" "$scratch/profile-aarch64/$path"
fi || fail "runtime-profile source ships the same $path on both architectures"
done <"$scratch/profile-x86_64.files"
cmp -s "$scratch/profile-x86_64.backup" "$scratch/profile-aarch64.backup" ||
fail 'runtime-profile source backs up the same files on both architectures'
cmp -s "$scratch/profile-x86_64.optdepends" "$scratch/profile-aarch64.optdepends" ||
fail 'runtime-profile source has the same optdepends on both architectures'
in_list etc/mkinitcpio.conf.d/00-omarchy-hooks.conf "$scratch/profile-x86_64.backup" ||
fail 'the HOOKS baseline drop-in is backed up where the source has it'
in_list usr/lib/systemd/user/omarchy-brightness-keyboard-auto.service "$scratch/profile-aarch64.files" ||
fail 'the keyboard unit first-run enables ships when the source has it'
comm -13 "$scratch/legacy-x86_64.files" "$scratch/profile-x86_64.files" >"$scratch/added"
for conf in 00-omarchy-hooks.conf omarchy_hooks.conf; do
cmp -s "$fixtures/omarchy-13362/$conf" "$scratch/profile-aarch64/etc/mkinitcpio.conf.d/$conf" ||
fail "runtime-profile source ships its $conf as it is on aarch64"
done
[[ $(cat "$scratch/added") == "$(printf '%s\n' usr/lib/systemd/user/omarchy-brightness-keyboard-auto.service usr/share/omarchy/default/settings-runtime-profile "usr/share/omarchy/$keyboard_unit" etc/mkinitcpio.conf.d/00-omarchy-hooks.conf | sort)" ]] ||
fail 'x86_64 gains only the new source files from a runtime-profile source' "$(cat "$scratch/added")"
echo "PASS: $recipe: a runtime-profile source ships the full set on aarch64"
done