diff --git a/README.md b/README.md index f189366..c138ea1 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ docs/ Settings reference, and the design specs behind the work ## Tests -121 of them, under `tests/`. Run the lot, or a subset by pattern: +126 of them, under `tests/`. Run the lot, or a subset by pattern: ```sh panama test # everything @@ -127,9 +127,21 @@ panama edit # open it in Neovim panama doctor # what is actually running, not what was installed panama test # every contract, or a subset by pattern panama upgrade # re-run ./install from anywhere +panama apps # choose applications to install, by category panama app # applications no repository carries; build one by name ``` +`panama apps` is the optional-application catalog, opened after the fact. The +interview offers the same categories during `./install`, whole; this picks a +category and then the applications inside it, so a machine can acquire Slack in +March without having wanted Discord in January. Both read +`setup/lib/extras-catalog`, so the two cannot describe different catalogues. + +A category is one file under `setup/packages/extras/`. A bare line is a dnf +package, a `flatpak:` line is a Flathub id, `| Name` gives the menu something +readable, and an indented line belongs to the entry above it — which is how OBS +carries its sixteen plugin extensions as one thing to tick. + `panama app` is deliberately not part of `./install`. Everything else Panama installs comes from dnf or Flathub; these are built from source because no packaged form exists, and a source build is slow, wants the network throughout, diff --git a/tests/setup/readme-contract b/tests/setup/readme-contract new file mode 100755 index 0000000..cb31538 --- /dev/null +++ b/tests/setup/readme-contract @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# The README describes this repository accurately. +# +# It carries two facts that are cheap to state and easy to leave behind: how +# many contracts there are, and which `panama` subcommands exist. Both had +# already drifted -- the count said 121 when the suite had grown to 125, one day +# after it was written. +# +# A number in prose is not worth much on its own. It is worth something as a +# claim somebody might rely on, and worth nothing once it is wrong, so it is +# either checked or it should not be there. + +set -uo pipefail + +repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +readme="$repo_dir/README.md" +panama="$repo_dir/bin/panama" + +findings=() +note() { findings+=("$1"); } + +# ── The contract count ─────────────────────────────────────────────────────── +# +# Counted the way `panama test` collects the suite, so the README agrees with +# what the runner actually reports rather than with a second idea of it. + +actual="$(find "$repo_dir/tests" -type f -not -path '*/fixtures/*' -not -path '*__pycache__*' \ + \( -executable -o -name '*_test.py' \) | wc -l)" + +claimed="$(grep -oE '^[0-9]+ of them, under' "$readme" | grep -oE '^[0-9]+')" + +if [[ -z "$claimed" ]]; then + note 'the README no longer states a contract count in the form this checks' +elif (( claimed != actual )); then + note "the README says $claimed contracts; there are $actual" +fi + +# ── Documented subcommands exist ───────────────────────────────────────────── +# +# A README listing a command the dispatcher does not have sends somebody to a +# 'Unknown command' error, which reads as a broken install rather than a stale +# document. + +while read -r subcommand; do + [[ -n "$subcommand" ]] || continue + grep -qE "^\s+$subcommand\)" "$panama" \ + || note "the README documents 'panama $subcommand', which the dispatcher does not handle" +done < <(sed -n '/^panama [a-z]/s/^panama \([a-z-]*\).*/\1/p' "$readme" | sort -u) + +if (( ${#findings[@]} > 0 )); then + mapfile -t findings < <(printf '%s\n' "${findings[@]}" | sort -u) + printf 'readme contract: %d finding(s)\n' "${#findings[@]}" >&2 + printf ' - %s\n' "${findings[@]}" >&2 + exit 1 +fi + +printf 'readme contract: PASS (%d contracts, as documented)\n' "$actual"