#!/usr/bin/env python3 import tempfile, shutil, subprocess, sys, argparse from pathlib import Path ROOT = Path(__file__).resolve().parents[1] def main(): ap = argparse.ArgumentParser() ap.add_argument("--bundle", help="Path to a specific installer zip (defaults to install/cascadingdev-.zip)") ap.add_argument("--keep", action="store_true", help="Keep temporary directory for inspection") ap.add_argument("--target", help="Write the demo repo to this path instead of a temp dir") ap.add_argument("--ramble", action="store_true", help="Run installer without --no-ramble") args = ap.parse_args() ver = (ROOT / "VERSION").read_text().strip() zip_path = Path(args.bundle) if args.bundle else (ROOT / "install" / f"cascadingdev-{ver}.zip") if not zip_path.exists(): print(f"Zip missing: {zip_path}. Run `cdev pack` first or pass --bundle."); sys.exit(2) def run_once(extract_dir: Path, target_dir: Path) -> int: shutil.unpack_archive(str(zip_path), str(extract_dir), "zip") setup = next(extract_dir.rglob("setup_cascadingdev.py")) target_dir.mkdir(parents=True, exist_ok=True) print(f"[•] Running installer from: {setup}") cmd = [sys.executable, str(setup), "--target", str(target_dir)] if not args.ramble: cmd.append("--no-ramble") rc = subprocess.call(cmd) if rc != 0: print(f"Installer exited with {rc}"); return rc # quick asserts required = [ target_dir / "process" / "policies.yml", target_dir / "Docs" / "features" / ".ai-rules.yml", target_dir / ".ai-rules.yml", target_dir / "USER_GUIDE.md", target_dir / ".git" / "hooks" / "pre-commit", ] missing = [str(p) for p in required if not p.exists()] if missing: print("Missing after install:\n " + "\n ".join(missing)); return 3 print(f"[✓] Bundle smoke OK. Demo repo: {target_dir}") return 0 if args.target: # Use a fixed location (never auto-delete). Clean if exists. target_dir = Path(args.target).expanduser().resolve() if target_dir.exists(): shutil.rmtree(target_dir) extract_dir = target_dir.parent / (target_dir.name + "-bundle") if extract_dir.exists(): shutil.rmtree(extract_dir) extract_dir.mkdir(parents=True, exist_ok=True) rc = run_once(extract_dir, target_dir) print(f"[i] Extracted bundle kept at: {extract_dir}") return rc # Temp-mode (default) with tempfile.TemporaryDirectory(prefix="cd-bundle-") as tmp: tmpdir = Path(tmp) extract_dir = tmpdir / "bundle" target_dir = tmpdir / "demo-repo" rc = run_once(extract_dir, target_dir) if args.keep: print(f"[i] Keeping temp dir: {tmpdir}") print(" You can inspect it now; press Enter to clean up...") try: input() except EOFError: pass return rc # auto-clean return rc if __name__ == "__main__": sys.exit(main())