Repository navigation
Expand file tree
/
Copy pathpre-commit
More file actions
executable file
·117 lines (99 loc) · 4.11 KB
/
Copy pathpre-commit
File metadata and controls
executable file
·117 lines (99 loc) · 4.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env bash
# pre-commit — zero-token, deterministic regen of the auto-generated index files.
#
# Whenever you commit anything in this repo, this hook:
# 1. Regenerates wiki/INDEX.md from current wiki/ pages
# 2. Regenerates bin/INDEX.md, scripts/workflows/INDEX.md,
# dictionaries/INDEX.md, wiki/compiled/EXPORTERS.md
# 3. Runs wiki-lint.py for warnings (does NOT block commit)
# 4. git-adds any updated index files so they go into the same commit
#
# True zero-roundtrip: no Claude tokens, no LLM, no API call. Pure Python +
# git, fires every time you `git commit`. Re-run safe — produces identical
# output for identical input.
#
# Apple-native: bash 3.2 (macOS default) + Python 3 stdlib + git. No deps.
#
# Bypass (rare; e.g. mid-rebase): git commit --no-verify
set -e
REPO_ROOT="$(git rev-parse --show-toplevel)"
cd "$REPO_ROOT"
# ─── secret scan, BEFORE anything else ────────────────────────────────────────
# Runs first on purpose: if the commit is going to be refused, refuse it before
# spending time regenerating indexes. Blocks account ids, keys, tokens, cards,
# IBANs and masked account digits. Bypass, deliberately: git commit --no-verify
if [ -x "$REPO_ROOT/bin/secret-scan" ]; then
if ! "$REPO_ROOT/bin/secret-scan"; then
exit 1
fi
fi
# Only regen if Python is available — fail loudly if not.
if ! command -v python3 >/dev/null 2>&1; then
echo "pre-commit: python3 not found, skipping wiki regen" >&2
exit 0
fi
# Track which indexes changed so we know what to stage at the end.
CHANGED_FILES=()
regen() {
local script="$1"
local label="$2"
shift 2
local watched=("$@")
# Snapshot mtimes of watched files BEFORE running the regenerator.
local before_state
before_state=$(stat -f "%N %m" "${watched[@]}" 2>/dev/null || true)
if ! python3 "$script" >/dev/null 2>&1; then
echo "pre-commit: $label failed (continuing)" >&2
return
fi
local after_state
after_state=$(stat -f "%N %m" "${watched[@]}" 2>/dev/null || true)
if [ "$before_state" != "$after_state" ]; then
CHANGED_FILES+=("${watched[@]}")
echo "pre-commit: regen $label → updated" >&2
fi
}
regen bin/wiki-index.py "wiki INDEX" wiki/INDEX.md
regen bin/gen-skill-indexes.py "skill indexes" \
bin/INDEX.md \
scripts/workflows/INDEX.md \
dictionaries/INDEX.md \
wiki/compiled/EXPORTERS.md
# AppleBar feature index — consolidated from features/*.feature (via `convey read`)
# + shared/intents.json. Auto-generated; never hand-edited.
regen bin/gen-features-index.py "features INDEX" features/INDEX.md
# Stage any updated indexes into the in-flight commit.
if [ ${#CHANGED_FILES[@]} -gt 0 ]; then
git add -- "${CHANGED_FILES[@]}"
fi
# Convey atlas — the principle board (atlas/INDEX.md), built from principles/.
# Tolerant: only if the convey CLI + principles/ are present. Same zero-token idea.
if [ -x bin/convey ] && [ -d principles ]; then
atlas_before=$(stat -f "%m" atlas/INDEX.md 2>/dev/null || echo 0)
if ./bin/convey atlas >/dev/null 2>&1; then
atlas_after=$(stat -f "%m" atlas/INDEX.md 2>/dev/null || echo 0)
if [ "$atlas_before" != "$atlas_after" ]; then
git add atlas/INDEX.md
echo "pre-commit: regen convey atlas → updated" >&2
fi
fi
fi
# gen-docs.py writes a variable number of files under docs/, so we can't
# enumerate the watch list. Snapshot the whole docs/ dir state instead.
if [ -d docs ] && [ -x bin/gen-docs.py ]; then
docs_before=$(find docs -type f -name "*.md" -exec stat -f "%N %m" {} \; 2>/dev/null | sort)
if python3 bin/gen-docs.py >/dev/null 2>&1; then
docs_after=$(find docs -type f -name "*.md" -exec stat -f "%N %m" {} \; 2>/dev/null | sort)
if [ "$docs_before" != "$docs_after" ]; then
git add docs/
echo "pre-commit: regen docs/ (wiki→Jekyll mirror) → updated" >&2
fi
else
echo "pre-commit: gen-docs failed (continuing)" >&2
fi
fi
# wiki-lint: warnings only, never blocks. Surface to stderr so you see them.
if [ -f bin/wiki-lint.py ]; then
python3 bin/wiki-lint.py 2>&1 | grep -E "WARN|orphan|oversized|broken" >&2 || true
fi
exit 0