chore: add new lint rule - check hardcoded text

This commit is contained in:
2026-09-26 21:23:50 +05:00
parent 7bca9f3a3a
commit b59a434c65
9 changed files with 454 additions and 24 deletions
+3 -3
View File
@@ -57,9 +57,9 @@
- production registry содержит 122 инструмента;
- `pnpm --dir web check` проходит без ошибок и предупреждений;
- `pnpm --dir web test` — 45 test files / 497 tests, включая тесты token audit и
PostCSS HCT-плагина;
- `pnpm --dir web test:rules` — 4 test files / 74 tests;
- `pnpm --dir web test` — 46 test files / 534 tests, включая тесты token audit,
PostCSS HCT-плагина и правил линтинга;
- `pnpm --dir web test:rules` — 5 test files / 104 tests;
- `pnpm --dir web lint:all` — 0 errors, 0 i18n warnings и 0 unused design tokens
от token audit;
- coverage `src/lib` — statements 91.77%, branches 83.3%, functions 74.31%,
+32 -16
View File
@@ -476,9 +476,38 @@ file-result-инструментам.
### Q8. Новые автоматические правила
**Оценка:** L. **Зависимости:** Q4, Q7.
**Оценка:** L. **Зависимости:** Q4, Q7. **Разбивка:** три атомарных шага, каждый
заканчивается либо работающим warn-правилом с нулевым baseline, либо измерением
с записью вывода. Механически важно: `lint-all` запускает ESLint с
`--max-warnings=0`, поэтому warn-правило обязано приземлиться без срабатываний
на текущем коде.
#### Дублирование HTML/Svelte-разметки
#### Q8.1. Пользовательские тексты вне i18n
**Статус:** выполнен. Пилот `i18n/no-hardcoded-user-text` (warn) с нулевым
baseline; 2 реальных нарушения исправлены.
- Измерение до правила: 42 строковых атрибута пользовательского текста, все — в
`/kit`; вне кита текстовые узлы дали 2 находки. Итог после исключений: 2
настоящих бага и 2 бренда, которые план требовал исключить.
- `web/eslint-plugins/i18n/no-hardcoded-user-text.js`: узлы `SvelteText` плюс
строковые литералы пользовательских атрибутов; `<style>`/`<script>`
пропускаются.
- Исключения из плана реализованы списками, а не эвристиками: форматы/единицы/
имена файлов/версии/размеры, ALL CAPS идентификаторы (registry source
strings), `/kit` через scope, бренд через опцию `allowWords` (в конфиге, а не
в коде правила).
- Исправлены 2 бага: `ColorPairControl.svelte` показывал английские `From`/`To`.
Ключи `ui.from`/`ui.to` уже существовали в обоих словарях — компонент их
просто не использовал, поэтому новые ключи не понадобились.
- 30 тестов в `__tests__/no-hardcoded-user-text.test.ts`; мутацией проверено,
что правило не декоративное: с пустым `allowWords` бренд начинает репортиться.
- Известные слепые зоны, зафиксированные как границы пилота: текст, собранный в
скрипте и переданный выражением, и текст вне Svelte-шаблонов (например, в
атрибутах, приходящих из registry). Расширение поверхности — отдельная работа,
а не молчаливое расширение правила.
#### Q8.2. Дублирование HTML/Svelte-разметки
Сначала провести report-only аудит новых `components/**` и `routes/**`.
Определить:
@@ -490,20 +519,7 @@ file-result-инструментам.
Только после оценки false positives выбирать между готовым detector и
собственным AST-правилом. Не включать detector в blocking gate сразу.
#### Пользовательские тексты вне i18n
Сделать warn-only пилот с исключениями для:
- бренда и версии;
- форматов и имён файлов;
- `X`/`Y` и технических значений;
- registry source strings;
- `/kit`;
- тестовых данных и внутренних сообщений.
Blanket-запрет всех string literals не использовать.
#### Согласованность комментариев
#### Q8.3. Согласованность комментариев
Автоматический lint не делать. Это review/process policy: комментарий должен
объяснять причину исключения, а `TODO`/`FIXME` — ссылаться на backlog или issue