Files
MetaCrate/tools/check_milestone_06.py
Chili Palmer c0be04968f
Some checks failed
CI / required (push) Failing after 7m31s
Consolidate required CI gate (#115)
2026-08-12 18:50:04 +00:00

139 lines
5.5 KiB
Python

#!/usr/bin/env python3
"""Audit the fixed ownership and feature boundary for milestone 06."""
from __future__ import annotations
import json
from pathlib import Path
import re
import tomllib
ROOT = Path(__file__).resolve().parents[1]
OWNED_CRATES = (
ROOT / "crates" / "libremetaverse-imaging",
ROOT / "crates" / "libremetaverse-imaging-skia",
ROOT / "crates" / "libremetaverse-prim-mesher",
)
OWNED_FIXTURES = {
"LibreMetaverse.Tests/ManagedImageTests.cs": 3,
"LibreMetaverse.Rendering.Tests/PrimMesher/CoordQuatTests.cs": 18,
"LibreMetaverse.Rendering.Tests/PrimMesher/PrimMeshTests.cs": 27,
}
STUB_RE = re.compile(r"\b(?:not_implemented|unimplemented_api)\b|\b(?:todo|unimplemented)!\s*\(")
def load_toml(path: Path) -> dict:
with path.open("rb") as stream:
return tomllib.load(stream)
def check_owned_rust() -> None:
offenders: list[str] = []
for crate in OWNED_CRATES:
for path in sorted((crate / "src").rglob("*.rs")):
if STUB_RE.search(path.read_text()):
offenders.append(path.relative_to(ROOT).as_posix())
if offenders:
raise SystemExit("milestone-owned Rust stubs remain: " + ", ".join(offenders))
def check_features() -> None:
imaging = load_toml(OWNED_CRATES[0] / "Cargo.toml")
if imaging["features"].get("default") != []:
raise SystemExit("imaging default features must stay empty")
if imaging["features"].get("jpeg2000") != ["dep:libremetaverse-openjpeg"]:
raise SystemExit("JPEG 2000 must stay isolated behind its optional feature")
if not imaging["dependencies"]["libremetaverse-openjpeg"].get("optional"):
raise SystemExit("the OpenJPEG adapter dependency must stay optional")
skia = load_toml(OWNED_CRATES[1] / "Cargo.toml")
if skia["features"].get("default") != []:
raise SystemExit("Skia adapter default features must stay empty")
if skia["features"].get("skia") != ["dep:skia-safe"]:
raise SystemExit("Skia must stay isolated behind its optional feature")
targets = skia.get("target", {}).values()
skia_dependencies = [
target.get("dependencies", {}).get("skia-safe") for target in targets
]
if not skia_dependencies or any(
dependency is None or not dependency.get("optional")
for dependency in skia_dependencies
):
raise SystemExit("every platform-specific Skia dependency must stay optional")
workspace = load_toml(ROOT / "Cargo.toml")["workspace"]
adapter = "crates/libremetaverse-openjpeg"
if adapter not in workspace.get("members", []):
raise SystemExit("the native OpenJPEG adapter must remain explicitly packageable")
if adapter in workspace.get("default-members", workspace.get("members", [])):
raise SystemExit("the native OpenJPEG adapter must stay outside default workspace builds")
def check_parity() -> None:
catalog = json.loads((ROOT / "tests" / "upstream-tests.json").read_text())
grouped: dict[str, list[dict]] = {source: [] for source in OWNED_FIXTURES}
for case in catalog["tests"]:
if case["source"] in grouped:
grouped[case["source"]].append(case)
for source, expected in OWNED_FIXTURES.items():
cases = grouped[source]
if len(cases) != expected:
raise SystemExit(f"{source}: expected {expected} reviewed cases, found {len(cases)}")
incomplete = [
case["id"]
for case in cases
if case["status"] != "translated"
or case.get("semantic_review") != "reviewed"
or not (ROOT / case["rust_file"]).is_file()
]
if incomplete:
raise SystemExit(f"{source}: incomplete parity cases: " + ", ".join(incomplete))
def check_benchmarks_and_ci() -> None:
expected_benches = {
OWNED_CRATES[0]: "image_pipeline",
OWNED_CRATES[2]: "meshing",
}
for crate, name in expected_benches.items():
manifest = load_toml(crate / "Cargo.toml")
benches = {entry["name"]: entry for entry in manifest.get("bench", [])}
if benches.get(name, {}).get("harness") is not False:
raise SystemExit(f"missing harness-free {name} benchmark declaration")
if not (crate / "benches" / f"{name}.rs").is_file():
raise SystemExit(f"missing {name} benchmark source")
workflows = {"consolidated": ROOT / ".gitea" / "workflows" / "ci.yml"}
for name, path in workflows.items():
if not path.is_file():
raise SystemExit(f"missing {name} native-feature workflow")
runners = re.findall(r"(?m)^\s*runs-on:\s*([^\s#]+)", path.read_text().lower())
if not runners:
raise SystemExit(f"{name} workflow has no runner")
unsupported = sorted({runner for runner in runners if runner != "ubuntu-latest"})
if unsupported:
raise SystemExit(
f"{name} workflow must use only ubuntu-latest, found: "
+ ", ".join(unsupported)
)
text = path.read_text()
for marker in ("required-gate", "METACRATE_SKIA_ARCHIVE", "OPENJPEG_PREFIX"):
if marker not in text:
raise SystemExit(f"{name} workflow is missing {marker}")
def main() -> None:
check_owned_rust()
check_features()
check_parity()
check_benchmarks_and_ci()
print(
"milestone 06 audit: owned Rust has no stubs; 48 reviewed parity cases, "
"optional native features, benchmarks, and Linux-only Gitea workflows are complete"
)
if __name__ == "__main__":
main()