refactor(make): правки по холодному ревью реализации
- Зачем: - половина критерия приёмки стояла не там, где решено: предупреждение о ручном равенстве версий ruff адресовано тому, кто правит лок в generator/, а лежало в корневом Makefile. - довод «генератор — отдельная сущность» был выписан трижды почти дословно. - Что: - равенство версий и охват корневой цели названы в карте проверок; три примечания к таблице собраны списком. - названа цена занижения target-version: даги бегут на 3.13 и модернизаций не получают. - шапка generator/Makefile вырезана, корневая сжата до строки, объяснение в ruff.toml укорочено. - формулировки в AGENTS.md и README поправлены. - Проверка: - make lint; make config-test — зелёные. - make -C generator lint; typecheck — зелёные; исходники генератора не менялись. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -79,7 +79,8 @@ Airflow) и названия из кода. Если для понятия ес
|
|||||||
|
|
||||||
- Python — только через `uv`; проверка и формат — `ruff`. Цель `make lint`
|
- Python — только через `uv`; проверка и формат — `ruff`. Цель `make lint`
|
||||||
есть за двумя дверями и охватывает разное: в корне — код стенда, в
|
есть за двумя дверями и охватывает разное: в корне — код стенда, в
|
||||||
`generator/` — код генератора. Правишь одно — зови ту.
|
`generator/` — код генератора. Правишь даги или Superset — зови корневую,
|
||||||
|
правишь генератор — зови из `generator/`.
|
||||||
- Изменения держать минимальными и в границах задания.
|
- Изменения держать минимальными и в границах задания.
|
||||||
- Куда класть новую проверку, что утверждает каждая цель `make` и почему смоук
|
- Куда класть новую проверку, что утверждает каждая цель `make` и почему смоук
|
||||||
обязан оставаться быстрым — [`docs/architecture/testing.md`](docs/architecture/testing.md).
|
обязан оставаться быстрым — [`docs/architecture/testing.md`](docs/architecture/testing.md).
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ GENERATOR_DAY ?= 0
|
|||||||
GENERATOR_LIMIT ?=
|
GENERATOR_LIMIT ?=
|
||||||
GENERATOR_SPEED ?=
|
GENERATOR_SPEED ?=
|
||||||
|
|
||||||
# Цели корня — про стенд. Проверки генератора живут за своей дверью, в
|
# Цели корня — про стенд; проверки генератора — в `generator/Makefile`.
|
||||||
# `generator/Makefile`: генератор — отдельная и заменяемая сущность со своим
|
|
||||||
# `pyproject.toml`, локом и образом, и цели у него свои.
|
|
||||||
.PHONY: up down clean ps logs smoke check-clickhouse check-services config-test lint generate-batch generate-live
|
.PHONY: up down clean ps logs smoke check-clickhouse check-services config-test lint generate-batch generate-live
|
||||||
|
|
||||||
# --- Жизнь стенда ---
|
# --- Жизнь стенда ---
|
||||||
@@ -47,8 +45,7 @@ config-test:
|
|||||||
# Пути названы вслух: без них ruff из корня прошёлся бы и по генератору, а у
|
# Пути названы вслух: без них ruff из корня прошёлся бы и по генератору, а у
|
||||||
# того своя дверь и свой конфиг. Версия закреплена, потому что лока в корне
|
# того своя дверь и свой конфиг. Версия закреплена, потому что лока в корне
|
||||||
# нет, а форматтер между версиями меняет вывод — иначе проверка однажды
|
# нет, а форматтер между версиями меняет вывод — иначе проверка однажды
|
||||||
# покраснела бы сама, без единой правки в репозитории. Держать её равной той,
|
# покраснела бы сама, без единой правки в репозитории.
|
||||||
# что в `generator/uv.lock`, приходится руками: сверять их некому.
|
|
||||||
lint:
|
lint:
|
||||||
uvx ruff@0.16.1 check dags infra/superset
|
uvx ruff@0.16.1 check dags infra/superset
|
||||||
uvx ruff@0.16.1 format --check dags infra/superset
|
uvx ruff@0.16.1 format --check dags infra/superset
|
||||||
|
|||||||
@@ -141,10 +141,9 @@ ClickHouse, пока мир не доедет. Повторный `make up` за
|
|||||||
|
|
||||||
Спрашивают её двое. `make test` в `generator/` сверяет опись с тем, что
|
Спрашивают её двое. `make test` в `generator/` сверяет опись с тем, что
|
||||||
собирается из кода сегодня: правка генератора меняет мир, и опись надо
|
собирается из кода сегодня: правка генератора меняет мир, и опись надо
|
||||||
пересобрать — `make inventory` там же. `make check-clickhouse` в корне
|
пересобрать — `make inventory` там же. `make check-clickhouse` в корне сверяет
|
||||||
сверяет с описью то, что доехало до
|
с описью то, что доехало до `ods.event`, подневно. Хеш дня можно пересчитать и
|
||||||
`ods.event`, подневно. Хеш дня можно пересчитать и руками — это обычный
|
руками — это обычный `sha256sum` файла, который пишет файловый приёмник:
|
||||||
`sha256sum` файла, который пишет файловый приёмник:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uv run --project generator python -m clickstream_generator batch \
|
uv run --project generator python -m clickstream_generator batch \
|
||||||
|
|||||||
@@ -54,11 +54,18 @@
|
|||||||
генератора, генераторная — ни одного файла стенда. Человек в корне видит
|
генератора, генераторная — ни одного файла стенда. Человек в корне видит
|
||||||
зелёное и может решить, что зелёный весь репозиторий.
|
зелёное и может решить, что зелёный весь репозиторий.
|
||||||
|
|
||||||
Список правил у обеих один, а строгость нет: правила `UP` предлагают синтаксис
|
Три тонкости, которых не видно из таблицы:
|
||||||
настолько новый, насколько позволяет `target-version`, — у генератора это 3.14
|
|
||||||
из `requires-python`, у стенда 3.10, младшая из версий Python в его образах.
|
- **Список правил у дверей один, а строгость нет.** Правила `UP` предлагают
|
||||||
Один и тот же файл может пройти корневую проверку и не пройти генераторную.
|
синтаксис настолько новый, насколько позволяет `target-version`: у генератора
|
||||||
Довод и замер — в комментарии `ruff.toml`.
|
это 3.14 из `requires-python`, у стенда 3.10 — столько у Superset, младшего из
|
||||||
|
его образов. Один и тот же файл может пройти корневую проверку и не пройти
|
||||||
|
генераторную. Довод и замер — в комментарии `ruff.toml`.
|
||||||
|
- **Версия ruff у корневой цели закреплена в самом вызове** (`uvx ruff@0.16.1`)
|
||||||
|
и равна той, что в `generator/uv.lock`. Равенство держится руками: обновили
|
||||||
|
лок — поправьте и вызов, сверять их некому.
|
||||||
|
- **Охват держат аргументы вызова, а не устройство дерева.** Python,
|
||||||
|
положенный вне двух названных в таблице путей, не проверит ни одна из дверей.
|
||||||
|
|
||||||
**Корневого `typecheck` нет, и это решение, а не пропуск.** Проверке типов мало
|
**Корневого `typecheck` нет, и это решение, а не пропуск.** Проверке типов мало
|
||||||
прочитать файл: чтобы понять `from airflow.sdk import dag`, ей нужен
|
прочитать файл: чтобы понять `from airflow.sdk import dag`, ей нужен
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
# Цели генератора. Дверь у него своя, потому что своя и сущность: пакет с
|
|
||||||
# собственными `pyproject.toml`, `uv.lock` и образом, заменяемый целиком
|
|
||||||
# (спека генератора, раздел 1). Отсюда и короткие имена — каталог уже сказал,
|
|
||||||
# о ком речь, и суффикс `-generator` был бы вторым разом про то же.
|
|
||||||
.PHONY: lint typecheck test docs inventory
|
.PHONY: lint typecheck test docs inventory
|
||||||
|
|
||||||
# --- Проверки ---
|
# --- Проверки ---
|
||||||
|
|||||||
@@ -2,17 +2,17 @@
|
|||||||
# в `generator/pyproject.toml`: конфиг ruff ищется вверх по дереву от файла,
|
# в `generator/pyproject.toml`: конфиг ruff ищется вверх по дереву от файла,
|
||||||
# поэтому ближний к генератору выигрывает и этот его не подменяет.
|
# поэтому ближний к генератору выигрывает и этот его не подменяет.
|
||||||
#
|
#
|
||||||
# Здесь отдельный файл, а не `pyproject.toml`, потому что пакета в корне нет:
|
# Отдельный файл, а не `pyproject.toml`: пакета в корне нет и заводить его
|
||||||
# корневой `pyproject.toml` завёл бы в репозитории второй проект `uv` — с
|
# ради настройки линтера незачем.
|
||||||
# локом и окружением, — которого стенду не нужно.
|
|
||||||
|
|
||||||
# На каком Python побежит код, ruff сам не знает: у генератора он берёт ответ
|
# На каком Python побежит код, ruff сам не знает: у генератора он берёт ответ
|
||||||
# из `requires-python`, а у стенда спрашивать некого — даги и Superset живут
|
# из `requires-python`, а у стенда спрашивать некого — даги и Superset живут
|
||||||
# внутри образов. Замер 9 августа 2026 года: `apache/airflow:3.3.0` несёт
|
# внутри образов. Замер 9 августа 2026 года: `apache/airflow:3.3.0` несёт
|
||||||
# Python 3.13.14, `apache/superset:6.1.0` — 3.10.20. Стоит младшая из двух,
|
# Python 3.13.14, `apache/superset:6.1.0` — 3.10.20. Стоит младшая из двух,
|
||||||
# иначе ruff предложил бы Superset синтаксис, которого его Python не знает.
|
# иначе ruff предложил бы Superset синтаксис, которого его Python не знает.
|
||||||
# Совпадает со значением ruff по умолчанию, и записано именно поэтому:
|
# Даги за это платят: они бегут на 3.13, и модернизаций, доступных только там,
|
||||||
# сменится умолчание — проверка не поедет следом молча.
|
# ruff им не предложит. Значение совпадает с умолчанием ruff, и записано
|
||||||
|
# именно поэтому: сменится умолчание — проверка не поедет следом молча.
|
||||||
target-version = "py310"
|
target-version = "py310"
|
||||||
|
|
||||||
[lint]
|
[lint]
|
||||||
|
|||||||
Reference in New Issue
Block a user