Files
crank/scripts/check-rust-module-boundaries.sh
T

79 lines
2.4 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="${CRANK_RUST_BOUNDARY_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
status=0
check_no_match() {
local description="$1"
local pattern="$2"
shift 2
local output
output="$(rg -n "$pattern" "$@" 2>/dev/null || true)"
if [[ -n "$output" ]]; then
echo "error: $description" >&2
echo "$output" >&2
status=1
fi
}
echo "Rust module boundary check: checking module-level imports"
python3 "$ROOT_DIR/scripts/check-config-boundaries.py" --root "$ROOT_DIR" || status=1
python3 "$ROOT_DIR/scripts/check-migration-boundaries.py" --root "$ROOT_DIR" || status=1
check_no_match \
"admin-api service modules must not depend on axum HTTP types" \
'^\s*use\s+axum(::|[;\{])' \
"$ROOT_DIR/apps/admin-api/src/service" \
"$ROOT_DIR/apps/admin-api/src/service.rs"
check_no_match \
"admin-api route modules must not call runtime directly" \
'^\s*use\s+crank_runtime(::|[;\{])' \
"$ROOT_DIR/apps/admin-api/src/routes" \
"$ROOT_DIR/apps/admin-api/src/routes.rs"
check_no_match \
"crank-core production modules must not depend on axum, sqlx, reqwest, tokio or tracing" \
'^\s*use\s+(axum|sqlx|reqwest|tokio|tracing)(::|[;\{])' \
"$ROOT_DIR/crates/crank-core/src"
check_no_match \
"crank-registry production modules must not depend on axum or reqwest" \
'^\s*use\s+(axum|reqwest)(::|[;\{])' \
"$ROOT_DIR/crates/crank-registry/src"
check_no_match \
"crank-runtime production modules must not depend on axum or sqlx" \
'^\s*use\s+(axum|sqlx)(::|[;\{])' \
"$ROOT_DIR/crates/crank-runtime/src"
check_no_match \
"product modules must record metrics only through crank-metrics" \
'(^|[^[:alnum:]_])(::)?metrics::(counter|gauge|histogram)!' \
"$ROOT_DIR/apps" \
"$ROOT_DIR/crates" \
--glob '!**/crank-metrics/**'
if (( status != 0 )); then
cat >&2 <<'EOF'
Rust module boundary check failed.
Rules:
- routes own HTTP extraction/response details;
- service modules own application use-cases and must not import axum;
- core remains framework/storage agnostic;
- registry remains storage-only and HTTP-client agnostic;
- runtime remains execution-only and storage/framework agnostic.
- names and labels of metrics remain inside the typed crank-metrics contract.
- process environment is read only by the leaf crank-config adapter.
- PostgreSQL DDL and migration advisory locks are owned only by crank-registry migrations.
EOF
fi
exit "$status"