no-issue-refs-in-comments: научить //-комментариям и снять types: [python]; todo-needs-issue: строгий TODO(#N) #8

Closed
opened 2026-08-25 23:59:40 +07:00 by claude-secretary · 1 comment

Решение volody 25.08.2026: check-file-length, todo-needs-issue и no-issue-refs-in-commentsобщий канон для всех репо homedevlab, включая TS-репо (jamzap/frontend, jamzap/mobile). Сегодня третий хук туда не переносится, и это чинится здесь, а не в конфигах потребителей.

1. no-issue-refs-in-comments — python-only дважды

Определение хука (.pre-commit-hooks.yaml) несёт types: [python]. Потребитель на TS может это переопределить (types: [file]), но упрётся во второе:

Реализация (scripts/check_no_issue_refs_in_comments.py, extract_comment) считает комментарием только то, что начинается с #. В .ts/.tsx комментарии — // и /* */, поэтому функция не найдёт ни одного комментария и хук молча пройдёт. Это хуже отсутствия хука: конфиг заявляет гейт, которого нет.

Что сделать:

  • снять types: [python] из определения — скоуп задаёт потребитель через files:, как уже сделано у no-broken-repo-paths и no-session-marks-in-code;
  • научить extract_comment распознавать // и блочные /* */ наряду с #; выбор синтаксиса — по расширению файла, а не «всё сразу»: # в .ts встречается в приватных полях классов (#field) и дал бы ложные срабатывания, а // в .py не комментарий вовсе;
  • строковые литералы по-прежнему не считать комментарием (сейчас это делает посимвольный проход с учётом кавычек — для /* */ понадобится отдельная ветка);
  • .md в скоуп не тащить: там # — заголовок. Ограничение задаёт потребитель, но стоит упомянуть в description хука.

Образец правильного устройства — no-broken-repo-paths: в .py сканирует COMMENT/STRING-токены, в прочих файлах идёт построчно.

2. todo-needs-issue — regex принимает префиксы

Сейчас: TODO\b(?!\s*\([^)]*#\d+[^)]*\)). Внутренний [^)]* разрешает что угодно перед номером, поэтому TODO(jamzap/backend#402) проходит наравне с TODO(#402).

Принятый формат — строго TODO(#123), голый номер: TODO живёт внутри своего репо, кросс-проектных не заводим. Regex ужесточить до варианта, который принимает только TODO(#N)TODO(#N, #M), если множественные ссылки нужны), а прочее содержимое скобок отвергает.

Осторожно с обратной совместимостью: у потребителей уже есть TODO с префиксами — в jamzap/mobile их около десятка. Ужесточение сделает их красными на следующем касании файла, что и требуется, но потребителей нужно предупредить в CHANGELOG.

3. Релиз

Обе правки — в один тег (v0.11.0), потребители поднимут rev:. Потребители, которые ждут именно этого: jamzap/frontend#229 и jamzap/mobile#124 (там канон включается после выхода тега). jamzap/backend#464, jamzap/infra#225 и volody/dispatcher#180 работают и на v0.10.0 — эти репозитории python/shell'овые.

Решение volody 25.08.2026: `check-file-length`, `todo-needs-issue` и `no-issue-refs-in-comments` — **общий канон для всех репо** homedevlab, включая TS-репо (jamzap/frontend, jamzap/mobile). Сегодня третий хук туда не переносится, и это чинится здесь, а не в конфигах потребителей. ## 1. `no-issue-refs-in-comments` — python-only дважды **Определение хука** (`.pre-commit-hooks.yaml`) несёт `types: [python]`. Потребитель на TS может это переопределить (`types: [file]`), но упрётся во второе: **Реализация** (`scripts/check_no_issue_refs_in_comments.py`, `extract_comment`) считает комментарием только то, что начинается с `#`. В `.ts`/`.tsx` комментарии — `//` и `/* */`, поэтому функция не найдёт ни одного комментария и хук **молча пройдёт**. Это хуже отсутствия хука: конфиг заявляет гейт, которого нет. Что сделать: - снять `types: [python]` из определения — скоуп задаёт потребитель через `files:`, как уже сделано у `no-broken-repo-paths` и `no-session-marks-in-code`; - научить `extract_comment` распознавать `//` и блочные `/* */` наряду с `#`; выбор синтаксиса — по расширению файла, а не «всё сразу»: `#` в `.ts` встречается в приватных полях классов (`#field`) и дал бы ложные срабатывания, а `//` в `.py` не комментарий вовсе; - строковые литералы по-прежнему не считать комментарием (сейчас это делает посимвольный проход с учётом кавычек — для `/* */` понадобится отдельная ветка); - `.md` в скоуп не тащить: там `#` — заголовок. Ограничение задаёт потребитель, но стоит упомянуть в `description` хука. Образец правильного устройства — `no-broken-repo-paths`: в `.py` сканирует COMMENT/STRING-токены, в прочих файлах идёт построчно. ## 2. `todo-needs-issue` — regex принимает префиксы Сейчас: `TODO\b(?!\s*\([^)]*#\d+[^)]*\))`. Внутренний `[^)]*` разрешает что угодно перед номером, поэтому `TODO(jamzap/backend#402)` проходит наравне с `TODO(#402)`. Принятый формат — **строго `TODO(#123)`**, голый номер: TODO живёт внутри своего репо, кросс-проектных не заводим. Regex ужесточить до варианта, который принимает только `TODO(#N)` (и `TODO(#N, #M)`, если множественные ссылки нужны), а прочее содержимое скобок отвергает. Осторожно с обратной совместимостью: у потребителей уже есть TODO с префиксами — в jamzap/mobile их около десятка. Ужесточение сделает их красными на следующем касании файла, что и требуется, но потребителей нужно предупредить в CHANGELOG. ## 3. Релиз Обе правки — в один тег (`v0.11.0`), потребители поднимут `rev:`. Потребители, которые ждут именно этого: jamzap/frontend#229 и jamzap/mobile#124 (там канон включается после выхода тега). jamzap/backend#464, jamzap/infra#225 и volody/dispatcher#180 работают и на `v0.10.0` — эти репозитории python/shell'овые.
Author
Owner

Вышло в v0.11.0 (PR #10, коммит 3530435).

no-issue-refs-in-comments — снят types: [python], синтаксис комментария выбирается по расширению: // и /* */ для C-подобных, # для остальных. Выбор по расширению, а не «все сразу», намеренный: в .ts символ # начинает приватное поле класса. Строковые литералы, включая шаблонные, комментарием не считаются; блочный комментарий переносит состояние между строками.

.css/.scss/.less в список не включены, хотя в задаче упоминались C-подобные вообще: hex-цвет в комментарии (// раньше был #336699) неотличим от ссылки на задачу, и это завело бы новый класс ложных срабатываний.

todo-needs-issue — формат строгий: TODO(#N), несколько ссылок через запятую. Исключение для TODO внутри no-issue-refs-in-comments сужено до того же формата, чтобы оба хука говорили о префиксе одно и то же.

Оговорка: кросс-проектную форму TODO(ns/proj#N) сам no-issue-refs-in-comments не ловит — там #N стоит вплотную к букве и под #NNN не подпадает. Расширять ISSUE_REF_RE не стал, это потянуло бы ложные срабатывания на URL-фрагментах; формат ловит todo-needs-issue.

Остаточные ограничения разбора комментариев (многострочный шаблонный литерал, второй комментарий в строке, апостроф в JSX, непокрытая обработка строковых литералов) вынесены в #11 — чинить их стоит переиспользованием машины состояний из no-broken-repo-paths, а не заплатами по одной.

Потребителям. Обновление rev: покрасит TODO с префиксами на первом же касании файла, а хук no-issue-refs-in-comments, прописанный без files:, расширится за пределы python. Это ожидаемо; в README дописана оговорка, что в 0.x ломающие правки едут в minor и обновлять rev: стоит отдельным PR.

✅ Вышло в `v0.11.0` (PR #10, коммит `3530435`). **`no-issue-refs-in-comments`** — снят `types: [python]`, синтаксис комментария выбирается по расширению: `//` и `/* */` для C-подобных, `#` для остальных. Выбор по расширению, а не «все сразу», намеренный: в `.ts` символ `#` начинает приватное поле класса. Строковые литералы, включая шаблонные, комментарием не считаются; блочный комментарий переносит состояние между строками. `.css/.scss/.less` в список **не** включены, хотя в задаче упоминались C-подобные вообще: hex-цвет в комментарии (`// раньше был #336699`) неотличим от ссылки на задачу, и это завело бы новый класс ложных срабатываний. **`todo-needs-issue`** — формат строгий: `TODO(#N)`, несколько ссылок через запятую. Исключение для TODO внутри `no-issue-refs-in-comments` сужено до того же формата, чтобы оба хука говорили о префиксе одно и то же. Оговорка: кросс-проектную форму `TODO(ns/proj#N)` сам `no-issue-refs-in-comments` не ловит — там `#N` стоит вплотную к букве и под `#NNN` не подпадает. Расширять `ISSUE_REF_RE` не стал, это потянуло бы ложные срабатывания на URL-фрагментах; формат ловит `todo-needs-issue`. **Остаточные ограничения разбора комментариев** (многострочный шаблонный литерал, второй комментарий в строке, апостроф в JSX, непокрытая обработка строковых литералов) вынесены в #11 — чинить их стоит переиспользованием машины состояний из `no-broken-repo-paths`, а не заплатами по одной. **Потребителям.** Обновление `rev:` покрасит TODO с префиксами на первом же касании файла, а хук `no-issue-refs-in-comments`, прописанный без `files:`, расширится за пределы python. Это ожидаемо; в README дописана оговорка, что в `0.x` ломающие правки едут в minor и обновлять `rev:` стоит отдельным PR.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
senokosov/pre-commit-hooks#8
No description provided.