From 4b49797b4d57c2d2cf63472636622a7a6280a38e Mon Sep 17 00:00:00 2001 From: historia Date: Tue, 25 Aug 2026 18:10:08 -0400 Subject: feat: no console drop when uninstalling backends --- app/backends/common.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'app/backends/common.py') diff --git a/app/backends/common.py b/app/backends/common.py index cb573c3..10b4ccf 100644 --- a/app/backends/common.py +++ b/app/backends/common.py @@ -71,6 +71,18 @@ def drain_post_tui_notices() -> List[str]: return notices +def cancel_requested(cancel) -> bool: + """True when CANCEL (a ``threading.Event``) is given and set. + + Shared guard for the multi-phase uninstall actions: cancellation is + honored only between phases (stop servers / pip / delete files), so a + phase that already started always runs to completion and an uninstall + never tears halfway. Callers return 130 when this fires before a + pending phase. + """ + return cancel is not None and cancel.is_set() + + def normalize_dir_arg(value: str) -> Path: """Normalize a user-supplied path argument. @@ -301,8 +313,7 @@ def run_console_subprocess(argv: List[str], cwd: Optional[Path] = None, """Run a subprocess, streaming output to the console or to EMIT. With EMIT None the child inherits the real terminal and its output - appears normally (used by the non-interactive CLI paths and the quick - ``tui.suspend`` actions like uninstall). With EMIT given (a + appears normally (the non-interactive CLI paths). With EMIT given (a ``callable(str)``) the child's stdout/stderr are merged, read line by line (splitting on both ``\\n`` and ``\\r`` so carriage-return progress updates like git's or tqdm's surface as lines), and each line is passed @@ -459,11 +470,13 @@ def pip_install(packages: List[str]) -> int: return envs.pip_install(packages) -def pip_uninstall(packages: List[str]) -> int: +def pip_uninstall(packages: List[str], *, emit=None) -> int: """pip uninstall PACKAGES from the managed venv. Returns exit code. Delegates to ``backends.envs.pip_uninstall`` (local import to avoid a - circular import). Used by the backends' ``uninstall`` action. + circular import). Used by the backends' ``uninstall`` action. With EMIT + given (the in-TUI task view) pip runs piped, streaming into EMIT, so + its output never touches the terminal behind curses. """ from backends import envs - return envs.pip_uninstall(packages) + return envs.pip_uninstall(packages, emit=emit) -- cgit v1.2.3