Files
dev-skills/lefthook.yml
T
av eae734f5cc гейт: добавлена проверка ссылок и номеров журнала решений
- `decisions.py` судит четыре вещи: уникальность номеров Т/Р/С, раскладку тем,
  указатель и ссылки — цель существует, подпись называет именно её;
- проверка идёт без glob, как адреса: файл темы и ссылки на него лежат порознь,
  и переименование темы трогает только одну сторону, а ломает обе;
- ссылка внутри блока кода ссылкой не считается — в скелетах канона она
  адресована дереву проекта.
2026-08-13 12:41:13 +03:00

74 lines
5.5 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Гейт коммита: всё, что в этом репозитории проверяется машиной.
#
# Документы — то, что читает не человек, а машина, и чья поломка **не видна при
# чтении**: фронтматтер (его разбирает загрузчик скиллов), помеченная копия
# правила (расходится молча) и диаграмма mermaid (текст правдоподобен, рендер
# падает). Скрипты — ruff и pyrefly: они же стерегут ноль внешних зависимостей,
# без которого tasks.py и docs.py перестают работать в чужом проекте.
# Всё остальное (проза, устройство, язык) — предмет ревью, а не хука.
#
# **Что судится — staged-файлы, а не рабочее дерево**, всюду, где проверка
# умеет смотреть поимённо: гейт обязан судить то, что уедет в историю, а не то,
# что случайно лежит на диске рядом. Три исключения названы у своих задач, и все
# — про то, что проверке нужен весь репозиторий по существу, а не для удобства.
#
# Ставится `lefthook install` (см. README, «Гейт коммита»). Обойти разово —
# `LEFTHOOK=0 git commit …`; обход законен ровно для того случая, когда чинить
# найденное нечем прямо сейчас.
pre-commit:
parallel: true
jobs:
# Обе проверки документов идут по всему репозиторию, и это не недосмотр.
# copies.py сверяет копию с домом, а дом лежит в другом файле, которого в
# индексе может не быть: список staged дал бы «копии дословны» там, где
# правка дома их и разошлась. frontmatter.py смотрел бы поимённо, но весь
# обход стоит сотые доли секунды — платить за него нечем. Glob у него шире
# на `*.json`: тем же проходом сверяется `description` плагина в
# `plugin.json` с записью того же плагина в `marketplace.json`, а коммит,
# правящий только манифест, по глобу `*.md` проверку бы не разбудил.
- name: фронтматтеры
glob: "*.{md,json}"
run: python3 scripts/frontmatter.py
- name: копии правил
glob: "*.md"
run: python3 scripts/copies.py
# Без glob намеренно, и это третье исключение из правила «судим staged».
# Проверка сводит две стороны: перечень адресов лежит в константе скрипта
# владельца (`.py`), упоминания — в прозе плагинов (`.md`). Коммит, где
# переименован документ канона, трогает только первую сторону: по глобу
# `*.md` он бы проверку не разбудил, а расходится в нём именно вторая.
# Весь обход — семь сотых секунды.
- name: адреса документов
run: python3 scripts/addresses.py
# Тоже без glob, и по той же причине, что у адресов: проверка сводит две
# стороны — файл темы и ссылку на него. Коммит, переименовавший тему или
# тронувший только `decisions/`, ломает ссылки в README и TODO, которых в
# индексе нет. Номера при этом сверяются на уникальность: буквенные метки
# решений уже разъезжались молча — `АЕАКЛ` была занята дважды.
- name: журнал решений
run: python3 scripts/decisions.py
# Самая дорогая проверка: каждый блок — свой запуск mermaid-cli со своим
# chromium. Отсюда и staged-файлы вместо обхода, и параллель внутри самого
# скрипта: репозиторий целиком — 3 секунды, один файл — одна.
- name: диаграммы
glob: "*.md"
run: python3 scripts/diagrams.py {staged_files}
# Линтеры — через uv: версии прибиты точно, и `uv run` берёт именно их, а не
# то, что оказалось в PATH. `--fix` чинит безопасное сам, `stage_fixed`
# доносит починку до этого же коммита — иначе она осталась бы в рабочем
# дереве, а в историю уехал бы невычищенный файл.
- name: ruff
glob: "*.py"
stage_fixed: true
run: uv run ruff check --fix {staged_files}
- name: pyrefly
glob: "*.py"
run: uv run pyrefly check {staged_files}