Files
Panama/tests/quickshell/panama-commands-contract
T
Gabriel Brown 3c359f3f7e Notice the battery, and the machine it is or is not in
Panama had no idea whether it was running on a laptop. No upower, no
battery, no lid, no AC: hypridle.conf says "This is a desktop" in its
own header, and that was true of the code as well as the machine.

panama-hw answers hardware questions one at a time, exits 0 or 1, and
prints nothing, so scripts, services and contracts all ask the same
way. The definition the rest of the laptop work hangs on is one line:
clamshell is lid-closed AND an external monitor. A machine with no
mains supply at all reports as being on wall power, because a desktop
cannot run out of it.

The battery service follows Vitals: sysfs through FileView, an
availability flag, and no subprocess on the timer. Globbing is the one
thing QML cannot do -- a battery is BAT0 or BAT1 or CMB0, mains is AC
or ADP1 or ACAD -- so panama-battery resolves the names once and the
shell reads the files directly after. Nothing falls back to a
plausible zero: a desktop shows no indicator, no card, and no charge
limit control where the firmware has no ceiling.

Also repairs two contracts that were already failing and had not been
noticed, because only the full suite runs them. The dependency
scanner treated line-initial variable assignments, case labels,
comments and heredoc bodies as commands, and `count`, `host`, `cancel`
and `import` are all real binaries on Fedora, so `command -v` could
not filter them out. It now drops comments and heredoc bodies and
requires a command to be followed by whitespace. Verified it still
catches a genuinely undeclared dependency rather than passing quietly.
The launcher command contract had not been told about the fourteen
commands added earlier today.
2026-08-21 21:43:14 -04:00

159 lines
6.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
commands_dir="$repo_dir/config/local/share/vicinae/scripts"
work="$(mktemp -d /tmp/panama-commands.XXXXXX)"
dispatch_log="$work/dispatch.log"
fail() {
printf 'Panama commands contract: %s\n' "$1" >&2
exit 1
}
cleanup() {
rm -rf "$work"
}
trap cleanup EXIT
declare -A expected=(
[open-control-center]=control-center
[open-notifications]=notifications
[open-calendar]=calendar
[open-clipboard]=clipboard
[open-mission-control]=overview
[open-settings]=settings
[check-system-health]=health
[toggle-dnd]=dnd
[toggle-caffeine]=caffeine
[toggle-night-light]=night-light
[start-focus]=focus-start
[end-focus]=focus-end
[capture]=capture
[screen-intelligence]=intelligence
[quick-screenshot]=screenshot
[toggle-microphone]=microphone
[open-prism-gallery]=gallery
[restart-shell]=restart-shell
)
# The per-page settings commands are generated from the settings page list, so
# they are enumerated from that list rather than restated here -- a hand-written
# copy would have to be edited every time a page is added, which is exactly the
# kind of second list this generator exists to avoid.
sidebar="$repo_dir/config/dot/quickshell/modules/settings/SettingsSidebar.qml"
while read -r page; do
[[ -n "$page" ]] || continue
[[ "$page" == "home" ]] && continue
expected[settings-$page]="settings-page $page"
done < <(grep -oE '\{ page: "[a-z-]+"' "$sidebar" | sed 's/.*"\([a-z-]*\)"/\1/')
(( ${#expected[@]} > 18 )) || fail 'no generated per-page commands were found; run scripts/panama-settings-commands'
# Commands that do not go through panama-action, and should not.
#
# Every command above asks the shell to do something, so routing them through
# one dispatcher is what keeps that surface small. search-web is a different
# animal: it takes a query and opens a browser, and neither half needs the
# shell. Sending it through panama-action would mean a web search stops working
# when Quickshell is down -- which is exactly when somebody is reaching for the
# launcher to look up what went wrong.
#
# The project commands are the same shape: they record or restore a window
# layout, which is panama-project's job and involves the shell not at all.
#
# They are still commands, so everything else below applies to them: a title,
# a description, search vocabulary, the Panama icon, and closing quietly.
#
# The OS-parity commands are standalone for the same reason. A power menu that
# needs the shell running is a power menu you cannot reach when the shell is
# what broke; the pick-lists render through `vicinae dmenu` and act through
# hyprctl; reminders are systemd timers. None of them has anything to ask the
# shell for, and routing them through panama-action would only add a way for
# them to stop working.
declare -a standalone=(
search-web save-project open-project
lock-screen suspend-system log-out reboot-system power-off
remind-me list-reminders pick-color
switch-window force-quit-window kill-process ssh-hosts recent-files
copy-password
)
# Generated commands must match their source. A stale command dispatches to a
# page that has been renamed or removed, and the launcher reports nothing wrong.
"$repo_dir/config/dot/quickshell/scripts/panama-settings-commands" --check >/dev/null \
|| fail 'the generated per-page commands are stale; run scripts/panama-settings-commands'
mkdir -p "$work/home/.config/quickshell/scripts"
cat >"$work/home/.config/quickshell/scripts/panama-action" <<'EOF'
#!/usr/bin/env bash
printf '%s\n' "$*" >>"$PANAMA_COMMAND_TEST_LOG"
EOF
chmod +x "$work/home/.config/quickshell/scripts/panama-action"
[[ -d "$commands_dir" ]] || fail 'Vicinae command directory is missing'
# Every file in the directory, not a glob on an extension. These scripts carry
# none: a shebang and the executable bit already select the interpreter, and an
# extension is one more thing that has to stay in sync -- which it did not.
mapfile -t actual_files < <(find "$commands_dir" -maxdepth 1 -type f -printf '%f\n' | sort)
declared=$(( ${#expected[@]} + ${#standalone[@]} ))
[[ ${#actual_files[@]} -eq $declared ]] \
|| fail "expected $declared commands, found ${#actual_files[@]}"
declare -A seen_titles=()
for script_name in "${!expected[@]}" "${standalone[@]}"; do
script="$commands_dir/$script_name"
[[ -x "$script" ]] || fail "$script_name is missing or not executable"
vicinae script check "$script" >/dev/null \
|| fail "$script_name is rejected by Vicinae"
title="$(sed -n 's/^# @vicinae.title //p' "$script")"
# No product prefix: this is the desktop's own settings, not a third-party
# add-on announcing itself in someone else's launcher. Uniqueness still
# matters, because two commands with one title are indistinguishable there.
[[ -n $title ]] || fail "$script_name has no title"
[[ $title != Panama* ]] || fail "$script_name still carries the product prefix: $title"
[[ -z ${seen_titles[$title]+x} ]] || fail "duplicate launcher title: $title"
seen_titles[$title]=1
grep -Fxq '# @vicinae.mode silent' "$script" \
|| fail "$script_name does not close quietly after success"
grep -Fq '# @vicinae.description ' "$script" \
|| fail "$script_name has no searchable description"
grep -Fq '# @vicinae.keywords ' "$script" \
|| fail "$script_name has no search vocabulary"
grep -Fxq '# @vicinae.icon ../../icons/hicolor/scalable/apps/panama-settings.svg' "$script" \
|| fail "$script_name does not use the Panama application identity"
if [[ $script_name == check-system-health ]]; then
[[ $title == 'Check System Health' ]] \
|| fail "health command has the wrong title: $title"
grep -Fxq '# @vicinae.schemaVersion 1' "$script" \
|| fail 'health command does not use schema version 1'
grep -Fxq '# @vicinae.keywords ["health", "doctor", "repair", "services"]' "$script" \
|| fail 'health command has the wrong search vocabulary'
grep -Fxq 'exec "$HOME/.config/quickshell/scripts/panama-action" health' "$script" \
|| fail 'health command bypasses the stable dispatcher path'
fi
# A standalone command has nothing to dispatch, and running it would open a
# browser at whoever is running the tests.
if [[ -z ${expected[$script_name]+x} ]]; then
if grep -Fq 'panama-action' "$script"; then
fail "$script_name is listed as standalone but goes through panama-action"
fi
continue
fi
: >"$dispatch_log"
HOME="$work/home" PANAMA_COMMAND_TEST_LOG="$dispatch_log" "$script"
dispatched="$(cat "$dispatch_log")"
[[ $dispatched == "${expected[$script_name]}" ]] \
|| fail "$script_name dispatched [$dispatched], expected [${expected[$script_name]}]"
done
printf 'Panama commands contract: PASS (%d commands)\n' "$declared"