@@ -204,10 +204,10 @@ def _format_version(value) -> str:
204204 percent = completed / total if total else 1.0
205205 filled = int (percent * bar_len )
206206 bar = "█" * filled + "-" * (bar_len - filled )
207- sys .stdout .write (
208- f"Upgrading: [{ bar } ] { completed } /{ total } tools processed"
207+ # Use \r to ensure we start at the beginning of the line
208+ typer .echo (
209+ f"Upgrading: [{ bar } ] { completed } /{ total } tools processed" , nl = False
209210 )
210- sys .stdout .flush ()
211211
212212 # First, count the skipped tools as completed
213213 for _tool_name , action , _ in prepared_tools :
@@ -217,10 +217,11 @@ def _format_version(value) -> str:
217217 percent = completed / total if total else 1.0
218218 filled = int (percent * bar_len )
219219 bar = "█" * filled + "-" * (bar_len - filled )
220- sys .stdout .write (
221- f"\r Upgrading: [{ bar } ] { completed } /{ total } tools processed"
220+ # Clear line and update progress
221+ typer .echo (
222+ f"\033 [2K\r Upgrading: [{ bar } ] { completed } /{ total } tools processed" ,
223+ nl = False ,
222224 )
223- sys .stdout .flush ()
224225 time .sleep (
225226 0.05
226227 ) # Small delay to make incremental progress visible
@@ -269,21 +270,20 @@ def _format_version(value) -> str:
269270 percent = completed / total if total else 1.0
270271 filled = int (percent * bar_len )
271272 bar = "█" * filled + "-" * (bar_len - filled )
272- sys .stdout .write (
273- f"\r Upgrading: [{ bar } ] { completed } /{ total } tools processed"
273+ typer .echo (
274+ f"\033 [2K\r Upgrading: [{ bar } ] { completed } /{ total } tools processed" ,
275+ nl = False ,
274276 )
275- sys .stdout .flush ()
276277 else :
277278 # Compact per-line update, keep only minimal text
278279 typer .echo (f" [{ completed } /{ total } ] tools processed" )
279280
280281 if is_tty :
281- # Finish the progress bar line
282- sys .stdout .write ("\n " )
283- sys .stdout .flush ()
282+ # Finish the progress bar line and ensure clean terminal state
283+ typer .echo ("" )
284284
285285 # Display results for ALL upgradeable tools, including ones skipped by pre-check
286- typer .echo (f"\n { Colors .GREEN } Upgrade results:{ Colors .RESET } " )
286+ typer .echo (f"{ Colors .GREEN } Upgrade results:{ Colors .RESET } " )
287287 for tool_name in upgradeable_tools .keys ():
288288 before_v = _format_version (pre_versions .get (tool_name , "unknown" ))
289289
@@ -453,32 +453,11 @@ def _perform_upgrade_task(tool_name, tool, install_cmd, quiet: bool = False):
453453 if not quiet :
454454 # typer.echo(f"{Colors.BLUE}Starting upgrade for {tool_name}...{Colors.RESET}")
455455 pass
456- # If quiet mode requested, ask tool to run quieter by passing a wrapper command
457- if quiet :
458- # Try to use script command for quiet execution, but fall back if it doesn't work
459- # Different Unix systems have different script command syntax
460- import subprocess
461456
462- try :
463- # Test if script command supports -q -c syntax (macOS style)
464- subprocess .run (
465- ["script" , "-q" , "-c" , "echo test" ],
466- capture_output = True ,
467- text = True ,
468- timeout = 1 ,
469- )
470- # If we get here, script -q -c works
471- wrapper_cmd = f"script -q -c { install_cmd !r} /dev/null"
472- except (
473- subprocess .TimeoutExpired ,
474- subprocess .CalledProcessError ,
475- FileNotFoundError ,
476- ):
477- # script command doesn't support -q -c, or doesn't exist, fall back to redirection
478- wrapper_cmd = f"{ install_cmd } >/dev/null 2>&1"
479- result = tool ._perform_upgrade (desc , wrapper_cmd )
480- else :
481- result = tool ._perform_upgrade (desc , install_cmd )
457+ # Perform the upgrade
458+ # Note: CommandRunner (used by _perform_upgrade) captures output, so it is inherently quiet.
459+ # We do not need to wrap commands in 'script' or redirects which can corrupt terminal state.
460+ result = tool ._perform_upgrade (desc , install_cmd )
482461 return result
483462 except Exception as e :
484463 # Do not print exception stack traces to stderr; return structured failure
0 commit comments