#!/usr/bin/env python3 import sys import shlex import subprocess def run_command(cmd_str: str, progress_prefix: str = "Progress", look_for: list = ["frame=", "time=", "fps=", "Rendering frame"]) -> bool: """Runs a system command, streams its output live, and reports errors on failure.""" args = shlex.split(cmd_str) # Redirect stderr to stdout to catch all logging/progress in one stream process = subprocess.Popen( args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1 ) print(f"Executing: {cmd_str[:90]}...") # Maintain a small buffer history to display context if a crash occurs output_history = [] # Stream the output live to the terminal while True: line = process.stdout.readline() if not line and process.poll() is not None: break if line: clean_line = line.strip() output_history.append(clean_line) # Keep history for error reporting # Keep history slim by only keeping the last 20 lines if len(output_history) > 20: output_history.pop(0) # Only print updates that show progress metrics to keep terminal clean if any(metric in clean_line for metric in look_for): sys.stdout.write(f"\r[{progress_prefix}] {clean_line}") sys.stdout.flush() elif "Error" in clean_line or "failed" in clean_line: print(f"\n[Alert] {clean_line}") print("\n") # New line after process finishes # Evaluate success status success = (process.returncode == 0) if not success: print(f"❌ Command failed with exit code: {process.returncode}") print("--- Technical Error Details (Last 5 lines of output) ---") # Print the last 5 captured lines to show the exact point of failure for error_line in output_history[-5:]: print(f" > {error_line}") print("---------------------------------------------------------") return success