#!/usr/bin/env python3 """Mechanical one-shot rename script for UCE's legacy value-tree API. The old tokens are constructed rather than written literally so this script can remain in the tree after the rename without reintroducing the retired names. """ from __future__ import annotations import os from pathlib import Path ROOT = Path(__file__).resolve().parents[2] OLD_TYPE = "D" + "Tree" OLD_LOWER = "d" + "tree" NEW_TYPE = "DValue" NEW_LOWER = "dvalue" DIR_EXCLUDES = { ".git", ".hg", ".svn", "3rdparty", "bin", "node_modules", "pkg", "tmp", "work", "__pycache__", } BINARY_SUFFIXES = { ".bin", ".gif", ".ico", ".jpg", ".jpeg", ".lock", ".o", ".pdf", ".png", ".pyc", ".so", ".sqlite", ".webp", ".zip", } REPLACEMENTS = ( (OLD_TYPE, NEW_TYPE), (OLD_TYPE.upper(), NEW_TYPE.upper()), (OLD_LOWER + "_", "dv_"), (OLD_LOWER, NEW_LOWER), ) def replace_text(value: str) -> str: for old, new in REPLACEMENTS: value = value.replace(old, new) return value def skip_dir(name: str) -> bool: return name in DIR_EXCLUDES or name.startswith(".fuse") def skip_file(path: Path) -> bool: return path.name.startswith(".fuse") or path.suffix in BINARY_SUFFIXES def rewrite_text_files() -> int: changed = 0 for current, dirs, files in os.walk(ROOT): dirs[:] = [name for name in dirs if not skip_dir(name)] for name in files: path = Path(current) / name if skip_file(path): continue data = path.read_bytes() if b"\0" in data: continue try: original = data.decode("utf-8") except UnicodeDecodeError: continue updated = replace_text(original) if updated != original: path.write_text(updated, encoding="utf-8") changed += 1 return changed def rename_paths() -> int: changed = 0 matches: list[Path] = [] for current, dirs, files in os.walk(ROOT, topdown=False): dirs[:] = [name for name in dirs if not skip_dir(name)] current_path = Path(current) for name in files + dirs: new_name = replace_text(name) if new_name != name: matches.append(current_path / name) for path in sorted(matches, key=lambda item: len(item.parts), reverse=True): if not path.exists(): continue target = path.with_name(replace_text(path.name)) if target.exists(): raise RuntimeError(f"cannot rename {path} -> {target}: target exists") path.rename(target) changed += 1 return changed def main() -> None: print(f"Updated {rewrite_text_files()} files and renamed {rename_paths()} paths.") if __name__ == "__main__": main()