diff --git a/src/launchpad/cli.py b/src/launchpad/cli.py index 2da831ab..78accaf3 100644 --- a/src/launchpad/cli.py +++ b/src/launchpad/cli.py @@ -7,6 +7,7 @@ import click from . import __version__ +from .distribution.cli import distribution_command from .service import run_service from .size.cli import size_command from .utils.console import console @@ -81,6 +82,7 @@ def serve(host: str, port: int, mode: str | None, verbose: bool) -> None: cli.add_command(size_command) +cli.add_command(distribution_command) def main() -> None: diff --git a/src/launchpad/distribution/__init__.py b/src/launchpad/distribution/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/launchpad/distribution/cli.py b/src/launchpad/distribution/cli.py new file mode 100644 index 00000000..bc92b5b5 --- /dev/null +++ b/src/launchpad/distribution/cli.py @@ -0,0 +1,45 @@ +from __future__ import annotations + +from pathlib import Path + +import click + +from ..utils.android.apksigner import Apksigner, ApksignerError +from ..utils.console import console +from ..utils.logging import setup_logging + + +@click.command("distribution") +@click.argument("apk_path", type=click.Path(exists=True, path_type=Path)) +@click.option("--verbose", "-v", is_flag=True, help="Enable verbose logging output.") +def distribution_command(apk_path: Path, verbose: bool) -> None: + """Print certificate information for an APK file. + + Uses apksigner to extract and display the certificate information + from the specified APK file. + """ + setup_logging(verbose=verbose, quiet=False) + + if not apk_path.suffix.lower() == ".apk": + console.print(f"[bold red]Error:[/bold red] File must be an APK file, got: {apk_path.suffix}") + raise click.Abort() + + console.print(f"[bold blue]Analyzing APK certificate:[/bold blue] {apk_path}") + + try: + apksigner = Apksigner() + cert_info = apksigner.get_certs(apk_path) + console.print("\n[bold green]Certificate Information:[/bold green]") + console.print(cert_info) + except ApksignerError as e: + console.print(f"[bold red]Error running apksigner:[/bold red] {e}") + if verbose: + console.print(f"Return code: {e.returncode}") + console.print(f"Stdout: {e.stdout}") + console.print(f"Stderr: {e.stderr}") + raise click.Abort() + except Exception as e: + console.print(f"[bold red]Unexpected error:[/bold red] {e}") + if verbose: + console.print_exception() + raise click.Abort()