From 319b95045a8f17a0d5f4d5e6e1fc7d631860e47c Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 28 Jul 2025 14:55:03 +0200 Subject: [PATCH 1/5] Add ability to check certificate. --- src/launchpad/cli.py | 2 ++ src/launchpad/distribution/__init__.py | 5 +++ src/launchpad/distribution/cli.py | 47 ++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 src/launchpad/distribution/__init__.py create mode 100644 src/launchpad/distribution/cli.py diff --git a/src/launchpad/cli.py b/src/launchpad/cli.py index 2da831ab..9a9af1ba 100644 --- a/src/launchpad/cli.py +++ b/src/launchpad/cli.py @@ -7,6 +7,7 @@ import click from . import __version__ +from .distribution 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..64d5b54b --- /dev/null +++ b/src/launchpad/distribution/__init__.py @@ -0,0 +1,5 @@ +"""Distribution module.""" + +from .cli import distribution_command + +__all__ = ["distribution_command"] diff --git a/src/launchpad/distribution/cli.py b/src/launchpad/distribution/cli.py new file mode 100644 index 00000000..dee8702b --- /dev/null +++ b/src/launchpad/distribution/cli.py @@ -0,0 +1,47 @@ +"""Distribution command for analyzing APK certificates.""" + +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() +@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() From 406af9b64dae914165bc59acca2b4e96a0ffe9b2 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 28 Jul 2025 15:43:25 +0200 Subject: [PATCH 2/5] empty init file --- src/launchpad/distribution/__init__.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/launchpad/distribution/__init__.py b/src/launchpad/distribution/__init__.py index 64d5b54b..e69de29b 100644 --- a/src/launchpad/distribution/__init__.py +++ b/src/launchpad/distribution/__init__.py @@ -1,5 +0,0 @@ -"""Distribution module.""" - -from .cli import distribution_command - -__all__ = ["distribution_command"] From 87434e046d65895efed6004e6af680898edf844a Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 28 Jul 2025 15:45:00 +0200 Subject: [PATCH 3/5] remove comment --- src/launchpad/distribution/cli.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/launchpad/distribution/cli.py b/src/launchpad/distribution/cli.py index dee8702b..8dee2e0b 100644 --- a/src/launchpad/distribution/cli.py +++ b/src/launchpad/distribution/cli.py @@ -1,5 +1,3 @@ -"""Distribution command for analyzing APK certificates.""" - from __future__ import annotations from pathlib import Path From 26980b744ee6763d4d078971447850cd8f40df7e Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 28 Jul 2025 15:46:58 +0200 Subject: [PATCH 4/5] Fix imports --- src/launchpad/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/launchpad/cli.py b/src/launchpad/cli.py index 9a9af1ba..78accaf3 100644 --- a/src/launchpad/cli.py +++ b/src/launchpad/cli.py @@ -7,7 +7,7 @@ import click from . import __version__ -from .distribution import distribution_command +from .distribution.cli import distribution_command from .service import run_service from .size.cli import size_command from .utils.console import console From b19de0c6dadd9abf87f49c7a27706c4b3bb27f71 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 28 Jul 2025 15:48:46 +0200 Subject: [PATCH 5/5] Add distribution command --- src/launchpad/distribution/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/launchpad/distribution/cli.py b/src/launchpad/distribution/cli.py index 8dee2e0b..bc92b5b5 100644 --- a/src/launchpad/distribution/cli.py +++ b/src/launchpad/distribution/cli.py @@ -9,7 +9,7 @@ from ..utils.logging import setup_logging -@click.command() +@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: