tawasuyu

tawasuyu/brahman

Rust 332TOML 127JSON 17Markdown 154710 Sutichaykuna

⎇ 88a3aae7626ce823f3142cfbefaa834b39ceb62f scripts/rename-chasqui.py Python · 194 siq'ikuna · 6.4 KB Ñawpa willay Pi imata llamkarqan ch'uya

refactor(naming): A1 — ente→arje, vista→revista, pluma→fana b83d40a83 · sergio ·

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()