refactor(make): корень — про стенд, генератор — за своей дверью #77

Merged
ddmitry merged 3 commits from refactor/65-make-two-doors into main 2026-08-09 22:14:51 +03:00
6 changed files with 24 additions and 24 deletions
Showing only changes of commit e4e5688775 - Show all commits
+2 -1
View File
@@ -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).
+2 -5
View File
@@ -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
+3 -4
View File
@@ -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 \
+12 -5
View File
@@ -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`, ей нужен
-4
View File
@@ -1,7 +1,3 @@
# Цели генератора. Дверь у него своя, потому что своя и сущность: пакет с
# собственными `pyproject.toml`, `uv.lock` и образом, заменяемый целиком
# (спека генератора, раздел 1). Отсюда и короткие имена — каталог уже сказал,
# о ком речь, и суффикс `-generator` был бы вторым разом про то же.
.PHONY: lint typecheck test docs inventory .PHONY: lint typecheck test docs inventory
# --- Проверки --- # --- Проверки ---
+5 -5
View File
@@ -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]