(patchText: string)
| 183 | } |
| 184 | |
| 185 | export function parsePatch(patchText: string): { hunks: Hunk[] } { |
| 186 | const cleaned = stripHeredoc(patchText.trim()) |
| 187 | const lines = cleaned.split("\n") |
| 188 | const hunks: Hunk[] = [] |
| 189 | let i = 0 |
| 190 | |
| 191 | // Look for Begin/End patch markers |
| 192 | const beginMarker = "*** Begin Patch" |
| 193 | const endMarker = "*** End Patch" |
| 194 | |
| 195 | const beginIdx = lines.findIndex((line) => line.trim() === beginMarker) |
| 196 | const endIdx = lines.findIndex((line) => line.trim() === endMarker) |
| 197 | |
| 198 | if (beginIdx === -1 || endIdx === -1 || beginIdx >= endIdx) { |
| 199 | throw new Error("Invalid patch format: missing Begin/End markers") |
| 200 | } |
| 201 | |
| 202 | // Parse content between markers |
| 203 | i = beginIdx + 1 |
| 204 | |
| 205 | while (i < endIdx) { |
| 206 | const header = parsePatchHeader(lines, i) |
| 207 | if (!header) { |
| 208 | i++ |
| 209 | continue |
| 210 | } |
| 211 | |
| 212 | if (lines[i].startsWith("*** Add File:")) { |
| 213 | const { content, nextIdx } = parseAddFileContent(lines, header.nextIdx) |
| 214 | hunks.push({ |
| 215 | type: "add", |
| 216 | path: header.filePath, |
| 217 | contents: content, |
| 218 | }) |
| 219 | i = nextIdx |
| 220 | } else if (lines[i].startsWith("*** Delete File:")) { |
| 221 | hunks.push({ |
| 222 | type: "delete", |
| 223 | path: header.filePath, |
| 224 | }) |
| 225 | i = header.nextIdx |
| 226 | } else if (lines[i].startsWith("*** Update File:")) { |
| 227 | const { chunks, nextIdx } = parseUpdateFileChunks(lines, header.nextIdx) |
| 228 | hunks.push({ |
| 229 | type: "update", |
| 230 | path: header.filePath, |
| 231 | move_path: header.movePath, |
| 232 | chunks, |
| 233 | }) |
| 234 | i = nextIdx |
| 235 | } else { |
| 236 | i++ |
| 237 | } |
| 238 | } |
| 239 | |
| 240 | return { hunks } |
| 241 | } |
| 242 |
no test coverage detected