95 lines
4.6 KiB
Bash
Executable File
95 lines
4.6 KiB
Bash
Executable File
#!/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
|
|
|
|
# ── Root server bootstrap ───────────────────────────────────────────────────
|
|
#
|
|
# This path runs before the repository exists on a fresh VPS. Its safety
|
|
# properties need to be stated beside the public `boot --server` example, not
|
|
# inferred from the shell implementation or buried in a fixture.
|
|
|
|
bootstrap_doc="$(sed -n '/^That command also works from a brand-new VPS/,/^`install` asks/p' "$readme" | tr '\n' ' ')"
|
|
|
|
require_bootstrap_doc() {
|
|
local pattern="$1" explanation="$2"
|
|
grep -qiE "$pattern" <<<"$bootstrap_doc" || note "$explanation"
|
|
}
|
|
|
|
require_bootstrap_doc 'verified target key' \
|
|
'the root bootstrap docs do not require a verified target key'
|
|
require_bootstrap_doc '700.*600|600.*700' \
|
|
'the root bootstrap docs do not state the exact SSH ownership and modes'
|
|
require_bootstrap_doc 'hardening (is )?unavailable.*(without|until).*key' \
|
|
'the root bootstrap docs do not say hardening is unavailable without a key'
|
|
require_bootstrap_doc 'sshd -t' \
|
|
'the root bootstrap docs do not name sshd -t validation'
|
|
require_bootstrap_doc 'atomic.*same.directory|same.directory.*atomic' \
|
|
'the root bootstrap docs do not describe the atomic same-directory drop-in'
|
|
require_bootstrap_doc 'detected (SSH )?unit.*reload|reload.*detected (SSH )?unit' \
|
|
'the root bootstrap docs do not describe reloading the detected SSH unit'
|
|
require_bootstrap_doc 'restores? (the )?previous drop-in.*(validation|reload)|(validation|reload).*restores? (the )?previous drop-in' \
|
|
'the root bootstrap docs do not promise rollback on validation or reload failure'
|
|
require_bootstrap_doc 'fixture contracts.*(these|this) (path|branch)|fixture contracts.*test' \
|
|
'the root bootstrap docs do not limit proof to fixture contracts'
|
|
require_bootstrap_doc 'no real daemon reload.*panama test --safe|panama test --safe.*no real daemon reload' \
|
|
'the root bootstrap docs imply a live daemon reload under the safe suite'
|
|
|
|
if grep -qiE 'merely writes? (the )?(SSH )?(drop-in|file)|reload failure.*ignored|ignores? .*reload failure' <<<"$bootstrap_doc"; then
|
|
note 'the root bootstrap docs weaken the transaction by treating the write or reload failure as harmless'
|
|
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"
|