docs: сняты проверки над проверками
- Из «Любой узел» в review.md убраны три свойства о годности самих проверок: мутация теста, мутация оракула критерия, требование без сценария. - Из go-linters.md снята «Лестница механизации», ссылки на неё переписаны в конвенциях, их индексе и журнале дефектов.
This commit is contained in:
@@ -48,10 +48,9 @@ htmx, а здесь решено делать SPA — и перенесённы
|
|||||||
- [web-ui.md](web-ui.md) — веб-UI: Vue 3 с Vite и статикой в бинарнике,
|
- [web-ui.md](web-ui.md) — веб-UI: Vue 3 с Vite и статикой в бинарнике,
|
||||||
однофайловые компоненты, таблица маршрутов, состояние в экране, одна обёртка
|
однофайловые компоненты, таблица маршрутов, состояние в экране, одна обёртка
|
||||||
над `fetch`, показ ошибок и состояний списка.
|
над `fetch`, показ ошибок и состояний списка.
|
||||||
- [go-linters.md](go-linters.md) — линтеры и механизированные проверки: лестница
|
- [go-linters.md](go-linters.md) — линтеры и механизированные проверки: два круга
|
||||||
механизации, два круга (pre-commit и гейт), перечень правил и подавлений,
|
(pre-commit и гейт), перечень правил и подавлений, порядок заведения нового
|
||||||
порядок заведения нового правила. Про инструменты, а не про то, как писать
|
правила. Про инструменты, а не про то, как писать тесты.
|
||||||
тесты.
|
|
||||||
|
|
||||||
## Что из этого проверяет машина
|
## Что из этого проверяет машина
|
||||||
|
|
||||||
|
|||||||
@@ -15,11 +15,11 @@
|
|||||||
исходники.
|
исходники.
|
||||||
|
|
||||||
Пока язык у проекта один, и запись названа по нему. Появится второй — у него
|
Пока язык у проекта один, и запись названа по нему. Появится второй — у него
|
||||||
будет своя запись, а лестница и два круга останутся общими.
|
будет своя запись, а два круга останутся общими.
|
||||||
|
|
||||||
Устройство ниже **переносимо**: разделы «Лестница механизации», «Два круга» и
|
Устройство ниже **переносимо**: разделы «Два круга» и «Как заводят новое
|
||||||
«Как заводят новое правило» — не особенность transcriber и переносятся в другой
|
правило» — не особенность transcriber и переносятся в другой Go-проект как есть.
|
||||||
Go-проект как есть. Своё здесь — перечень правил и подавлений.
|
Своё здесь — перечень правил и подавлений.
|
||||||
|
|
||||||
## Границы: где что живёт
|
## Границы: где что живёт
|
||||||
|
|
||||||
@@ -48,37 +48,6 @@ Go-проект как есть. Своё здесь — перечень пра
|
|||||||
механики и мало пользы. Долгом это больше не числится — задача
|
механики и мало пользы. Долгом это больше не числится — задача
|
||||||
`migrations-step-norm-and-tests` закрыта без реализации.
|
`migrations-step-norm-and-tests` закрыта без реализации.
|
||||||
|
|
||||||
## Лестница механизации
|
|
||||||
|
|
||||||
Свойство поднимается по ступеням, и ступень выбирают не по вкусу, а по тому,
|
|
||||||
чем свойство выражается. Верхняя ступень дешевле нижней в эксплуатации и дороже
|
|
||||||
в заведении, поэтому прыгать через ступень без нужды не надо.
|
|
||||||
|
|
||||||
1. **Проза конвенции.** Свойство названо словами, проверяет человек на каждом
|
|
||||||
ревью заново. Это ступень по умолчанию и худшая из всех: она стоит внимания
|
|
||||||
каждого прогона и молча перестаёт работать, когда внимание кончилось.
|
|
||||||
2. **Настройка готового линтера.** Свойство совпало с чужим правилом —
|
|
||||||
включается строкой в `.golangci.yml`. Дешевле всего; ограничение в том, что
|
|
||||||
правило чужое и говорит о том, о чём его написали.
|
|
||||||
3. **Запрет по имени** (`forbidigo`, `depguard`). Свойство выражается через «эту
|
|
||||||
функцию/пакет тут звать нельзя». Дешёво и точно, но требует **единой точки**,
|
|
||||||
куда запрещённое переносят: запрет без дома оставляет код без способа сделать
|
|
||||||
нужное.
|
|
||||||
4. **Тест-сканер исходников** (`internal/archrules`). Свойство — о структуре, а
|
|
||||||
не о вызове: направление зависимостей, согласованность двух перечней,
|
|
||||||
отсутствие идиомы. Пишется руками на `go/parser` или регулярном выражении,
|
|
||||||
зато читается как тест и ломается заметно.
|
|
||||||
5. **Свой шаг проверки** (`scripts/`, шаги `Taskfile.yml`). Свойство выходит за
|
|
||||||
пределы кода на Go: версия инструмента, форма `Dockerfile`, раскладка
|
|
||||||
документов. Дороже всех — у шага появляется своя норма и свои тесты.
|
|
||||||
|
|
||||||
Ступень, выбранная неверно, видна сразу. Запрет по имени, обходимый одной
|
|
||||||
лишней строкой, — на деле правило четвёртой ступени, оформленное как правило
|
|
||||||
третьей: так было с правилом о
|
|
||||||
заголовках ответа, которое сначала запретило текст `\.Header\(\)\.Get`, а
|
|
||||||
обходилось присваиванием в переменную. Правило переписано на суждение **по типу
|
|
||||||
приёмника** (`analyze-types`), и это уже настоящая третья ступень.
|
|
||||||
|
|
||||||
## Два круга: pre-commit и гейт
|
## Два круга: pre-commit и гейт
|
||||||
|
|
||||||
Проверки идут двумя кругами, и круг выбирается по цене прогона.
|
Проверки идут двумя кругами, и круг выбирается по цене прогона.
|
||||||
@@ -199,8 +168,8 @@ Go-проект как есть. Своё здесь — перечень пра
|
|||||||
остаётся то, чему нет ни готового правила, ни детерминированного оракула:
|
остаётся то, чему нет ни готового правила, ни детерминированного оракула:
|
||||||
уровень лога по адресату, единая логирующая точка на доменной границе, словарь
|
уровень лога по адресату, единая логирующая точка на доменной границе, словарь
|
||||||
имён полей, канонический вид идентификатора, естественные ключи у деталей.
|
имён полей, канонический вид идентификатора, естественные ключи у деталей.
|
||||||
Свойство, оставшееся прозой, проверяет человек на каждом ревью заново — это и
|
Свойство, оставшееся прозой, проверяет человек на каждом ревью заново, и правило,
|
||||||
есть первая ступень лестницы, и подъём с неё всегда выигрыш.
|
снявшее с него эту работу, всегда выигрыш.
|
||||||
|
|
||||||
Названы поимённо и **остатки правил** — то, что правило не ловит и потому
|
Названы поимённо и **остатки правил** — то, что правило не ловит и потому
|
||||||
осталось человеку:
|
осталось человеку:
|
||||||
@@ -242,8 +211,9 @@ Go-проект как есть. Своё здесь — перечень пра
|
|||||||
|
|
||||||
Порядок один и тот же, и последние два шага пропускать нельзя.
|
Порядок один и тот же, и последние два шага пропускать нельзя.
|
||||||
|
|
||||||
1. **Найти дом.** Ступень лестницы выбирается по тому, чем свойство
|
1. **Найти дом.** Дом выбирается по тому, чем свойство выражается, а не по тому,
|
||||||
выражается, а не по тому, что проще включить.
|
что проще включить: настройка готового линтера, запрет по имени, тест-сканер
|
||||||
|
исходников или свой шаг набора проверок.
|
||||||
2. **Написать причину рядом.** Правило без причины снимают при первом же
|
2. **Написать причину рядом.** Правило без причины снимают при первом же
|
||||||
неудобстве: тот, кто снимает, не знает, что оно ловило.
|
неудобстве: тот, кто снимает, не знает, что оно ловило.
|
||||||
3. **Починить находки, а не подавить.** Подавление годится, когда правило
|
3. **Починить находки, а не подавить.** Подавление годится, когда правило
|
||||||
|
|||||||
+9
-20
@@ -69,22 +69,11 @@
|
|||||||
|
|
||||||
- изменённое место покрыто хоть одним **проходящим** тестом. Тест, который
|
- изменённое место покрыто хоть одним **проходящим** тестом. Тест, который
|
||||||
никогда не был зелёным, обнуляет сигнал всего пакета: настоящий отказ в нём
|
никогда не был зелёным, обнуляет сигнал всего пакета: настоящий отказ в нём
|
||||||
становится неотличим от привычного шума (журнал, запись 2026-08-10);
|
становится неотличим от привычного шума (журнал, запись 2026-08-10).
|
||||||
- проверка **способна упасть**. Утверждение, разбирающее ответ в ту же
|
|
||||||
структуру, чьи теги и составляют проверяемый контракт, меняется вместе с ним
|
Свойств о годности самих проверок здесь больше нет: требования мутировать тест,
|
||||||
и никогда не ловит поломку; такое судят по сырому виду ответа. Признак ищется
|
оракул критерия приёмки и норму сняты 2026-08-13 решением владельца — проверка
|
||||||
мутацией: сломай проверяемое свойство и убедись, что тест краснеет (журнал,
|
над проверкой стоит внимания каждого прогона и отвечает редко.
|
||||||
запись 2026-08-11);
|
|
||||||
- **то же и об оракуле критерия приёмки, не только о тесте.** Критерий, чей
|
|
||||||
единственный оракул — молчание линтера, годится ровно тогда, когда линтер
|
|
||||||
краснеет на **всех** негодных реализациях; проверяется той же мутацией.
|
|
||||||
Прецедент: «отказ `Close` не теряется молча» принимался молчанием `errcheck`,
|
|
||||||
а тот пропускал `_ = conn.Close()` — реализацию, теряющую отказ целиком
|
|
||||||
(журнал, запись 2026-08-11 про недостижимую норму; закрыто
|
|
||||||
[решением](adr/ADR-2026-08-11-errcheck-check-blank.md));
|
|
||||||
- **требование без сценария не имеет оракула** и потому не может быть нарушено
|
|
||||||
заметно. Норма, которую нечем уронить, расходится с кодом молча — и расходится
|
|
||||||
тем вернее, чем убедительнее написана (журнал, запись 2026-08-11).
|
|
||||||
|
|
||||||
### Типовые ложноположительные
|
### Типовые ложноположительные
|
||||||
|
|
||||||
@@ -357,10 +346,10 @@ API и имя не откатываются обратной правкой по
|
|||||||
которого писали. Мутация была, но одна — нужна была по одной на каждую форму
|
которого писали. Мутация была, но одна — нужна была по одной на каждую форму
|
||||||
- **Что меняем:** правило судит по типу приёмника (`analyze-types`,
|
- **Что меняем:** правило судит по типу приёмника (`analyze-types`,
|
||||||
`httptest.ResponseRecorder.Header` и `.HeaderMap`) и ловит все шесть форм;
|
`httptest.ResponseRecorder.Header` и `.HeaderMap`) и ловит все шесть форм;
|
||||||
проверено мутацией по каждой. Отсюда же строка в
|
проверено мутацией по каждой. Урок записи: запрет по имени, обходимый лишней
|
||||||
docs/conventions/go-linters.md, «Лестница механизации»: запрет по имени,
|
строкой, свойства не держит — такому свойству нужен тест-сканер. Строка об этом
|
||||||
обходимый лишней строкой, требует ступени тест-сканера, хотя выглядит запретом
|
стояла в `docs/conventions/go-linters.md`, разделе «Лестница механизации»;
|
||||||
по имени
|
раздел снят 2026-08-13, урок остался здесь
|
||||||
|
|
||||||
## 2026-08-12 — закрыли поверхность так, что войти не мог никто [пойман ревью]
|
## 2026-08-12 — закрыли поверхность так, что войти не мог никто [пойман ревью]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user