#!/usr/bin/env python3 """Compiler-independent source-size and test-isolation contracts for non-Rust modules.""" from __future__ import annotations from pathlib import Path import os import re import shutil import subprocess import tempfile ROOT = Path(__file__).resolve().parents[2] MAX_LINES = 500 def lines(path: Path) -> int: return len(path.read_text(encoding="utf-8").splitlines()) # Browser implementation modules are bounded. QA harnesses under tools/checks are checked separately. for path in sorted((ROOT / "src/admin/web").rglob("*.js")): assert lines(path) <= MAX_LINES, f"{path.relative_to(ROOT)} has {lines(path)} lines (max {MAX_LINES})" # Docker Agent implementation and Go tests are separate files and all remain bounded. for path in sorted((ROOT / "docker-agent").glob("*.go")): assert lines(path) <= MAX_LINES, f"{path.relative_to(ROOT)} has {lines(path)} lines (max {MAX_LINES})" if not path.name.endswith("_test.go"): text = path.read_text(encoding="utf-8") assert not re.search(r"(?m)^func\s+Test[A-Z]", text), f"Go test remains in implementation file: {path.relative_to(ROOT)}" # Application-coupled Python entry points are split from external QA/dev tooling. for directory in ("scripts/runtime", "scripts/build", "scripts/deploy", "scripts/migration"): for path in sorted((ROOT / directory).glob("*.py")): assert lines(path) <= MAX_LINES, f"{path.relative_to(ROOT)} has {lines(path)} lines (max {MAX_LINES})" for old in (ROOT / "src/admin/web/app.js", ROOT / "src/admin/web/vhosts.js"): assert not old.exists(), f"oversized browser monolith returned: {old.relative_to(ROOT)}" for required in ( "src/admin/web/app/core.js", "src/admin/web/app/session-resume.js", "src/admin/web/app/preferences.js", "src/admin/web/app/config-history.js", "src/admin/web/app/runtime.js", "src/admin/web/app/settings.js", "src/admin/web/vhosts/core.js", "src/admin/web/vhosts/rates.js", "src/admin/web/vhosts/health.js", "src/admin/web/vhosts/editor.js", "src/admin/web/vhosts/render.js", "docker-agent/model.go", "docker-agent/docker.go", "docker-agent/network.go", "docker-agent/certificate.go", "docker-agent/server.go", "scripts/deploy/deploy_core.py", "scripts/deploy/deploy_runtime.py", "scripts/migration/migrate_npm_core.py", "scripts/migration/migrate_npm_api.py", ): assert (ROOT / required).is_file(), f"missing split source module: {required}" # When Node is available, parse every standalone browser module and both assembled public bundles. node = shutil.which("node") if node: env = dict(os.environ, TERM=os.environ.get("TERM", "xterm")) standalone = list((ROOT / "src/admin/web").rglob("*.js")) for path in sorted(standalone): subprocess.run([node, "--check", str(path)], check=True, env=env, stdout=subprocess.DEVNULL) from web_assets import read_app_js, read_vhosts_js browser_markup = (ROOT / "src/admin/web/index.html").read_text(encoding="utf-8") assert browser_markup.count('