| 53 | |
| 54 | |
| 55 | def parse_targets(project_file: Path) -> List[Target]: |
| 56 | content = project_file.read_text(encoding="utf-8") |
| 57 | targets: List[Target] = [] |
| 58 | for match in TARGET_BLOCK_RE.finditer(content): |
| 59 | body = match.group("body") |
| 60 | if "isa = PBXNativeTarget;" not in body: |
| 61 | continue |
| 62 | name = _search_value(body, r"name = (?P<value>[^;]+);") |
| 63 | product_type = _search_value(body, r"productType = \"(?P<value>[^\"]+)\";") |
| 64 | product_name = _search_value(body, r"productReference = [0-9A-F]{24} /\* (?P<value>[^*]+) \*/;") |
| 65 | if not name or not product_type: |
| 66 | continue |
| 67 | targets.append( |
| 68 | Target( |
| 69 | identifier=match.group("identifier"), |
| 70 | name=name.strip().strip('"'), |
| 71 | product_type=product_type.strip(), |
| 72 | product_name=product_name.strip() if product_name else None, |
| 73 | ) |
| 74 | ) |
| 75 | return targets |
| 76 | |
| 77 | |
| 78 | def _search_value(text: str, pattern: str) -> Optional[str]: |