Parses all sections (@@, context, -, +) for a single Update File action.
(
self, lines: List[str], index: int, file_content: str
)
| 410 | return patch |
| 411 | |
| 412 | def _parse_update_file_sections( |
| 413 | self, lines: List[str], index: int, file_content: str |
| 414 | ) -> Tuple[PatchAction, int, int]: |
| 415 | """Parses all sections (@@, context, -, +) for a single Update File action.""" |
| 416 | action = PatchAction(type=ActionType.UPDATE, path="") # Path set by caller |
| 417 | orig_lines = file_content.splitlines() # Use splitlines for consistency |
| 418 | current_file_index = 0 # Track position in original file content |
| 419 | total_fuzz = 0 |
| 420 | |
| 421 | while index < len(lines): |
| 422 | norm_line = _norm(lines[index]) |
| 423 | # Check for terminators for *this* file update |
| 424 | if norm_line.startswith( |
| 425 | ( |
| 426 | "*** End Patch", |
| 427 | "*** Update File:", |
| 428 | "*** Delete File:", |
| 429 | "*** Add File:", |
| 430 | ) |
| 431 | ): |
| 432 | break # End of this file's update section |
| 433 | |
| 434 | # Handle @@ scope lines (optional) |
| 435 | scope_lines = [] |
| 436 | while index < len(lines) and _norm(lines[index]).startswith("@@"): |
| 437 | scope_line_content = lines[index][len("@@") :].strip() |
| 438 | if scope_line_content: # Ignore empty @@ lines? |
| 439 | scope_lines.append(scope_line_content) |
| 440 | index += 1 |
| 441 | |
| 442 | # Find the scope in the original file if specified |
| 443 | if scope_lines: |
| 444 | # Simple scope finding: search from current position |
| 445 | # A more robust finder could handle nested scopes like the reference @@ @@ |
| 446 | found_scope = False |
| 447 | temp_index = current_file_index |
| 448 | while temp_index < len(orig_lines): |
| 449 | # Check if all scope lines match sequentially from temp_index |
| 450 | match = True |
| 451 | for i, scope in enumerate(scope_lines): |
| 452 | if ( |
| 453 | temp_index + i >= len(orig_lines) |
| 454 | or _norm(orig_lines[temp_index + i]).strip() != scope |
| 455 | ): |
| 456 | match = False |
| 457 | break |
| 458 | if match: |
| 459 | current_file_index = temp_index + len(scope_lines) |
| 460 | found_scope = True |
| 461 | break |
| 462 | temp_index += 1 |
| 463 | |
| 464 | if not found_scope: |
| 465 | # Try fuzzy scope matching (strip whitespace) |
| 466 | temp_index = current_file_index |
| 467 | while temp_index < len(orig_lines): |
| 468 | match = True |
| 469 | for i, scope in enumerate(scope_lines): |
no test coverage detected