Skip to content

application

appimage_updater.cli.application

Main CLI application class for AppImage Updater.

AppImageUpdaterCLI()

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)

GlobalState

Global state for CLI options that need to be accessible across commands.

debug = False class-attribute instance-attribute