Files
geointel/scripts/check_architecture_budgets.py
T
Jens dc3a3b2a65
Managed validation / full (pull_request) Successful in 7s
GeoIntel release gates / Trusted workflow source (pull_request) Successful in 2s
GeoIntel release gates / Compile, test, contracts and builds (pull_request) Failing after 1m43s
GeoIntel release gates / Python and npm vulnerability policy (pull_request) Failing after 57s
GeoIntel release gates / GIS image, SBOM and container scan (pull_request) Successful in 2m36s
GeoIntel release gates / AI image, SBOM and container scan (pull_request) Failing after 3m9s
ci: freeze existing frontend architecture hotspots
2026-08-29 22:41:10 +02:00

75 lines
2.6 KiB
Python

#!/usr/bin/env python3
from __future__ import annotations
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
LEGACY_MAX_BYTES = {
"backend/app/services/dataset_service.py": 138_951,
"backend/app/services/official_vector_acquisition_service.py": 85_921,
"backend/app/services/data_contract_validation.py": 85_783,
"backend/app/services/detection_service.py": 61_248,
"frontend/src/WorkbenchApp.tsx": 64_092,
"frontend/src/types.ts": 46_900,
"frontend/src/components/map/MapAdvancedWorkbench.tsx": 47_887,
"frontend/src/components/map/MapExplorerView.tsx": 55_417,
"frontend/src/components/detection/DetectionLab.tsx": 55_020,
}
SERVICE_MAX_BYTES = 60_000
ROUTE_MAX_BYTES = 45_000
TSX_COMPONENT_MAX_BYTES = 45_000
def _check_file(relative: str, max_bytes: int, violations: list[str]) -> None:
path = ROOT / relative
if not path.is_file():
violations.append(f"{relative}: expected architecture-budget file is missing")
return
size = path.stat().st_size
if size > max_bytes:
violations.append(f"{relative}: {size} bytes exceeds budget {max_bytes}")
def main() -> int:
violations: list[str] = []
for relative, max_bytes in LEGACY_MAX_BYTES.items():
_check_file(relative, max_bytes, violations)
legacy = set(LEGACY_MAX_BYTES)
for path in (ROOT / "backend/app/services").glob("*.py"):
relative = path.relative_to(ROOT).as_posix()
if relative not in legacy and path.stat().st_size > SERVICE_MAX_BYTES:
violations.append(
f"{relative}: {path.stat().st_size} bytes exceeds service budget {SERVICE_MAX_BYTES}"
)
for path in (ROOT / "backend/app/api/routes").glob("*.py"):
relative = path.relative_to(ROOT).as_posix()
if relative not in legacy and path.stat().st_size > ROUTE_MAX_BYTES:
violations.append(
f"{relative}: {path.stat().st_size} bytes exceeds route budget {ROUTE_MAX_BYTES}"
)
for path in (ROOT / "frontend/src/components").rglob("*.tsx"):
relative = path.relative_to(ROOT).as_posix()
if relative not in legacy and path.stat().st_size > TSX_COMPONENT_MAX_BYTES:
violations.append(
f"{relative}: {path.stat().st_size} bytes exceeds component budget {TSX_COMPONENT_MAX_BYTES}"
)
if violations:
print("Architecture budget violations:", file=sys.stderr)
for violation in violations:
print(f" - {violation}", file=sys.stderr)
return 1
print("Architecture budgets passed.")
return 0
if __name__ == "__main__":
raise SystemExit(main())