import os import re import json import argparse from pathlib import Path ROOT = Path(__file__).resolve().parents[1] def main(): parser = argparse.ArgumentParser() parser.add_argument("--root", default=".") parser.add_argument("--out", default="Temp/version_sprawl_audit_v1.json") args = parser.parse_args() root_path = ROOT / args.root version_pattern = re.compile(r"(.+)_v(\d+)\.(.+)") groups = {} for dirpath, _, filenames in os.walk(root_path): if ".git" in dirpath or "node_modules" in dirpath or "__pycache__" in dirpath: continue for f in filenames: match = version_pattern.match(f) if match: base, version, ext = match.groups() rel_dir = os.path.relpath(dirpath, root_path) group_key = (rel_dir, base, ext) if group_key not in groups: groups[group_key] = [] groups[group_key].append({ "version": int(version), "filename": f, "path": os.path.join(rel_dir, f) }) report = { "formula_id": "VERSION_SPRAWL_AUDIT_V1", "version_groups": [] } for (rel_dir, base, ext), versions in groups.items(): if len(versions) >= 3: versions.sort(key=lambda x: x["version"], reverse=True) report["version_groups"].append({ "directory": rel_dir, "base": base, "extension": ext, "count": len(versions), "versions": versions }) out_file = ROOT / args.out out_file.parent.mkdir(parents=True, exist_ok=True) with open(out_file, "w", encoding="utf-8") as f: json.dump(report, f, indent=2) print(f"Version sprawl audit completed. Found {len(report['version_groups'])} groups with 3+ versions.") print(json.dumps(report, indent=2)) if __name__ == "__main__": main()