#!/usr/bin/env python3 """ D4 — driver-manager-audit-no-stubs.py Static-analysis gate for the § 0.5 comprehensive implementation principle (see `local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md` § 0.5). Four rules: - R1: stub macros (`unimplemented!()` / `todo!()` / `unreachable!()`) in production paths. - R2: empty catch-all match arms (`_ => {}`). - R3: `DriverParams::default()` returns in concrete drivers. - R5: stub-macro calls inside Driver trait method bodies — distinguish from test-only usage. Whitelisted: tests under `#[cfg(test)]`, examples, doc-tests. Returns exit 0 on a clean audit, 1 otherwise. """ from __future__ import annotations import os import re import subprocess import sys from pathlib import Path from typing import Iterator REPO_ROOT = Path("/mnt/data/Builds/RedBear-OS") SCAN_ROOTS = [ REPO_ROOT / "local/recipes/system/driver-manager/source", REPO_ROOT / "local/recipes/drivers/redox-driver-core/source", REPO_ROOT / "local/recipes/drivers/redox-driver-pci/source", REPO_ROOT / "local/recipes/drivers/redox-driver-sys/source", ] RUST_EXT = ".rs" # Lines to skip — match by exact suffix. SKIP_LINE_SUFFIXES = ( "unimplemented!()", "todo!()", "unreachable!()", ) # R5: stub macros that are particularly suspect inside callback / fn bodies. # We only flag these in production paths (i.e. not in #[cfg(test)] modules). STUB_MACRO_PATTERN = ( r"\b(?:unimplemented|todo|unreachable)!\(\)", "R5", "stub macro left in callback / fn body", ) # Match-block skip: # `_ => { }` or `_ => {}` (empty body) EMPTY_CATCH_ALL = re.compile(r"^\s*_?\s*=>\s*\{\s*\}\s*,?\s*$") # Default trait method returning Ok(()) in lifecycle hooks: # fn probe(...) -> ProbeResult { ... Ok(()) skip ... } # fn remove(...) -> Result<...> { ... Ok(()) skip ... } TRAIT_LIFECYCLE_OK_BODY = re.compile( r"^\s*Ok\s*\(\s*\)\s*,?\s*$" ) # Default DriverParams::default() return in concrete driver impl. DRIVER_PARAMS_DEFAULT = re.compile(r"\bDriverParams::default\s*\(\s*\)") def iter_rust_files() -> Iterator[Path]: for root in SCAN_ROOTS: if not root.exists(): continue for path in sorted(root.rglob(f"*{RUST_EXT}")): # Skip vendored or generated directories if any ever appear. if "/target/" in str(path): continue yield path def file_is_test_only(path: Path, content: str) -> bool: """Return True if every top-level item in this file is gated by `#[cfg(test)]` (i.e. helper files for tests, doc tests, fixtures).""" test_count = content.count("#[cfg(test)]") if test_count == 0: return False non_test_items = 0 fn_count = content.count("\nfn ") struct_count = content.count("\nstruct ") enum_count = content.count("\nenum ") impl_count = content.count("\nimpl ") non_test_items = fn_count + struct_count + enum_count + impl_count # Be conservative: only treat as test-only if `#[cfg(test)]` appears # at module level (outside any inner `mod tests { ... }`). if content.lstrip().startswith("#[cfg(test)]"): return True return False def audit_file(path: Path) -> list[tuple[int, str, str]]: """Return a list of (line_no, rule_id, message) violations for one file.""" content = path.read_text(encoding="utf-8", errors="replace") lines = content.splitlines() is_test_only = file_is_test_only(path, content) out: list[tuple[int, str, str]] = [] for line_no, line in enumerate(lines, start=1): stripped = line.strip() if not stripped or stripped.startswith("//"): continue # Rule R1 — direct stub-macro calls. for suffix in SKIP_LINE_SUFFIXES: if stripped.endswith(suffix) or f".{suffix}" in stripped: if not is_test_only: out.append( ( line_no, "R1", f"`{suffix}` is a stub. Implement the case (see § 0.5).", ) ) # Rule R2 — empty catch-all in matches. if EMPTY_CATCH_ALL.match(line): # Heuristic: empty body is fine in some contexts (e.g. specific # feature flags), but only flag when there's a preceding match. # We just flag with a low-severity tag. out.append( ( line_no, "R2", "empty catch-all match arm `_ => {}` — confirm this is intentional", ) ) # Rule R3 — DriverParams::default() returns in production code. if not is_test_only and DRIVER_PARAMS_DEFAULT.search(line): out.append( ( line_no, "R3", "`DriverParams::default()` is a stub for production drivers — define real params", ) ) for pattern, rule_id, message in [STUB_MACRO_PATTERN]: if is_test_only: break import re as _re if _re.search(pattern, stripped): out.append((line_no, rule_id, message)) return out def main() -> int: violations_total = 0 files_scanned = 0 files_clean = 0 for path in iter_rust_files(): files_scanned += 1 violations = audit_file(path) if not violations: files_clean += 1 continue violations_total += len(violations) for line_no, rule_id, message in violations: rel = path.relative_to(REPO_ROOT) print(f"{rel}:{line_no}: [{rule_id}] {message}") print() print(f"=== driver-manager-audit-no-stubs.py ===") print(f"files scanned: {files_scanned}") print(f"files clean: {files_clean}") print(f"violations: {violations_total}") print(f"root: {REPO_ROOT}") print( "rules: R1 (stub macros), R2 (empty catch-all), R3 (DriverParams::default)," ) print(" R5 (todo!/unimplemented! in callbacks)") if violations_total > 0: print() print("FAIL — driver-manager has unresolved § 0.5 comprehensive-implementation violations.") print("Fix every violation above and re-run. See migration plan § 5.1 D4 exit criteria.") return 1 print() print("OK — every scanned file passes the § 0.5 stub-audit.") return 0 if __name__ == "__main__": sys.exit(main())