54 lines
3.4 KiB
Bash
Executable file
54 lines
3.4 KiB
Bash
Executable file
#!/bin/sh
|
||
# Зонный pre-commit фрагмент docs/. Запускается тем же диспетчером .git/hooks/pre-commit,
|
||
# что и фрагмент фронта (он перебирает */scripts/githooks/pre-commit).
|
||
#
|
||
# Зачем: за одну сессию №15 четыре из десяти рукописных копий производных чисел разошлись с
|
||
# источником, а голова CURRENT-STATE отставала ТРЕТИЙ раз в истории проекта — у трёх разных
|
||
# оркестраторов (D39.81, D39.83, D39.112 п.5б). Одна и та же ошибка у независимых сессий на одном
|
||
# поле — свойство поля, а не сессий, поэтому проверка механическая, а не нормой прозой.
|
||
#
|
||
# ⚠ ПРЕДУПРЕЖДАЕТ, НЕ БЛОКИРУЕТ (решение оркестратора №15, 07.08): фрагмент лежит в общем
|
||
# диспетчере и сработает на коммите ЛЮБОЙ сессии, включая те, которым я не писал промт. Жёсткий
|
||
# гейт, останавливающий чужой коммит, ставится только словом владельца. Обход, если понадобится:
|
||
# git commit --no-verify.
|
||
|
||
staged=$(git diff --cached --name-only)
|
||
[ -z "$staged" ] && exit 0
|
||
|
||
dlog='docs/architecture/05-decisions-log.md'
|
||
prog='docs/PROGRESS.md'
|
||
|
||
printf '%s\n' "$staged" | grep -qE "^($dlog|$prog)$" || exit 0
|
||
|
||
# Содержимое ПОСЛЕ коммита: для застейдженного файла это индекс, для нетронутого — HEAD.
|
||
after() {
|
||
if printf '%s\n' "$staged" | grep -qx "$1"; then git show ":$1" 2>/dev/null; else git show "HEAD:$1" 2>/dev/null; fi
|
||
}
|
||
|
||
note=$(after "$dlog" | grep -oE '^## D39\.[0-9]+' | tail -1 | sed 's/^## //')
|
||
banner=$(after "$dlog" | head -1 | grep -oE 'D1–D39\.[0-9]+' | sed 's/^D1–//')
|
||
claimed=$(after "$prog" | head -6 | grep -oE 'голова D39\.[0-9]+' | head -1 | sed 's/^голова //')
|
||
|
||
warn=0
|
||
if [ -n "$note" ] && [ -n "$claimed" ] && [ "$note" != "$claimed" ]; then
|
||
echo "pre-commit ⚠ docs: голова разошлась — последняя нота D-лога $note, CURRENT-STATE говорит $claimed." >&2
|
||
echo " Норма промта оркестратора: голова бампается при КАЖДОМ аппенде ноты, в том же коммите." >&2
|
||
warn=1
|
||
fi
|
||
if [ -n "$note" ] && [ -n "$banner" ] && [ "$note" != "$banner" ]; then
|
||
echo "pre-commit ⚠ docs: шапка-диапазон D-лога $banner при последней ноте $note." >&2
|
||
warn=1
|
||
fi
|
||
|
||
# Производные числа доков — сверка пере-счётом (docs/scripts/counts.py). Считает по РАБОЧЕМУ
|
||
# дереву: при частичном стейдже это advisory, а не приговор.
|
||
if command -v python3 >/dev/null 2>&1 && [ -f docs/scripts/counts.py ]; then
|
||
out=$(python3 docs/scripts/counts.py --check 2>&1) || {
|
||
echo "pre-commit ⚠ docs: литералы в доках разошлись с пере-счётом:" >&2
|
||
printf '%s\n' "$out" | grep '✗' >&2
|
||
warn=1
|
||
}
|
||
fi
|
||
|
||
[ "$warn" -eq 1 ] && echo "pre-commit: это ПРЕДУПРЕЖДЕНИЕ, коммит не остановлен." >&2
|
||
exit 0
|