diff --git a/readme.md b/readme.md index 2bd5426..3e7d56c 100644 --- a/readme.md +++ b/readme.md @@ -79,6 +79,9 @@ For an existing checkout, run this from the repository root: Use `-NoMpv`, `-NoDeno`, or `-NoPlaywright` to skip optional external runtime installation when those components are already managed separately. +The installer now waits for Enter before closing. Pass `-NoPause` for scripted +automation. + Notes: - The bootstrap script creates `.venv`, installs the project, and exposes the `mm` and `medeia` console commands. diff --git a/scripts/bootstrap.ps1 b/scripts/bootstrap.ps1 index 39a7262..ebda49a 100644 --- a/scripts/bootstrap.ps1 +++ b/scripts/bootstrap.ps1 @@ -28,7 +28,8 @@ param( [string]$PlaywrightBrowsers = "chromium", [switch]$FixUrllib3, [switch]$RemovePth, - [switch]$Quiet + [switch]$Quiet, + [switch]$NoPause ) $ErrorActionPreference = "Stop" @@ -71,6 +72,7 @@ if ($CreateDesktopShortcut -or $CreateStartMenuShortcut -or $FixUrllib3 -or $Rem } try { + $exitCode = 1 $pythonCommand = $null if ($Python) { $pythonCommand = $Python @@ -90,10 +92,25 @@ try { & $pythonCommand $bootstrapPath @pythonArgs } $exitCode = $LASTEXITCODE + if (-not $Quiet) { + if ($exitCode -eq 0) { + Write-Host "Installation finished successfully." -ForegroundColor Green + } else { + Write-Host "Installation exited with code $exitCode." -ForegroundColor Red + } + } } finally { if ($temporaryBootstrap -and (Test-Path $bootstrapPath)) { Remove-Item -LiteralPath $bootstrapPath -Force -ErrorAction SilentlyContinue } } +if (-not $NoPause -and -not $Quiet -and [Environment]::UserInteractive) { + try { + [void](Read-Host "Press Enter to close installer") + } catch { + # Ignore host/input edge cases and continue to exit. + } +} + exit $exitCode \ No newline at end of file diff --git a/scripts/bootstrap.py b/scripts/bootstrap.py index 4121657..7a0afc7 100644 --- a/scripts/bootstrap.py +++ b/scripts/bootstrap.py @@ -134,28 +134,14 @@ class ProgressBar: self.current += 1 if self.quiet: return - - term_width = shutil.get_terminal_size((80, 20)).columns percent = int(100 * (self.current / self.total)) filled = int(self.bar_width * self.current // self.total) bar = "█" * filled + "░" * (self.bar_width - filled) - - # Overwrite previous bar/label by moving up if not the first step - if self.current > 1: - sys.stdout.write("\033[2A") - - bar_line = f"[{bar}]" - info_line = f"{percent}% | {step_name}" - - sys.stdout.write(f"\r{bar_line.center(term_width)}\n") - # Clear line and print info line centered - sys.stdout.write(f"\r\033[K{info_line.center(term_width)}\r") - sys.stdout.flush() - - if self.current == self.total: - sys.stdout.write("\n") - sys.stdout.flush() + + # Keep progress output append-only for terminals that do not reliably + # handle cursor-up ANSI control sequences. + print(f"[{bar}] {percent:>3}% | {step_name}") LOGO = r""" @@ -1537,9 +1523,12 @@ def main() -> int: pb = ProgressBar(total_steps, quiet=args.quiet or args.debug) - def _run_cmd(cmd: list[str], cwd: Optional[Path] = None): + def _run_cmd(cmd: list[str], cwd: Optional[Path] = None, context: str = ""): """Helper to run commands with shared settings.""" - run(cmd, quiet=not args.debug, debug=args.debug, cwd=cwd) + if not args.quiet and context: + print(f"[working] {context}") + # In normal mode, stream subprocess output so users can see activity. + run(cmd, quiet=(args.quiet and not args.debug), debug=args.debug, cwd=cwd) # Opinionated: always create or use a local venv at the project root (.venv) venv_dir = repo_root / ".venv" @@ -1610,12 +1599,15 @@ def main() -> int: # Playwright browser install (short-circuit) pb.update("Setting up Playwright and browsers...") if not playwright_package_installed(venv_python): - _run_cmd([str(venv_python), "-m", "pip", "install", "--no-cache-dir", "playwright"]) + _run_cmd( + [str(venv_python), "-m", "pip", "install", "--no-cache-dir", "playwright"], + context="Installing Playwright package", + ) try: cmd = _build_playwright_install_cmd(args.browsers) cmd[0] = str(venv_python) - _run_cmd(cmd) + _run_cmd(cmd, context="Installing Playwright browsers") except Exception as exc: print(f"Error: {exc}", file=sys.stderr) return 2 @@ -1635,7 +1627,8 @@ def main() -> int: "pip", "setuptools", "wheel", - ] + ], + context="Upgrading pip, setuptools, and wheel", ) # 4. Core Dependencies @@ -1643,18 +1636,24 @@ def main() -> int: if should_install_deps: pb.update("Installing core dependencies...") if req_file.exists(): - _run_cmd([str(venv_python), "-m", "pip", "install", "--no-cache-dir", "-r", str(req_file)]) + _run_cmd( + [str(venv_python), "-m", "pip", "install", "--no-cache-dir", "-r", str(req_file)], + context=f"Installing dependency set from {req_file}", + ) # 5. Playwright Setup if should_install_playwright: pb.update("Setting up Playwright and browsers...") if not playwright_package_installed(venv_python): - _run_cmd([str(venv_python), "-m", "pip", "install", "--no-cache-dir", "playwright"]) + _run_cmd( + [str(venv_python), "-m", "pip", "install", "--no-cache-dir", "playwright"], + context="Installing Playwright package", + ) try: cmd = _build_playwright_install_cmd(args.browsers) cmd[0] = str(venv_python) - _run_cmd(cmd) + _run_cmd(cmd, context="Installing Playwright browsers") except Exception: pass @@ -1674,7 +1673,7 @@ def main() -> int: project_cmd.extend(["-e", str(repo_root / "scripts")]) else: project_cmd.append(str(repo_root / "scripts")) - _run_cmd(project_cmd) + _run_cmd(project_cmd, context="Installing Medios-Macina package") # 7. CLI Verification pb.update("Verifying CLI configuration...") @@ -2248,10 +2247,11 @@ if (Test-Path (Join-Path $repo 'CLI.py')) { _install_user_shims(repo_root) if not args.quiet: - os.system('cls' if os.name == 'nt' else 'clear') print() - print("launch command from terminal: mm") - print("inside the app: .config") + print("Installation completed successfully.") + print(f"Environment path: {venv_dir}") + print("Launch command from terminal: mm") + print("Inside the app: .config") print() return 0