Files
soleprint/ctrl/theme.sh

81 lines
3.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Bake the theme and its parts into the pages that use them.
#
# Usage:
# ./ctrl/theme.sh # bake — rewrite every generated block
# ./ctrl/theme.sh check # fail if any page is stale; changes nothing
# ./ctrl/theme.sh new [title] # a scaffold page to start from
# ./ctrl/theme.sh run FILE [--list|--check] [--only NAME]
# # every page a run file lists, each with a contract
# ./ctrl/theme.sh parts # what can be added, and the markup that adds it
# ./ctrl/theme.sh export [name...] # the contract for a subset, as one doc
#
# `export` is for handing a vetted LLM what it needs to write an ad-hoc page —
# the chosen parts, their markup, and the tokens resolved to literal values, so
# the document stands alone. Naming parts is the point: hand over everything and
# you get back a page built from Vue components that cannot run standalone.
#
# ./ctrl/theme.sh export panel split > /tmp/contract.md
#
# Call the script directly when piping; `make` echoes its recipe to stdout.
# For whole-repo context this is the wrong tool — station/tools/distill already
# flattens a tree to one budgeted document.
#
# A page that says `background: var(--bg)` and never gets `--bg` is UNSTYLED,
# not merely unbranded — the declaration is invalid at computed-value time. That
# is why every page carries a baked default, and why `check` is worth running.
#
# This exists because bake.py was reachable by no command at all: not from the
# Makefile, not from ctrl/, not from build.py. A drift check nobody runs is a
# drift check that reports nothing, and the evidence was already on disk —
# histgen's page linked /theme.css for months, was missing from the old
# hardcoded page list, and so was never baked once.
set -e
# Where the caller stood. A run file is named relative to there, and the cd below
# would otherwise make `run ./theme.toml` mean a different file.
CALLER_DIR="$PWD"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
cd "$ROOT_DIR/soleprint"
PYTHON="${PYTHON:-python3}"
case "${1:-bake}" in
bake) exec "$PYTHON" common/theme/bake.py ;;
check) exec "$PYTHON" common/theme/bake.py --check ;;
parts)
exec "$PYTHON" common/theme/bake.py --parts
;;
run)
# A run file: every page a project has, its context, and a contract per
# page for the LLM. See soleprint/common/theme/theme.example.toml.
shift
args=() file="" prev=""
for a in "$@"; do
if [[ -z "$file" && "$a" != -* && "$prev" != "--only" ]]; then
file="$(cd "$CALLER_DIR" && realpath -m -- "$a")"
args+=("$file")
else
args+=("$a")
fi
prev="$a"
done
exec "$PYTHON" common/theme/bake.py --run "${args[@]}"
;;
new)
shift
exec "$PYTHON" common/theme/bake.py --new "$@"
;;
export)
shift
exec "$PYTHON" common/theme/bake.py --export "$@"
;;
*)
echo "Unknown: $1" >&2
echo "Usage: ./ctrl/theme.sh [new [title]|parts|bake|check|export [name...]|run FILE]" >&2
exit 1
;;
esac