Skip to content

Commit 8bb5f86

Browse files
runningcodeclaude
andcommitted
refactor: Remove duplicate tooling metadata extraction (EME-606)
Removed duplicate metadata extraction logic from artifact_processor.py since the tooling versions are already extracted by the platform analyzers using the dedicated metadata_extractor.py utility. The values are available via the app_info object, eliminating the need for redundant extraction. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 0cfd711 commit 8bb5f86

File tree

6 files changed

+25
-156
lines changed

6 files changed

+25
-156
lines changed

src/launchpad/api/update_api_models.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,12 @@ class UpdateData(BaseModel):
6464
android_app_info: Optional[AndroidAppInfo] = None
6565
dequeued_at: Optional[datetime] = Field(None, description="Timestamp when message was dequeued from Kafka")
6666
cli_version: Optional[str] = Field(None, description="sentry-cli version extracted from .sentry-cli-metadata.txt")
67-
fastlane_plugin_version: Optional[str] = Field(None, description="Fastlane plugin version extracted from .sentry-cli-metadata.txt")
68-
gradle_plugin_version: Optional[str] = Field(None, description="Gradle plugin version extracted from .sentry-cli-metadata.txt")
67+
fastlane_plugin_version: Optional[str] = Field(
68+
None, description="Fastlane plugin version extracted from .sentry-cli-metadata.txt"
69+
)
70+
gradle_plugin_version: Optional[str] = Field(
71+
None, description="Gradle plugin version extracted from .sentry-cli-metadata.txt"
72+
)
6973

7074
@field_serializer("dequeued_at")
7175
def serialize_datetime(self, dt: datetime | None) -> str | None:

src/launchpad/artifact_processor.py

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -411,41 +411,6 @@ def _update_size_error(
411411
except SentryClientError:
412412
logger.exception(f"Failed to update artifact with error {message}")
413413

414-
def _extract_tooling_versions(self, artifact: Artifact) -> Dict[str, str | None]:
415-
"""Extract tooling version information from the artifact zip file.
416-
417-
Looks for metadata files like .sentry-cli-metadata.txt in the zip
418-
and extracts version information.
419-
420-
Returns:
421-
Dict with keys: sentry_cli_version, fastlane_plugin_version, gradle_plugin_version
422-
"""
423-
import zipfile
424-
425-
versions = {
426-
"sentry_cli_version": None,
427-
"fastlane_plugin_version": None,
428-
"gradle_plugin_version": None,
429-
}
430-
431-
try:
432-
with zipfile.ZipFile(artifact.path, "r") as zf:
433-
# Look for .sentry-cli-metadata.txt in the root of the zip
434-
if ".sentry-cli-metadata.txt" in zf.namelist():
435-
with zf.open(".sentry-cli-metadata.txt") as f:
436-
content = f.read().decode("utf-8")
437-
# Parse format: sentry-cli-version: {version}
438-
for line in content.strip().split("\n"):
439-
if line.startswith("sentry-cli-version:"):
440-
version = line.split(":", 1)[1].strip()
441-
versions["sentry_cli_version"] = version
442-
logger.debug(f"Extracted sentry-cli version: {version}")
443-
break
444-
except Exception as e:
445-
logger.debug(f"Could not extract tooling versions: {e}")
446-
447-
return versions
448-
449414
def _prepare_update_data(
450415
self,
451416
app_info: AppleAppInfo | BaseAppInfo,
@@ -485,9 +450,6 @@ def _get_artifact_type(artifact: Artifact) -> ArtifactType:
485450
has_proguard_mapping=app_info.has_proguard_mapping,
486451
)
487452

488-
# Extract tooling versions from the artifact metadata
489-
tooling_versions = self._extract_tooling_versions(artifact)
490-
491453
update_data = UpdateData(
492454
app_name=app_info.name,
493455
app_id=app_info.app_id,

src/launchpad/size/models/common.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@ class BaseAppInfo(BaseModel):
2929
build: str = Field(..., description="Build number")
3030
app_id: str = Field(..., description="App ID (bundle id on iOS, package name on Android)")
3131
cli_version: str | None = Field(None, description="sentry-cli version extracted from .sentry-cli-metadata.txt")
32-
fastlane_plugin_version: str | None = Field(None, description="Fastlane plugin version extracted from .sentry-cli-metadata.txt")
33-
gradle_plugin_version: str | None = Field(None, description="Gradle plugin version extracted from .sentry-cli-metadata.txt")
32+
fastlane_plugin_version: str | None = Field(
33+
None, description="Fastlane plugin version extracted from .sentry-cli-metadata.txt"
34+
)
35+
gradle_plugin_version: str | None = Field(
36+
None, description="Gradle plugin version extracted from .sentry-cli-metadata.txt"
37+
)
3438

3539

3640
class FileAnalysis(BaseModel):

src/launchpad/utils/metadata_extractor.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ def _parse_metadata_content(content: str) -> ToolingMetadata:
6565
6666
Expected format:
6767
sentry-cli-version: 2.58.2
68-
fastlane-plugin-version: 1.2.3
69-
gradle-plugin-version: 4.12.0
68+
sentry-fastlane-plugin: 1.2.3
69+
sentry-gradle-plugin: 4.12.0
7070
7171
Args:
7272
content: The text content of the metadata file
@@ -89,6 +89,6 @@ def _parse_metadata_content(content: str) -> ToolingMetadata:
8989

9090
return ToolingMetadata(
9191
cli_version=metadata.get("sentry-cli-version"),
92-
fastlane_plugin_version=metadata.get("fastlane-plugin-version"),
93-
gradle_plugin_version=metadata.get("gradle-plugin-version"),
92+
fastlane_plugin_version=metadata.get("sentry-fastlane-plugin"),
93+
gradle_plugin_version=metadata.get("sentry-gradle-plugin"),
9494
)

tests/unit/artifacts/test_artifact_processor.py

Lines changed: 0 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -291,104 +291,3 @@ def test_process_message_project_not_skipped(self, mock_process, mock_sentry_cli
291291
calls = fake_statsd.calls
292292
assert ("increment", {"metric": "artifact.processing.started", "value": 1, "tags": None}) in calls
293293
assert ("increment", {"metric": "artifact.processing.completed", "value": 1, "tags": None}) in calls
294-
295-
296-
class TestToolingVersionExtraction:
297-
"""Test extraction of tooling version information from artifacts."""
298-
299-
def setup_method(self):
300-
"""Set up test fixtures."""
301-
mock_sentry_client = Mock(spec=SentryClient)
302-
mock_statsd = Mock()
303-
self.processor = ArtifactProcessor(mock_sentry_client, mock_statsd)
304-
305-
def test_extract_tooling_versions_with_sentry_cli_version(self, tmp_path):
306-
"""Test extracting sentry-cli version from artifact zip."""
307-
import zipfile
308-
309-
from launchpad.artifacts.artifact import Artifact
310-
311-
# Create a test zip file with .sentry-cli-metadata.txt
312-
zip_path = tmp_path / "test_artifact.zip"
313-
with zipfile.ZipFile(zip_path, "w") as zf:
314-
zf.writestr(".sentry-cli-metadata.txt", "sentry-cli-version: 2.39.1\n")
315-
316-
# Create an artifact pointing to the zip
317-
artifact = Artifact(path=zip_path)
318-
319-
# Extract versions
320-
versions = self.processor._extract_tooling_versions(artifact)
321-
322-
# Verify sentry-cli version was extracted
323-
assert versions["sentry_cli_version"] == "2.39.1"
324-
assert versions["fastlane_plugin_version"] is None
325-
assert versions["gradle_plugin_version"] is None
326-
327-
def test_extract_tooling_versions_no_metadata_file(self, tmp_path):
328-
"""Test extracting versions when no metadata file exists."""
329-
import zipfile
330-
331-
from launchpad.artifacts.artifact import Artifact
332-
333-
# Create a test zip file without metadata
334-
zip_path = tmp_path / "test_artifact.zip"
335-
with zipfile.ZipFile(zip_path, "w") as zf:
336-
zf.writestr("some_file.txt", "content")
337-
338-
artifact = Artifact(path=zip_path)
339-
versions = self.processor._extract_tooling_versions(artifact)
340-
341-
# All versions should be None
342-
assert versions["sentry_cli_version"] is None
343-
assert versions["fastlane_version"] is None
344-
assert versions["gradle_plugin_version"] is None
345-
346-
def test_extract_tooling_versions_multiline_metadata(self, tmp_path):
347-
"""Test extracting version from metadata file with multiple lines."""
348-
import zipfile
349-
350-
from launchpad.artifacts.artifact import Artifact
351-
352-
zip_path = tmp_path / "test_artifact.zip"
353-
with zipfile.ZipFile(zip_path, "w") as zf:
354-
metadata_content = """# Sentry CLI Metadata
355-
sentry-cli-version: 2.40.0
356-
upload-date: 2025-11-10
357-
"""
358-
zf.writestr(".sentry-cli-metadata.txt", metadata_content)
359-
360-
artifact = Artifact(path=zip_path)
361-
versions = self.processor._extract_tooling_versions(artifact)
362-
363-
assert versions["sentry_cli_version"] == "2.40.0"
364-
365-
def test_extract_tooling_versions_with_spaces(self, tmp_path):
366-
"""Test extracting version with extra whitespace."""
367-
import zipfile
368-
369-
from launchpad.artifacts.artifact import Artifact
370-
371-
zip_path = tmp_path / "test_artifact.zip"
372-
with zipfile.ZipFile(zip_path, "w") as zf:
373-
zf.writestr(".sentry-cli-metadata.txt", "sentry-cli-version: 2.39.1 \n")
374-
375-
artifact = Artifact(path=zip_path)
376-
versions = self.processor._extract_tooling_versions(artifact)
377-
378-
assert versions["sentry_cli_version"] == "2.39.1"
379-
380-
def test_extract_tooling_versions_invalid_zip(self, tmp_path):
381-
"""Test graceful handling of invalid/corrupted zip file."""
382-
from launchpad.artifacts.artifact import Artifact
383-
384-
# Create a non-zip file
385-
invalid_zip = tmp_path / "invalid.zip"
386-
invalid_zip.write_text("not a zip file")
387-
388-
artifact = Artifact(path=invalid_zip)
389-
versions = self.processor._extract_tooling_versions(artifact)
390-
391-
# Should return all None values without crashing
392-
assert versions["sentry_cli_version"] is None
393-
assert versions["fastlane_version"] is None
394-
assert versions["gradle_plugin_version"] is None

tests/unit/utils/test_metadata_extractor.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ class TestParseMetadataContent:
1717

1818
def test_parse_all_fields(self):
1919
content = """sentry-cli-version: 2.58.2
20-
fastlane-plugin: 1.2.3
21-
gradle-plugin: 4.12.0"""
20+
sentry-fastlane-plugin: 1.2.3
21+
sentry-gradle-plugin: 4.12.0"""
2222
metadata = _parse_metadata_content(content)
2323
assert metadata.cli_version == "2.58.2"
2424
assert metadata.fastlane_plugin_version == "1.2.3"
2525
assert metadata.gradle_plugin_version == "4.12.0"
2626

2727
def test_parse_partial_fields(self):
2828
content = """sentry-cli-version: 2.58.2
29-
fastlane-plugin: 1.2.3"""
29+
sentry-fastlane-plugin: 1.2.3"""
3030
metadata = _parse_metadata_content(content)
3131
assert metadata.cli_version == "2.58.2"
3232
assert metadata.fastlane_plugin_version == "1.2.3"
@@ -48,8 +48,8 @@ def test_parse_empty_content(self):
4848

4949
def test_parse_with_extra_whitespace(self):
5050
content = """ sentry-cli-version: 2.58.2
51-
fastlane-plugin: 1.2.3
52-
gradle-plugin: 4.12.0 """
51+
sentry-fastlane-plugin: 1.2.3
52+
sentry-gradle-plugin: 4.12.0 """
5353
metadata = _parse_metadata_content(content)
5454
assert metadata.cli_version == "2.58.2"
5555
assert metadata.fastlane_plugin_version == "1.2.3"
@@ -59,9 +59,9 @@ def test_parse_with_extra_lines(self):
5959
content = """
6060
sentry-cli-version: 2.58.2
6161
62-
fastlane-plugin: 1.2.3
62+
sentry-fastlane-plugin: 1.2.3
6363
64-
gradle-plugin: 4.12.0
64+
sentry-gradle-plugin: 4.12.0
6565
"""
6666
metadata = _parse_metadata_content(content)
6767
assert metadata.cli_version == "2.58.2"
@@ -71,7 +71,7 @@ def test_parse_with_extra_lines(self):
7171
def test_parse_with_unknown_fields(self):
7272
content = """sentry-cli-version: 2.58.2
7373
unknown-field: some-value
74-
fastlane-plugin: 1.2.3"""
74+
sentry-fastlane-plugin: 1.2.3"""
7575
metadata = _parse_metadata_content(content)
7676
assert metadata.cli_version == "2.58.2"
7777
assert metadata.fastlane_plugin_version == "1.2.3"
@@ -87,7 +87,7 @@ def test_extract_from_zip_root(self):
8787
with zipfile.ZipFile(tf.name, "w") as zf:
8888
zf.writestr(
8989
".sentry-cli-metadata.txt",
90-
"sentry-cli-version: 2.58.2\nfastlane-plugin: 1.2.3\ngradle-plugin: 4.12.0",
90+
"sentry-cli-version: 2.58.2\nsentry-fastlane-plugin: 1.2.3\nsentry-gradle-plugin: 4.12.0",
9191
)
9292
zf.writestr("some-file.txt", "content")
9393

0 commit comments

Comments
 (0)