67 lines
2.2 KiB
Bash
67 lines
2.2 KiB
Bash
#!/usr/bin/env bash
|
|
# CHECK -- commit-author census extract (Extract lane, ledger).
|
|
#
|
|
# Replays `git log --format=%an` from the committed tree and diffs the derived
|
|
# author->count map against the committed commits-by-author.tsv and
|
|
# commits-by-author.json. Exit code IS the verdict:
|
|
# 0 = PASS (replay matches committed files)
|
|
# nonzero = FAIL
|
|
#
|
|
# No || true / ; true / ; echo arms, no trailing prose: the exit code is the
|
|
# verdict and a prose gloss is a fault (tools/check_lint.py).
|
|
|
|
set -u
|
|
|
|
# Resolve the repo root from git so the check is location-independent.
|
|
REPO="$(git rev-parse --show-toplevel)" || exit 1
|
|
ART="$REPO/wizard-work/ledger/2026-10-29-commit-author-census"
|
|
cd "$ART" || exit 1
|
|
|
|
python3 - <<'PY'
|
|
import csv
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
|
|
out = subprocess.run(
|
|
["git", "log", "--format=%an"], capture_output=True, text=True, check=True
|
|
).stdout
|
|
counts = {}
|
|
for line in out.splitlines():
|
|
counts[line] = counts.get(line, 0) + 1
|
|
|
|
# Deterministic order: count desc, author asc (matches the committed TSV/JSON).
|
|
expected = sorted(counts.items(), key=lambda kv: (-kv[1], kv[0]))
|
|
|
|
with open("commits-by-author.tsv", encoding="utf-8") as fh:
|
|
tsv = list(csv.reader(fh, delimiter="\t"))
|
|
committed = [(r[0], int(r[1])) for r in tsv[1:]]
|
|
|
|
if len(expected) != len(committed):
|
|
print(f"FAIL: author count replay={len(expected)} committed={len(committed)}")
|
|
sys.exit(1)
|
|
for (a_exp, c_exp), (a_got, c_got) in zip(expected, committed):
|
|
if a_exp != a_got or c_exp != c_got:
|
|
print(f"FAIL: TSV author={a_exp}/{c_exp} got={a_got}/{c_got}")
|
|
sys.exit(1)
|
|
|
|
with open("commits-by-author.json", encoding="utf-8") as fh:
|
|
j = json.load(fh)
|
|
if j.get("total_commits") != sum(c for _, c in expected):
|
|
print("FAIL: JSON total_commits mismatch")
|
|
sys.exit(1)
|
|
if j.get("authors") != len(expected):
|
|
print("FAIL: JSON authors mismatch")
|
|
sys.exit(1)
|
|
for (a_exp, c_exp), gl in zip(expected, j["rows"]):
|
|
if (a_exp, c_exp) != (gl["author"], gl["commits"]):
|
|
print(f"FAIL: JSON row {a_exp}/{c_exp} got {gl['author']}/{gl['commits']}")
|
|
sys.exit(1)
|
|
|
|
print(
|
|
f"PASS: {len(expected)} authors, {sum(c for _, c in expected)} commits "
|
|
f"(replay == commits-by-author.tsv + .json)"
|
|
)
|
|
PY
|
|
exit $?
|