#!/usr/bin/env python3 """ Rename akasha → chasqui (2026-05-19, segunda iteración del día). El rename de la mañana (nouser → akasha) se revierte parcialmente: el explorador de nómadas pasa a chasqui (Inca: mensajero corredor) para liberar el nombre `akasha` que queda reservado para el módulo de notas `akashi` (planeado, sin código aún). Reusa el patrón de scripts/reorg.py: 1. git mv directorios 2. package names en Cargo.toml 3. paths relativos en Cargo.toml 4. imports `use akasha_::` en .rs 5. workspace root Cargo.toml Uso: python3 scripts/rename-chasqui.py --dry-run python3 scripts/rename-chasqui.py """ import os, re, subprocess, sys from pathlib import Path ROOT = Path("/home/sergio/brahman") DRY = "--dry-run" in sys.argv MOVES: dict[str, str] = { "crates/modules/akasha": "crates/modules/chasqui", "crates/apps/akasha-explorer": "crates/apps/chasqui-explorer", } # Sub-crates dentro de modules/akasha/ no se renombran (mantienen card/core/nous/...); # solo cambia el directorio padre y los nombres de paquete. PKG_RENAMES: dict[str, str] = { "akasha-card": "chasqui-card", "akasha-core": "chasqui-core", "akasha-nous": "chasqui-nous", "akasha-nous-mock": "chasqui-nous-mock", "akasha-nous-real": "chasqui-nous-real", "akasha-explorer": "chasqui-explorer", # Binario umbrella (bin name = "akasha" en akasha-core/Cargo.toml) "akasha": "chasqui", } def sh(cmd, check=True): if DRY: print(f" DRY: {' '.join(cmd)}") return None return subprocess.run(cmd, check=check, cwd=str(ROOT)) def git_mv(src: str, dst: str): src_p = ROOT / src dst_p = ROOT / dst if not src_p.exists(): print(f" SKIP {src} (no existe)") return if dst_p.exists(): print(f" WARN {dst} ya existe — saltando") return dst_p.parent.mkdir(parents=True, exist_ok=True) sh(["git", "mv", src, dst]) def all_cargo_tomls() -> list[Path]: return [p for p in (ROOT / "crates").rglob("Cargo.toml") if "target" not in p.parts] def all_rs() -> list[Path]: return [p for p in (ROOT / "crates").rglob("*.rs") if "target" not in p.parts] CURRENT_TO_OLD = {new: old for old, new in MOVES.items()} def owner_old_for(toml: Path) -> str: cur = str(toml.parent.relative_to(ROOT)) # Match cualquier prefix mapeado for new, old in CURRENT_TO_OLD.items(): if cur == new or cur.startswith(new + "/"): return cur.replace(new, old, 1) return cur def resolve_canon(base_dir: str, rel: str) -> str | None: try: return str((ROOT / base_dir / rel).resolve().relative_to(ROOT)) except ValueError: return None def rewrite_paths_in_toml(toml: Path): text = toml.read_text() owner_old = owner_old_for(toml) owner_new = str(toml.parent.relative_to(ROOT)) def map_target(old_tgt: str) -> str: for old_prefix, new_prefix in MOVES.items(): if old_tgt == old_prefix or old_tgt.startswith(old_prefix + "/"): return old_tgt.replace(old_prefix, new_prefix, 1) return old_tgt def repl(m: re.Match) -> str: rel_in_file = m.group(1) for base in (owner_old, owner_new): tgt = resolve_canon(base, rel_in_file) if tgt is None: continue new_tgt = map_target(tgt) if (ROOT / new_tgt).exists() or new_tgt != tgt: new_rel = os.path.relpath(str(ROOT / new_tgt), str(ROOT / owner_new)) return f'path = "{new_rel}"' return m.group(0) new_text = re.sub(r'path\s*=\s*"([^"]+)"', repl, text) if new_text != text: if DRY: print(f" DRY paths: {toml.relative_to(ROOT)}") else: toml.write_text(new_text) def rewrite_pkg_names_in_toml(toml: Path): text = toml.read_text() orig = text for old, new in sorted(PKG_RENAMES.items(), key=lambda kv: -len(kv[0])): text = re.sub(rf'(\bname\s*=\s*)"{re.escape(old)}"', rf'\1"{new}"', text) text = re.sub(rf'(\bpackage\s*=\s*)"{re.escape(old)}"', rf'\1"{new}"', text) text = re.sub(rf'^([ \t]*){re.escape(old)}(\s*=)', rf'\1{new}\2', text, flags=re.MULTILINE) text = re.sub(rf'"dep:{re.escape(old)}"', f'"dep:{new}"', text) text = re.sub(rf'"{re.escape(old)}/', f'"{new}/', text) text = re.sub(rf'"{re.escape(old)}"', f'"{new}"', text) if text != orig: if DRY: print(f" DRY names: {toml.relative_to(ROOT)}") else: toml.write_text(text) USE_RENAMES = {k.replace("-", "_"): v.replace("-", "_") for k, v in PKG_RENAMES.items()} def rewrite_imports_in_rs(rs: Path): text = rs.read_text() orig = text for old, new in USE_RENAMES.items(): text = re.sub(rf'(?