Main CLI application class encapsulating all Typer functionality.
This class manages the entire CLI interface, including:
- Command registration and routing
- Global option handling
- Error handling and exception management
- Application lifecycle management
Source code in src/appimage_updater/cli/application.py
| def __init__(self) -> None:
"""Initialize the CLI application."""
self.app = typer.Typer(
name="appimage-updater",
help="AppImage update manager",
pretty_exceptions_enable=False, # Prevent stack traces for user errors
)
self.global_state = GlobalState()
self.console = Console()
# Configure logging with INFO level by default to prevent debug messages during init
configure_logging(debug=False)
# Register all command handlers (but suppress debug logs during registration)
self._register_handlers()
# Setup global callbacks
self._setup_global_callbacks()
|
app = typer.Typer(name='appimage-updater', help='AppImage update manager', pretty_exceptions_enable=False)
instance-attribute
console = Console()
instance-attribute
global_state = GlobalState()
instance-attribute
run()
Run the CLI application with proper exception handling.
Source code in src/appimage_updater/cli/application.py
| def run(self) -> None:
"""Run the CLI application with proper exception handling."""
# Override sys.excepthook to prevent stack traces from being displayed
def clean_excepthook(exc_type: type[BaseException], exc_value: BaseException, _exc_traceback: Any) -> None:
"""Clean exception handler that doesn't show stack traces for user errors."""
# For typer.Exit and click.exceptions.Exit, just exit cleanly
if exc_type.__name__ in ("Exit", "ClickException") or issubclass(exc_type, SystemExit):
if hasattr(exc_value, "exit_code"):
sys.exit(exc_value.exit_code)
else:
sys.exit(getattr(exc_value, "code", 1))
# For other exceptions, show a clean error message without stack trace
console_ = Console(stderr=True)
console_.print(f"[red]Error: {exc_value}[/red]")
sys.exit(1)
# Install our clean exception handler
# Note: excepthook assignment is intentional for global error handling
sys.excepthook = clean_excepthook
try:
self.app()
except (typer.Exit, SystemExit) as e:
# Handle exits cleanly without showing stack trace
sys.exit(getattr(e, "exit_code", getattr(e, "code", 1)))
except KeyboardInterrupt:
# Handle Ctrl+C gracefully
console = Console(stderr=True)
console.print("\n[yellow]Operation cancelled by user.[/yellow]")
sys.exit(130) # Standard exit code for SIGINT
except Exception as e:
# Handle unexpected exceptions with clean error message
console = Console(stderr=True)
console.print(f"[red]Error: {e}[/red]")
sys.exit(1)
|