|
24 | 24 | import PackageDescription |
25 | 25 | import Foundation |
26 | 26 |
|
27 | | -struct DependencyInfo { |
| 27 | +struct SPMPackageInfo { |
28 | 28 | let url: String |
29 | 29 | let version: String |
30 | | - let mode: String |
31 | | - let product: String |
| 30 | + let products: [String] |
32 | 31 | } |
33 | 32 |
|
34 | | -func parseGDIPFile(at path: String) -> [DependencyInfo] { |
| 33 | +func parseGDIPFile(at path: String) -> [SPMPackageInfo] { |
35 | 34 | let fileURL = URL(fileURLWithPath: path) |
36 | 35 | guard let content = try? String(contentsOf: fileURL, encoding: .utf8) else { |
37 | 36 | return [] |
38 | 37 | } |
39 | | - |
40 | | - // Regex to find admob_packages array content |
41 | | - let pattern = #"admob_packages\s*=\s*\[\s*([\s\S]*?)\s*\]"# |
42 | | - guard let regex = try? NSRegularExpression(pattern: pattern) else { return [] } |
43 | | - |
44 | | - let range = NSRange(content.startIndex..., in: content) |
45 | | - guard let match = regex.firstMatch(in: content, options: [], range: range) else { return [] } |
46 | | - |
47 | | - let arrayContent = String(content[Range(match.range(at: 1), in: content)!]) |
48 | | - |
49 | | - // Parse each line in the array: "url@mode:version|product" |
50 | | - let lines = arrayContent.components(separatedBy: ",") |
51 | | - var dependencies: [DependencyInfo] = [] |
52 | | - |
53 | | - for line in lines { |
54 | | - let trimmedLine = line.trimmingCharacters(in: .whitespacesAndNewlines) |
55 | | - .trimmingCharacters(in: CharacterSet(charactersIn: "\"")) |
56 | | - |
57 | | - if trimmedLine.isEmpty { continue } |
58 | | - |
59 | | - // Split by @ and | |
60 | | - let mainParts = trimmedLine.components(separatedBy: "|") |
61 | | - let product = mainParts.count > 1 ? mainParts[1] : "" |
62 | | - |
63 | | - let urlAndRules = mainParts[0].components(separatedBy: "@") |
64 | | - let url = urlAndRules[0] |
65 | | - |
66 | | - if urlAndRules.count > 1 { |
67 | | - let rules = urlAndRules[1].components(separatedBy: ":") |
68 | | - if rules.count > 1 { |
69 | | - dependencies.append(DependencyInfo( |
70 | | - url: url, |
71 | | - version: rules[1], |
72 | | - mode: rules[0], |
73 | | - product: product |
74 | | - )) |
75 | | - } |
| 38 | + |
| 39 | + guard let spmStart = content.range(of: "spm_packages") else { return [] } |
| 40 | + let afterSpm = String(content[spmStart.upperBound...]) |
| 41 | + |
| 42 | + let sectionPattern = #"\n\s*\[[a-zA-Z]"# |
| 43 | + let nextSection: String |
| 44 | + if let sectionRegex = try? NSRegularExpression(pattern: sectionPattern), |
| 45 | + let sectionMatch = sectionRegex.firstMatch(in: afterSpm, range: NSRange(afterSpm.startIndex..., in: afterSpm)) { |
| 46 | + nextSection = String(afterSpm[afterSpm.startIndex..<Range(sectionMatch.range, in: afterSpm)!.lowerBound]) |
| 47 | + } else { |
| 48 | + nextSection = afterSpm |
| 49 | + } |
| 50 | + |
| 51 | + let dictPattern = #"\{([^}]+)\}"# |
| 52 | + guard let dictRegex = try? NSRegularExpression(pattern: dictPattern) else { return [] } |
| 53 | + |
| 54 | + let dictRange = NSRange(nextSection.startIndex..., in: nextSection) |
| 55 | + let dictMatches = dictRegex.matches(in: nextSection, options: [], range: dictRange) |
| 56 | + |
| 57 | + var packages: [SPMPackageInfo] = [] |
| 58 | + |
| 59 | + for dictMatch in dictMatches { |
| 60 | + let dictContent = String(nextSection[Range(dictMatch.range(at: 1), in: nextSection)!]) |
| 61 | + |
| 62 | + let url = extractValue(from: dictContent, key: "url") |
| 63 | + let version = extractValue(from: dictContent, key: "version") |
| 64 | + let products = extractArray(from: dictContent, key: "products") |
| 65 | + |
| 66 | + if !url.isEmpty && !version.isEmpty { |
| 67 | + packages.append(SPMPackageInfo(url: url, version: version, products: products)) |
76 | 68 | } |
77 | 69 | } |
78 | | - |
79 | | - return dependencies |
| 70 | + |
| 71 | + return packages |
| 72 | +} |
| 73 | + |
| 74 | +func extractValue(from text: String, key: String) -> String { |
| 75 | + let pattern = #""\#(key)"\s*:\s*"([^"]+)""# |
| 76 | + guard let regex = try? NSRegularExpression(pattern: pattern) else { return "" } |
| 77 | + let range = NSRange(text.startIndex..., in: text) |
| 78 | + guard let match = regex.firstMatch(in: text, options: [], range: range) else { return "" } |
| 79 | + return String(text[Range(match.range(at: 1), in: text)!]) |
| 80 | +} |
| 81 | + |
| 82 | +func extractArray(from text: String, key: String) -> [String] { |
| 83 | + let pattern = #""\#(key)"\s*:\s*\[([^\]]*)\]"# |
| 84 | + guard let regex = try? NSRegularExpression(pattern: pattern) else { return [] } |
| 85 | + let range = NSRange(text.startIndex..., in: text) |
| 86 | + guard let match = regex.firstMatch(in: text, options: [], range: range) else { return [] } |
| 87 | + |
| 88 | + let arrayContent = String(text[Range(match.range(at: 1), in: text)!]) |
| 89 | + return arrayContent.components(separatedBy: ",") |
| 90 | + .map { $0.trimmingCharacters(in: .whitespacesAndNewlines).trimmingCharacters(in: CharacterSet(charactersIn: "\"")) } |
| 91 | + .filter { !$0.isEmpty } |
80 | 92 | } |
81 | 93 |
|
82 | 94 | var packageDependencies: [Package.Dependency] = [] |
@@ -110,25 +122,21 @@ if gdipFiles.isEmpty { |
110 | 122 |
|
111 | 123 | for gdipFile in gdipFiles { |
112 | 124 | print("PoingAdMob: Parsing \(gdipFile)") |
113 | | - let deps = parseGDIPFile(at: gdipFile) |
114 | | - for dep in deps { |
115 | | - print("PoingAdMob: Found dependency \(dep.product) from \(dep.url)") |
116 | | - if !seenURLs.contains(dep.url) { |
117 | | - if dep.mode == "exact" { |
118 | | - packageDependencies.append(.package(url: dep.url, exact: Version(stringLiteral: dep.version))) |
119 | | - } else if dep.mode == "from" { |
120 | | - packageDependencies.append(.package(url: dep.url, from: Version(stringLiteral: dep.version))) |
121 | | - } else if dep.mode == "branch" { |
122 | | - packageDependencies.append(.package(url: dep.url, branch: dep.version)) |
123 | | - } |
124 | | - seenURLs.insert(dep.url) |
| 125 | + let spmPackages = parseGDIPFile(at: gdipFile) |
| 126 | + for package in spmPackages { |
| 127 | + print("PoingAdMob: Found package \(package.url) v\(package.version) → \(package.products)") |
| 128 | + if !seenURLs.contains(package.url) { |
| 129 | + packageDependencies.append(.package(url: package.url, exact: Version(stringLiteral: package.version))) |
| 130 | + seenURLs.insert(package.url) |
125 | 131 | } |
126 | | - |
127 | | - if !seenProducts.contains(dep.product) && !dep.product.isEmpty { |
128 | | - let packageName = dep.url.components(separatedBy: "/").last? |
129 | | - .replacingOccurrences(of: ".git", with: "") ?? "" |
130 | | - targetDependencies.append(.product(name: dep.product, package: packageName)) |
131 | | - seenProducts.insert(dep.product) |
| 132 | + |
| 133 | + let packageName = package.url.components(separatedBy: "/").last? |
| 134 | + .replacingOccurrences(of: ".git", with: "") ?? "" |
| 135 | + for product in package.products { |
| 136 | + if !seenProducts.contains(product) { |
| 137 | + targetDependencies.append(.product(name: product, package: packageName)) |
| 138 | + seenProducts.insert(product) |
| 139 | + } |
132 | 140 | } |
133 | 141 | } |
134 | 142 | } |
|
0 commit comments