5.4 KiB
Rust Code Health
Цель
В Community-репозитории нужно удерживать Rust-код в состоянии, где модули можно безопасно менять без разрастания скрытых связей.
Основные риски сейчас:
- крупные production-файлы с тестами внутри;
- интеграционные сценарии, написанные рядом с кодом;
- смешение HTTP, registry, runtime и test fixtures в одном модуле;
- отсутствие автоматического контроля размера файлов.
Инструменты
В Rust нет одного прямого аналога Python import-linter, который закрывает cohesion, coupling и connascence на уровне workspace.
Используемая база:
cargo fmt— единый стиль.cargo clippy --workspace --all-targets --all-features -- -D warnings— локальные ошибки, smell-и и часть API-антипаттернов.cargo test --workspace --all-targets— unit и integration-style тесты.scripts/check-rust-code-health.sh— локальный repo-level gate для размера Rust-файлов.scripts/check-rust-boundaries.sh— crate-level dependency direction и module-level import rules.scripts/check-rust-module-boundaries.sh— запрет на опасные imports внутри слоев.
Что можно добавить позже:
cargo-denyдля лицензий, security advisories и duplicate dependencies.cargo-macheteдля поиска неиспользуемых зависимостей.cargo-udepsдля более строгой проверки зависимостей, если nightly допустим в отдельной job.cargo-modulesилиcargo-guppyдля анализа графа модулей и зависимостей между crate-ами.
Правила размера
Новые Rust-файлы не должны быть больше 1000 строк.
Существующие крупные файлы зафиксированы baseline-ом в scripts/check-rust-code-health.sh. Они не должны расти дальше. При изменении таких файлов предпочтительно:
- выносить вложенный
mod testsвtests/, если тест проверяет публичное поведение, БД, HTTP или несколько модулей сразу; - выделять route/service/runtime helper в отдельный модуль;
- оставлять рядом с production-кодом только короткие unit-тесты приватной логики.
Текущие крупные production-файлы считаются debt baseline. Они не должны расти, а при изменении их нужно постепенно разбирать:
apps/admin-api/src/service.rscrates/crank-registry/src/postgres/mod.rscrates/crank-community-mcp/src/app.rscrates/crank-registry/src/postgres/operation.rs
Уже выделенные направления:
apps/admin-api/src/dto.rsсодержит HTTP payloads и view models.crates/crank-registry/src/postgres/pool_config.rsсодержит env parsing и validation pool settings.crates/crank-registry/src/postgres/connection.rsсодержит connection/migration wiring.crates/crank-community-mcp/src/transport.rsсодержит Streamable HTTP transport helpers.crates/crank-runtime::RuntimeExecutionRequestявляется основным способом передавать execution параметры.
Правила тестов
Рядом с кодом допустимы:
- маленькие pure unit tests;
- проверки приватных parser/mapper/helper-функций;
- тесты без сети, БД и поднятых серверов.
В tests/ нужно выносить:
- PostgreSQL integration tests;
- admin-api HTTP сценарии;
- fake upstream servers;
- publish/test-run/YAML roundtrip flow;
- MCP Streamable HTTP сценарии.
Целевая структура:
apps/admin-api/tests/
crates/crank-registry/tests/
crates/crank-runtime/tests/
crates/crank-community-mcp/tests/
Архитектурные границы
Базовое правило направления зависимостей:
apps/* -> crates/*
crank-community-mcp -> crank-registry + crank-runtime + crank-core
crank-runtime -> crank-core + crank-mapping + crank-schema + adapters
crank-registry -> crank-core
crank-adapter-rest -> crank-core + crank-mapping + crank-schema
crank-core -> no app crates
Если потребуется строгая автоматическая проверка границ, добавим отдельный script на основе cargo metadata или cargo-guppy.
Module-level правила уже проверяются:
apps/admin-api/src/service*не импортируетaxum;apps/admin-api/src/routes*не импортируетcrank_runtime;crank-core/srcне импортирует framework/storage/network runtime crates;crank-registry/srcне импортирует HTTP framework/client crates;crank-runtime/srcне импортирует HTTP framework или SQL storage crates.