⎇ 1fdbd358c8cd914fb767cbee1483d79935aa1fec
scripts/rename-fase-a.py
Ñawpa willay
Pi imata llamkarqan
ch'uya
refactor(naming): A1 — ente→arje, vista→revista, pluma→fana
1#!/usr/bin/env python3
2"""
3Fase A · rename batch (2026-05-19):
4 - ente-* → arje-* (25 crates: protocol/init/runtime/compat)
5 - vista → revista (vista-core/web → revista-core/web)
6 - pluma → fana (pluma-md → fana-md, pluma-reader-web → fana-md-reader-web)
7
8Reusa el patrón de scripts/reorg.py + rename-chasqui.py.
9
10Uso:
11 python3 scripts/rename-fase-a.py --dry-run
12 python3 scripts/rename-fase-a.py
13"""
14
15import os, re, subprocess, sys
16from pathlib import Path
17
18ROOT = Path("/home/sergio/brahman")
19DRY = "--dry-run" in sys.argv
20
21# ============================================================
22# MOVES — leaf crate dirs, old → new (git_mv crea dirs padre)
23# ============================================================
24MOVES: dict[str, str] = {}
25
26ENTE = {
27 "protocol": ["ente-card"],
28 "init": ["ente-zero", "ente-kernel", "ente-soma",
29 "ente-snapshot", "ente-incarnate"],
30 "runtime": ["ente-bus", "ente-cas", "ente-wasm",
31 "ente-brain", "ente-echo"],
32 "compat": ["ente-logind-compat", "ente-hostnamed-compat",
33 "ente-timedated-compat", "ente-localed-compat",
34 "ente-journald-compat", "ente-resolved-compat",
35 "ente-polkit-compat", "ente-machined-compat",
36 "ente-systemd1-compat", "ente-notify-compat",
37 "ente-timer-compat", "ente-tmpfiles-compat",
38 "ente-binfmt-compat", "ente-policy-provider"],
39}
40for layer, crates in ENTE.items():
41 for c in crates:
42 new = c.replace("ente-", "arje-", 1)
43 MOVES[f"crates/{layer}/{c}"] = f"crates/{layer}/{new}"
44
45# vista → revista
46MOVES["crates/modules/vista/vista-core"] = "crates/modules/revista/revista-core"
47MOVES["crates/modules/vista/vista-web"] = "crates/modules/revista/revista-web"
48# pluma → fana
49MOVES["crates/modules/pluma/pluma-md"] = "crates/modules/fana/fana-md"
50MOVES["crates/modules/pluma/pluma-reader-web"] = "crates/modules/fana/fana-md-reader-web"
51
52# SDD.md de los módulos renombrados
53SDD_MOVES = {
54 "crates/modules/vista/SDD.md": "crates/modules/revista/SDD.md",
55 "crates/modules/pluma/SDD.md": "crates/modules/fana/SDD.md",
56}
57
58# ============================================================
59# PKG_RENAMES — nombres de paquete viejo → nuevo
60# ============================================================
61PKG_RENAMES: dict[str, str] = {}
62for layer, crates in ENTE.items():
63 for c in crates:
64 PKG_RENAMES[c] = c.replace("ente-", "arje-", 1)
65PKG_RENAMES["ente-journalctl"] = "arje-journalctl" # bin name especial
66PKG_RENAMES["vista-core"] = "revista-core"
67PKG_RENAMES["vista-web"] = "revista-web"
68PKG_RENAMES["pluma-md"] = "fana-md"
69PKG_RENAMES["pluma-reader-web"] = "fana-md-reader-web"
70
71# ============================================================
72# Helpers
73# ============================================================
74def sh(cmd, check=True):
75 if DRY:
76 print(f" DRY: {' '.join(cmd)}")
77 return None
78 return subprocess.run(cmd, check=check, cwd=str(ROOT))
79
80def git_mv(src: str, dst: str):
81 src_p, dst_p = ROOT / src, ROOT / dst
82 if not src_p.exists():
83 print(f" SKIP {src} (no existe)")
84 return
85 if dst_p.exists():
86 print(f" WARN {dst} ya existe — saltando")
87 return
88 dst_p.parent.mkdir(parents=True, exist_ok=True)
89 sh(["git", "mv", src, dst])
90
91def all_cargo_tomls():
92 return [p for p in (ROOT / "crates").rglob("Cargo.toml") if "target" not in p.parts]
93
94def all_rs():
95 return [p for p in (ROOT / "crates").rglob("*.rs") if "target" not in p.parts]
96
97CURRENT_TO_OLD = {new: old for old, new in MOVES.items()}
98
99def owner_old_for(toml: Path) -> str:
100 cur = str(toml.parent.relative_to(ROOT))
101 return CURRENT_TO_OLD.get(cur, cur)
102
103def resolve_canon(base_dir: str, rel: str):
104 try:
105 return str((ROOT / base_dir / rel).resolve().relative_to(ROOT))
106 except ValueError:
107 return None
108
109def map_target(old_tgt: str) -> str:
110 return MOVES.get(old_tgt, old_tgt)
111
112def rewrite_paths_in_toml(toml: Path):
113 text = toml.read_text()
114 owner_old = owner_old_for(toml)
115 owner_new = str(toml.parent.relative_to(ROOT))
116
117 def repl(m):
118 rel_in_file = m.group(1)
119 for base in (owner_old, owner_new):
120 tgt = resolve_canon(base, rel_in_file)
121 if tgt is None:
122 continue
123 new_tgt = map_target(tgt)
124 if (ROOT / new_tgt).exists() or new_tgt != tgt:
125 new_rel = os.path.relpath(str(ROOT / new_tgt), str(ROOT / owner_new))
126 return f'path = "{new_rel}"'
127 return m.group(0)
128
129 new_text = re.sub(r'path\s*=\s*"([^"]+)"', repl, text)
130 if new_text != text:
131 if DRY: print(f" DRY paths: {toml.relative_to(ROOT)}")
132 else: toml.write_text(new_text)
133
134def rewrite_pkg_names_in_toml(toml: Path):
135 text = toml.read_text()
136 orig = text
137 for old, new in sorted(PKG_RENAMES.items(), key=lambda kv: -len(kv[0])):
138 old_us, new_us = old.replace("-", "_"), new.replace("-", "_")
139 # name = "old" / "old_us" (package, lib, bin)
140 text = re.sub(rf'(\bname\s*=\s*)"{re.escape(old)}"', rf'\1"{new}"', text)
141 text = re.sub(rf'(\bname\s*=\s*)"{re.escape(old_us)}"', rf'\1"{new_us}"', text)
142 text = re.sub(rf'(\bpackage\s*=\s*)"{re.escape(old)}"', rf'\1"{new}"', text)
143 # dep key al inicio de línea
144 text = re.sub(rf'^([ \t]*){re.escape(old)}(\s*=)', rf'\1{new}\2',
145 text, flags=re.MULTILINE)
146 # features / strings
147 text = re.sub(rf'"dep:{re.escape(old)}"', f'"dep:{new}"', text)
148 text = re.sub(rf'"{re.escape(old)}/', f'"{new}/', text)
149 text = re.sub(rf'"{re.escape(old)}"', f'"{new}"', text)
150 if text != orig:
151 if DRY: print(f" DRY names: {toml.relative_to(ROOT)}")
152 else: toml.write_text(text)
153
154USE_RENAMES = {k.replace("-", "_"): v.replace("-", "_") for k, v in PKG_RENAMES.items()}
155
156def rewrite_imports_in_rs(rs: Path):
157 text = rs.read_text()
158 orig = text
159 for old, new in sorted(USE_RENAMES.items(), key=lambda kv: -len(kv[0])):
160 text = re.sub(rf'(?<![A-Za-z0-9_]){re.escape(old)}(?![A-Za-z0-9_])', new, text)
161 if text != orig:
162 if DRY: print(f" DRY imports: {rs.relative_to(ROOT)}")
163 else: rs.write_text(text)
164
165def rewrite_workspace_toml():
166 p = ROOT / "Cargo.toml"
167 text = p.read_text()
168 orig = text
169 for old, new in MOVES.items():
170 text = text.replace(f'"{old}"', f'"{new}"')
171 for old, new in PKG_RENAMES.items():
172 text = re.sub(rf'^([ \t]*){re.escape(old)}(\s*=)', rf'\1{new}\2',
173 text, flags=re.MULTILINE)
174 # Comentarios de sección
175 text = text.replace("(era yahweh)", "(era yahweh)") # no-op, placeholder
176 text = text.replace("# modules/vista/ — Deck horizontal swipe (Flutter PageView)",
177 "# modules/revista/ — Deck horizontal swipe (Flutter PageView)")
178 text = text.replace("# modules/pluma/ — Markdown agnóstico + visor web",
179 "# modules/fana/ — Writer DAG editor (absorbe pluma)")
180 if text != orig:
181 if DRY: print(" DRY workspace toml")
182 else: p.write_text(text)
183
184def cleanup_empty(rel_dir: str):
185 d = ROOT / rel_dir
186 if d.exists() and d.is_dir() and not any(d.iterdir()):
187 if DRY: print(f" DRY rmdir {rel_dir}")
188 else: d.rmdir()
189
190def run():
191 print(f"=== rename-fase-a.py (DRY={DRY}) ===")
192 print(f" {len(MOVES)} moves, {len(PKG_RENAMES)} pkg renames")
193
194 print("\n-- step 1: git mv crates --")
195 for old, new in MOVES.items():
196 git_mv(old, new)
197
198 print("\n-- step 2: git mv SDDs --")
199 for old, new in SDD_MOVES.items():
200 git_mv(old, new)
201
202 print("\n-- step 3: cleanup dirs vacíos --")
203 cleanup_empty("crates/modules/vista")
204 cleanup_empty("crates/modules/pluma")
205
206 print("\n-- step 4: package names --")
207 for toml in all_cargo_tomls():
208 rewrite_pkg_names_in_toml(toml)
209
210 print("\n-- step 5: paths relativos --")
211 for toml in all_cargo_tomls():
212 rewrite_paths_in_toml(toml)
213
214 print("\n-- step 6: imports .rs --")
215 for rs in all_rs():
216 rewrite_imports_in_rs(rs)
217
218 print("\n-- step 7: workspace Cargo.toml --")
219 rewrite_workspace_toml()
220
221 print("\nOK")
222
223if __name__ == "__main__":
224 run()