#!/usr/bin/env python3 """Verify internal Go packages contain package-level Test functions.""" from __future__ import annotations import argparse import json import re import subprocess import sys from pathlib import Path TEST_FUNC_RE = re.compile(r"^\s*func\s+Test[A-Za-z0-9_]*\s*\(", re.MULTILINE) def repo_root() -> Path: return Path(__file__).resolve().parents[2] def load_internal_packages(root: Path) -> list[dict]: proc = subprocess.run( ["go", "list", "-json", "./internal/..."], cwd=root, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=False, ) if proc.returncode != 0: print(proc.stderr, file=sys.stderr, end="") raise SystemExit(f"go list -json ./internal/... failed with exit code {proc.returncode}") decoder = json.JSONDecoder() packages: list[dict] = [] output = proc.stdout index = 0 while index < len(output): while index < len(output) and output[index].isspace(): index += 1 if index >= len(output): break package, next_index = decoder.raw_decode(output, index) packages.append(package) index = next_index return packages def package_has_test_function(package: dict) -> bool: directory = Path(package["Dir"]) for key in ("TestGoFiles", "XTestGoFiles"): for filename in package.get(key) or []: path = directory / filename try: if TEST_FUNC_RE.search(path.read_text()): return True except OSError as exc: raise SystemExit(f"read {path}: {exc}") from exc return False def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--expect-missing", type=int, default=None, help="Pass only if exactly this many internal packages are missing Test functions.", ) return parser.parse_args() def main() -> int: args = parse_args() root = repo_root() packages = load_internal_packages(root) missing = sorted( package["ImportPath"] for package in packages if not package_has_test_function(package) ) if args.expect_missing is not None: if len(missing) != args.expect_missing: print( f"internal package test audit expected {args.expect_missing} missing packages, found {len(missing)}", file=sys.stderr, ) for import_path in missing: print(f"MISSING {import_path}", file=sys.stderr) return 1 print( f"internal package test audit matched expected missing count: missing={len(missing)} total={len(packages)}" ) for import_path in missing: print(f"MISSING {import_path}") return 0 if missing: print( f"internal packages without Test functions: {len(missing)} of {len(packages)}", file=sys.stderr, ) for import_path in missing: print(f"MISSING {import_path}", file=sys.stderr) return 1 print(f"internal package test audit passed: total={len(packages)} missing=0") return 0 if __name__ == "__main__": raise SystemExit(main())