(line: string)
| 150 | } |
| 151 | |
| 152 | export function parseBuildErrorDiagnostic(line: string): ParsedBuildError | null { |
| 153 | // File path with line number: /path/to/File.swift:42:10: error: message |
| 154 | const locationMatch = line.match(/^(.*?):(\d+)(?::\d+)?: (?:fatal error|error): (.+)$/u); |
| 155 | if (locationMatch) { |
| 156 | const [, filePath, lineNumber, message] = locationMatch; |
| 157 | return { |
| 158 | location: `${filePath}:${lineNumber}`, |
| 159 | message, |
| 160 | renderedLine: line, |
| 161 | }; |
| 162 | } |
| 163 | |
| 164 | // Path-based error without line number: /path/to/Project.xcodeproj: error: message |
| 165 | const pathErrorMatch = line.match(/^(\/[^:]+): (?:fatal error|error): (.+)$/u); |
| 166 | if (pathErrorMatch) { |
| 167 | const [, filePath, message] = pathErrorMatch; |
| 168 | return { |
| 169 | location: filePath, |
| 170 | message, |
| 171 | renderedLine: line, |
| 172 | }; |
| 173 | } |
| 174 | |
| 175 | // Prefixed error: xcodebuild: error: message / error: message |
| 176 | const rawMatch = line.match(/^(?:[\w-]+:\s+)?(?:fatal error|error): (.+)$/u); |
| 177 | if (rawMatch) { |
| 178 | const [, message] = rawMatch; |
| 179 | return { message, renderedLine: line }; |
| 180 | } |
| 181 | |
| 182 | if (!isBuildErrorDiagnosticLine(line)) { |
| 183 | return null; |
| 184 | } |
| 185 | |
| 186 | return { message: line, renderedLine: line }; |
| 187 | } |
no test coverage detected