#!/bin/sh
# Pre-commit hook for holger.
#
# 1. nornir — re-render managed markdown (README.md / CHANGELOG.md) and stage it.
# 2. kvasir — regenerate the tracked AI-context packs
# (docs/ai-context.md + docs/ai-context-full.md) from .nornir/ai-context.toml
# and the code, and stage them, so they never drift.
#
# Rules:
# * Markdown only — never regenerates the depgraph SVG or the rendered book.
# * A MISSING tool never blocks a commit (warn + skip).
# * kvasir DOES block the commit if the metadata is broken (blocking validation
# errors) — that is a real defect to fix, not a doc refresh.
set -u
REPO='holger'
REPO_ROOT="$(git rev-parse --show-toplevel)"
# ── 1. nornir: managed markdown (README.md / CHANGELOG.md) ────────────────────
if command -v nornir >/dev/null 2>&1; then
if out=$(nornir docs render "$REPO" 2>&1); then
# HARD RULE: markdown only — discard any regenerated assets.
# Also discard .nornir/README-full.md: the installed nornir blanks its
# benchmark tables ("no bench history yet") whenever the bench warehouse
# is unreachable, which would clobber the committed numbers. Restore it so
# only README.md / CHANGELOG.md are refreshed here; regenerate README-full
# deliberately (with the warehouse available) when the benches change.
for restore in .nornir/assets/depgraph.svg docs/book.pdf .nornir/README-full.md; do
[ -f "$restore" ] && git checkout -- "$restore" 2>/dev/null || true
done
for f in README.md CHANGELOG.md; do
[ -f "$f" ] && git add -- "$f" 2>/dev/null || true
done
else
echo "nornir: docs render failed — committing without README/CHANGELOG refresh" >&2
echo "$out" | sed 's/^/nornir: /' >&2
fi
else
echo "nornir: README/CHANGELOG render skipped (nornir not on PATH)" >&2
fi
# ── 2. kvasir: AI-context packs (docs/ai-context{,-full}.md) ──────────────────
# Only regenerate when this commit actually stages code / a manifest / the
# maintained metadata — a doc-only or config-only commit cannot change the packs'
# content, so skip it (avoids churning the 490 KB full pack and re-stamping the
# snapshot on every commit).
if git diff --cached --name-only | grep -qE '\.rs$|(^|/)Cargo\.toml$|^\.nornir/ai-context\.toml$'; then
kvasir_relevant=1
else
kvasir_relevant=0
fi
# Prefer kvasir on PATH; else fall back to a sibling release build.
KVASIR="$(command -v kvasir 2>/dev/null || true)"
if [ -z "$KVASIR" ] && [ -x "$REPO_ROOT/../kvasir/target/release/kvasir" ]; then
KVASIR="$REPO_ROOT/../kvasir/target/release/kvasir"
fi
if [ "$kvasir_relevant" = 0 ]; then
: # no code/metadata staged — packs cannot have changed; leave them as-is.
elif [ -n "$KVASIR" ]; then
log="$(mktemp)"
if "$KVASIR" "$REPO_ROOT" >"$log" 2>&1; then
git add -- docs/ai-context.md docs/ai-context-full.md 2>/dev/null || true
else
echo "kvasir: AI-context generation has BLOCKING validation errors — commit aborted." >&2
echo "kvasir: fix .nornir/ai-context.toml (or run: kvasir .) and retry." >&2
sed 's/^/kvasir: /' "$log" >&2
rm -f "$log"
exit 1
fi
rm -f "$log"
else
echo "kvasir: AI-context refresh skipped (kvasir not found on PATH or at ../kvasir/target/release)" >&2
echo "kvasir: install with 'cargo install --path ../kvasir' to keep docs/ai-context*.md in sync." >&2
fi
exit 0