⎇ 6facc3c8ed901d441e45bc052eadd6bbd2c668f5
scripts/rename-chasqui.py
Ñawpa willay
Pi imata llamkarqan
ch'uya
refactor(naming): A1 — ente→arje, vista→revista, pluma→fana
1#!/usr/bin/env python3
2"""
3Rename akasha → chasqui (2026-05-19, segunda iteración del día).
4
5El rename de la mañana (nouser → akasha) se revierte parcialmente: el
6explorador de nómadas pasa a chasqui (Inca: mensajero corredor) para
7liberar el nombre `akasha` que queda reservado para el módulo de notas
8`akashi` (planeado, sin código aún).
9
10Reusa el patrón de scripts/reorg.py:
11 1. git mv directorios
12 2. package names en Cargo.toml
13 3. paths relativos en Cargo.toml
14 4. imports `use akasha_::` en .rs
15 5. workspace root Cargo.toml
16
17Uso:
18 python3 scripts/rename-chasqui.py --dry-run
19 python3 scripts/rename-chasqui.py
20"""
21
22import os, re, subprocess, sys
23from pathlib import Path
24
25ROOT = Path("/home/sergio/brahman")
26DRY = "--dry-run" in sys.argv
27
28MOVES: dict[str, str] = {
29 "crates/modules/akasha": "crates/modules/chasqui",
30 "crates/apps/akasha-explorer": "crates/apps/chasqui-explorer",
31}
32
33# Sub-crates dentro de modules/akasha/ no se renombran (mantienen card/core/nous/...);
34# solo cambia el directorio padre y los nombres de paquete.
35
36PKG_RENAMES: dict[str, str] = {
37 "akasha-card": "chasqui-card",
38 "akasha-core": "chasqui-core",
39 "akasha-nous": "chasqui-nous",
40 "akasha-nous-mock": "chasqui-nous-mock",
41 "akasha-nous-real": "chasqui-nous-real",
42 "akasha-explorer": "chasqui-explorer",
43 # Binario umbrella (bin name = "akasha" en akasha-core/Cargo.toml)
44 "akasha": "chasqui",
45}
46
47def sh(cmd, check=True):
48 if DRY:
49 print(f" DRY: {' '.join(cmd)}")
50 return None
51 return subprocess.run(cmd, check=check, cwd=str(ROOT))
52
53def git_mv(src: str, dst: str):
54 src_p = ROOT / src
55 dst_p = ROOT / dst
56 if not src_p.exists():
57 print(f" SKIP {src} (no existe)")
58 return
59 if dst_p.exists():
60 print(f" WARN {dst} ya existe — saltando")
61 return
62 dst_p.parent.mkdir(parents=True, exist_ok=True)
63 sh(["git", "mv", src, dst])
64
65def all_cargo_tomls() -> list[Path]:
66 return [p for p in (ROOT / "crates").rglob("Cargo.toml") if "target" not in p.parts]
67
68def all_rs() -> list[Path]:
69 return [p for p in (ROOT / "crates").rglob("*.rs") if "target" not in p.parts]
70
71CURRENT_TO_OLD = {new: old for old, new in MOVES.items()}
72
73def owner_old_for(toml: Path) -> str:
74 cur = str(toml.parent.relative_to(ROOT))
75 # Match cualquier prefix mapeado
76 for new, old in CURRENT_TO_OLD.items():
77 if cur == new or cur.startswith(new + "/"):
78 return cur.replace(new, old, 1)
79 return cur
80
81def resolve_canon(base_dir: str, rel: str) -> str | None:
82 try:
83 return str((ROOT / base_dir / rel).resolve().relative_to(ROOT))
84 except ValueError:
85 return None
86
87def rewrite_paths_in_toml(toml: Path):
88 text = toml.read_text()
89 owner_old = owner_old_for(toml)
90 owner_new = str(toml.parent.relative_to(ROOT))
91
92 def map_target(old_tgt: str) -> str:
93 for old_prefix, new_prefix in MOVES.items():
94 if old_tgt == old_prefix or old_tgt.startswith(old_prefix + "/"):
95 return old_tgt.replace(old_prefix, new_prefix, 1)
96 return old_tgt
97
98 def repl(m: re.Match) -> str:
99 rel_in_file = m.group(1)
100 for base in (owner_old, owner_new):
101 tgt = resolve_canon(base, rel_in_file)
102 if tgt is None:
103 continue
104 new_tgt = map_target(tgt)
105 if (ROOT / new_tgt).exists() or new_tgt != tgt:
106 new_rel = os.path.relpath(str(ROOT / new_tgt), str(ROOT / owner_new))
107 return f'path = "{new_rel}"'
108 return m.group(0)
109
110 new_text = re.sub(r'path\s*=\s*"([^"]+)"', repl, text)
111 if new_text != text:
112 if DRY:
113 print(f" DRY paths: {toml.relative_to(ROOT)}")
114 else:
115 toml.write_text(new_text)
116
117def rewrite_pkg_names_in_toml(toml: Path):
118 text = toml.read_text()
119 orig = text
120 for old, new in sorted(PKG_RENAMES.items(), key=lambda kv: -len(kv[0])):
121 text = re.sub(rf'(\bname\s*=\s*)"{re.escape(old)}"', rf'\1"{new}"', text)
122 text = re.sub(rf'(\bpackage\s*=\s*)"{re.escape(old)}"', rf'\1"{new}"', text)
123 text = re.sub(rf'^([ \t]*){re.escape(old)}(\s*=)', rf'\1{new}\2',
124 text, flags=re.MULTILINE)
125 text = re.sub(rf'"dep:{re.escape(old)}"', f'"dep:{new}"', text)
126 text = re.sub(rf'"{re.escape(old)}/', f'"{new}/', text)
127 text = re.sub(rf'"{re.escape(old)}"', f'"{new}"', text)
128 if text != orig:
129 if DRY:
130 print(f" DRY names: {toml.relative_to(ROOT)}")
131 else:
132 toml.write_text(text)
133
134USE_RENAMES = {k.replace("-", "_"): v.replace("-", "_") for k, v in PKG_RENAMES.items()}
135
136def rewrite_imports_in_rs(rs: Path):
137 text = rs.read_text()
138 orig = text
139 for old, new in USE_RENAMES.items():
140 text = re.sub(rf'(?<![A-Za-z0-9_]){re.escape(old)}(?![A-Za-z0-9_])', new, text)
141 if text != orig:
142 if DRY:
143 print(f" DRY imports: {rs.relative_to(ROOT)}")
144 else:
145 rs.write_text(text)
146
147def rewrite_workspace_toml():
148 p = ROOT / "Cargo.toml"
149 text = p.read_text()
150 orig = text
151 for old, new in MOVES.items():
152 text = text.replace(f'"{old}"', f'"{new}"')
153 text = text.replace(f'"{old}/', f'"{new}/')
154 for old, new in PKG_RENAMES.items():
155 text = re.sub(rf'^([ \t]*){re.escape(old)}(\s*=)', rf'\1{new}\2',
156 text, flags=re.MULTILINE)
157 # Comentario del workspace que dice "akasha" → "chasqui"
158 text = text.replace(
159 "# modules/akasha/ — Explorador semántico de Mónadas (era nouser)",
160 "# modules/chasqui/ — Explorador semántico de nómadas (ex-nouser, ex-akasha)"
161 )
162 if text != orig:
163 if DRY:
164 print(" DRY workspace toml")
165 else:
166 p.write_text(text)
167
168def run():
169 print(f"=== rename-chasqui.py (DRY={DRY}) ===")
170 print(f" {len(MOVES)} moves, {len(PKG_RENAMES)} pkg renames")
171
172 print("\n-- step 1: git mv --")
173 for old, new in MOVES.items():
174 git_mv(old, new)
175
176 print("\n-- step 2: package names --")
177 for toml in all_cargo_tomls():
178 rewrite_pkg_names_in_toml(toml)
179
180 print("\n-- step 3: paths relativos --")
181 for toml in all_cargo_tomls():
182 rewrite_paths_in_toml(toml)
183
184 print("\n-- step 4: imports en .rs --")
185 for rs in all_rs():
186 rewrite_imports_in_rs(rs)
187
188 print("\n-- step 5: workspace Cargo.toml --")
189 rewrite_workspace_toml()
190
191 print("\nOK")
192
193if __name__ == "__main__":
194 run()