Skip to content

Commit b9bfafe

Browse files
committed
Improve xcresult attachment detection
1 parent 3039e2c commit b9bfafe

File tree

1 file changed

+61
-12
lines changed

1 file changed

+61
-12
lines changed

scripts/ios/export_xcresult_attachments.py

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,18 @@ def get_json(bundle_path: str, object_id: Optional[str] = None) -> Dict:
4141
return json.loads(output or "{}")
4242

4343

44+
def extract_id(ref: object) -> Optional[str]:
45+
if isinstance(ref, str):
46+
return ref
47+
if isinstance(ref, dict):
48+
if "id" in ref:
49+
return extract_id(ref["id"])
50+
if "_value" in ref:
51+
value = ref["_value"]
52+
return value if isinstance(value, str) else None
53+
return None
54+
55+
4456
def collect_nodes(node) -> Tuple[List[Dict], List[str]]:
4557
attachments: List[Dict] = []
4658
refs: List[str] = []
@@ -55,13 +67,13 @@ def collect_nodes(node) -> Tuple[List[Dict], List[str]]:
5567
attachments.append(item)
5668
for key, value in current.items():
5769
if key.endswith("Ref") and isinstance(value, dict):
58-
ref_id = value.get("id")
70+
ref_id = extract_id(value)
5971
if isinstance(ref_id, str) and ref_id:
6072
refs.append(ref_id)
6173
elif key.endswith("Refs") and isinstance(value, dict):
6274
for entry in value.get("_values", []):
6375
if isinstance(entry, dict):
64-
ref_id = entry.get("id")
76+
ref_id = extract_id(entry)
6577
if isinstance(ref_id, str) and ref_id:
6678
refs.append(ref_id)
6779
if isinstance(value, (dict, list)):
@@ -71,14 +83,41 @@ def collect_nodes(node) -> Tuple[List[Dict], List[str]]:
7183
return attachments, refs
7284

7385

74-
def is_image_attachment(attachment: Dict) -> bool:
75-
uti = (attachment.get("uniformTypeIdentifier") or "").lower()
76-
filename = (attachment.get("filename") or attachment.get("name") or "").lower()
77-
if filename.endswith((".png", ".jpg", ".jpeg")):
86+
def _looks_like_image(value: Optional[str]) -> bool:
87+
if not value:
88+
return False
89+
lower = value.lower()
90+
if lower.endswith((".png", ".jpg", ".jpeg")):
7891
return True
79-
if "png" in uti or "jpeg" in uti:
92+
keywords = ("png", "jpeg", "image", "screenshot")
93+
return any(keyword in lower for keyword in keywords)
94+
95+
96+
def is_image_attachment(attachment: Dict) -> bool:
97+
filename = attachment.get("filename") or attachment.get("name")
98+
if _looks_like_image(filename):
8099
return True
81-
return False
100+
101+
uti_candidates = [
102+
attachment.get("uniformTypeIdentifier"),
103+
attachment.get("contentType"),
104+
attachment.get("uti"),
105+
]
106+
payload = (
107+
attachment.get("payloadRef")
108+
or attachment.get("inlinePayloadRef")
109+
or attachment.get("payload")
110+
)
111+
if isinstance(payload, dict):
112+
uti_candidates.extend(
113+
[
114+
payload.get("contentType"),
115+
payload.get("uti"),
116+
payload.get("uniformTypeIdentifier"),
117+
]
118+
)
119+
120+
return any(_looks_like_image(candidate) for candidate in uti_candidates)
82121

83122

84123
def sanitize_filename(name: str) -> str:
@@ -101,8 +140,13 @@ def ensure_extension(name: str, uti: str) -> str:
101140
def export_attachment(
102141
bundle_path: str, attachment: Dict, destination_dir: str, used_names: Set[str]
103142
) -> None:
104-
payload = attachment.get("payloadRef") or {}
105-
attachment_id = payload.get("id")
143+
payload = (
144+
attachment.get("payloadRef")
145+
or attachment.get("inlinePayloadRef")
146+
or attachment.get("payload")
147+
or {}
148+
)
149+
attachment_id = extract_id(payload)
106150
if not attachment_id:
107151
return
108152
name = attachment.get("filename") or attachment.get("name") or attachment_id
@@ -141,8 +185,13 @@ def handle_attachments(
141185
seen_attachment_ids: Set[str],
142186
) -> None:
143187
for attachment in items:
144-
payload = attachment.get("payloadRef") or {}
145-
attachment_id = payload.get("id")
188+
payload = (
189+
attachment.get("payloadRef")
190+
or attachment.get("inlinePayloadRef")
191+
or attachment.get("payload")
192+
or {}
193+
)
194+
attachment_id = extract_id(payload)
146195
if not attachment_id or attachment_id in seen_attachment_ids:
147196
continue
148197
if not is_image_attachment(attachment):

0 commit comments

Comments
 (0)