AgentnessBench / tools /restructure_imports.py
irregular6612's picture
chore(tools): add import codemod for game/web restructure
789894f
Raw
History Blame Contribute Delete
2.8 kB
# tools/restructure_imports.py
"""One-shot codemod: rewrite proteus import paths for the game/web restructure.
Usage:
python tools/restructure_imports.py <file_or_dir> [<file_or_dir> ...]
NEVER run this on tools/ — this file contains the rule strings themselves.
Rules apply IN ORDER (most-specific first) so prefix collisions resolve
correctly:
* grid.scenarios (plural) before grid.scenario (singular) before grid (bare)
* runtime.metrics/persona/rollout/aggregate before runtime (bare)
Each rule matches a dotted path at a word boundary so 'proteus.grid' does not
hit 'proteus.gridx', and (because longer rules run first) does not pre-empt
'proteus.grid.game'.
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
RULES: list[tuple[str, str]] = [
# grid family — plural, then singular, then submodules, then bare
("proteus.grid.scenarios", "proteus.game.scenarios"),
("proteus.grid.scenario", "proteus.game.scenarios.base"),
("proteus.grid.game", "proteus.game.engine.grid"),
("proteus.grid.difficulty", "proteus.game.engine.difficulty"),
("proteus.grid.ascii_view", "proteus.game.engine.ascii_view"),
("proteus.grid", "proteus.game.scenarios"),
# arc_grid (engine + rendering)
("proteus.arc_grid", "proteus.game.engine"),
# runtime — metrics group out to game.metrics (specific first), then bare
("proteus.runtime.metrics", "proteus.game.metrics.metrics"),
("proteus.runtime.persona", "proteus.game.metrics.persona"),
("proteus.runtime.rollout", "proteus.game.metrics.rollout"),
("proteus.runtime.aggregate", "proteus.game.metrics.aggregate"),
("proteus.runtime", "proteus.game.runtime"),
# agents / viz
("proteus.agents", "proteus.game.agents"),
("proteus.viz", "proteus.game.viz"),
# web -> web.local (arena is new; no old refs)
("proteus.web", "proteus.web.local"),
]
COMPILED = [(re.compile(r"\b" + re.escape(old) + r"(?![\w])"), new)
for old, new in RULES]
def rewrite(text: str) -> str:
for pat, new in COMPILED:
text = pat.sub(new, text)
return text
def iter_py(paths: list[str]):
for p in paths:
path = Path(p)
if path.is_dir():
yield from sorted(path.rglob("*.py"))
elif path.suffix == ".py":
yield path
def main(argv: list[str]) -> int:
changed = 0
for path in iter_py(argv):
old = path.read_text()
new = rewrite(old)
if new != old:
path.write_text(new)
changed += 1
print(f"rewrote {path}")
print(f"--- {changed} files changed ---")
return 0
if __name__ == "__main__":
raise SystemExit(main(sys.argv[1:]))