Skip to content

Commit b9445b8

Browse files
authored
Add a platform independent size analysis method (#52)
This adds a new method: do_size(input_file: BinaryIO) -> BaseAnalysisResult - Which takes a file-like input containing an artifact - Uses ArtifactFactory to create an Artifact - Creates the correct Analyzer - Returns the result of the analyzer The point of this is to minimize the amount of boiler plate required in getsentry/sentry and the launchpad service when adding a new kind of artifact to be analyzed. Ideally the code path for {Android,Apple,Unity,.so,.exe,...} would be almost identical until it gets to `do_size`. Also add a matching CLI command for this `launchpad size`. This is done in a separate file (src/launchpad/size/cli.py) showing how we could split up the subcommand definitions and have them live near the code they use as opposed to all have to be in a large monolithic file. This replaces the existing size commands. While here also do a few other small cleanups: - Move `Console()` into `console.py` so we make only one instance for the whole project (as suggested in the rich docs). - Fix a few incorrect references to Android in artifact_factory. - Add the ability for ArtifactFactory to take file-like objects as input.
1 parent 84b92aa commit b9445b8

File tree

10 files changed

+327
-339
lines changed

10 files changed

+327
-339
lines changed

src/launchpad/analyzers/android.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import time
44
from datetime import datetime, timezone
5+
from typing import Any
56

67
from ..artifacts.android.aab import AAB
78
from ..artifacts.android.apk import APK
@@ -25,6 +26,9 @@
2526
class AndroidAnalyzer:
2627
"""Analyzer for Android apps (.apk, .aab files)."""
2728

29+
def __init__(self, **_: Any) -> None:
30+
pass
31+
2832
def analyze(self, artifact: AndroidArtifact) -> AndroidAnalysisResults:
2933
manifest_dict = artifact.get_manifest().model_dump()
3034
start_time = time.time()

src/launchpad/artifacts/artifact_factory.py

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from io import BytesIO
22
from pathlib import Path
3+
from typing import BinaryIO
34
from zipfile import ZipFile
45

56
from .android.aab import AAB
@@ -18,20 +19,50 @@ def from_path(path: Path) -> Artifact:
1819
"""Create appropriate Artifact from file path.
1920
2021
Args:
21-
path: Path to the Android artifact file
22+
path: Path to the artifact file
2223
2324
Returns:
2425
Appropriate Artifact instance
2526
2627
Raises:
2728
FileNotFoundError: If path does not exist
28-
ValueError: If file is not a valid Android artifact
29+
ValueError: If file is not a valid artifact
2930
"""
3031
if not path.is_file():
3132
raise FileNotFoundError(f"Path is not a file: {path}")
3233

3334
content = path.read_bytes()
35+
return ArtifactFactory.from_bytes(content)
3436

37+
@staticmethod
38+
def from_file(file: BinaryIO) -> Artifact:
39+
"""Create appropriate Artifact from file.
40+
41+
Args:
42+
file: The artifact file
43+
44+
Returns:
45+
Appropriate Artifact instance
46+
47+
Raises:
48+
ValueError: If file is not a valid artifact
49+
"""
50+
content = file.read()
51+
return ArtifactFactory.from_bytes(content)
52+
53+
@staticmethod
54+
def from_bytes(content: bytes) -> Artifact:
55+
"""Create appropriate Artifact from file path.
56+
57+
Args:
58+
content: bytes of the artifact
59+
60+
Returns:
61+
Appropriate Artifact instance
62+
63+
Raises:
64+
ValueError: If file is not a valid artifact
65+
"""
3566
# Check if it's a zip file by looking at magic bytes
3667
if content.startswith(b"PK\x03\x04"):
3768
# Check if zip contains a single APK (ZippedAPK)
@@ -70,4 +101,4 @@ def from_path(path: Path) -> Artifact:
70101
except Exception:
71102
pass
72103

73-
raise ValueError(f"File is not a supported Android artifact: {path}")
104+
raise ValueError("Input is not a supported artifact")

0 commit comments

Comments
 (0)