* Parse a single hunk (file operation) from lines. * Returns the parsed hunk and number of lines consumed.
(lines: string[], lineNumber: number)
| 199 | * Returns the parsed hunk and number of lines consumed. |
| 200 | */ |
| 201 | function parseOneHunk(lines: string[], lineNumber: number): { hunk: Hunk; linesConsumed: number } { |
| 202 | const firstLine = lines[0]?.trim() |
| 203 | |
| 204 | // Add File |
| 205 | if (firstLine?.startsWith(ADD_FILE_MARKER)) { |
| 206 | const path = firstLine.substring(ADD_FILE_MARKER.length) |
| 207 | let contents = "" |
| 208 | let parsedLines = 1 |
| 209 | |
| 210 | for (let i = 1; i < lines.length; i++) { |
| 211 | const line = lines[i] |
| 212 | if (line?.startsWith("+")) { |
| 213 | contents += line.substring(1) + "\n" |
| 214 | parsedLines++ |
| 215 | } else { |
| 216 | break |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | return { |
| 221 | hunk: { type: "AddFile", path, contents }, |
| 222 | linesConsumed: parsedLines, |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | // Delete File |
| 227 | if (firstLine?.startsWith(DELETE_FILE_MARKER)) { |
| 228 | const path = firstLine.substring(DELETE_FILE_MARKER.length) |
| 229 | return { |
| 230 | hunk: { type: "DeleteFile", path }, |
| 231 | linesConsumed: 1, |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | // Update File |
| 236 | if (firstLine?.startsWith(UPDATE_FILE_MARKER)) { |
| 237 | const path = firstLine.substring(UPDATE_FILE_MARKER.length) |
| 238 | let remainingLines = lines.slice(1) |
| 239 | let parsedLines = 1 |
| 240 | |
| 241 | // Check for optional Move to line |
| 242 | let movePath: string | null = null |
| 243 | if (remainingLines[0]?.startsWith(MOVE_TO_MARKER)) { |
| 244 | movePath = remainingLines[0].substring(MOVE_TO_MARKER.length) |
| 245 | remainingLines = remainingLines.slice(1) |
| 246 | parsedLines++ |
| 247 | } |
| 248 | |
| 249 | const chunks: UpdateFileChunk[] = [] |
| 250 | |
| 251 | while (remainingLines.length > 0) { |
| 252 | // Skip blank lines between chunks |
| 253 | if (remainingLines[0]?.trim() === "") { |
| 254 | parsedLines++ |
| 255 | remainingLines = remainingLines.slice(1) |
| 256 | continue |
| 257 | } |
| 258 |
no test coverage detected