Parse a ``*** Begin Patch`` / ``*** End Patch`` block. Ported from ShinkaEvolve ``shinka/edit/apply_patch.py``.
(patch_text: str)
| 624 | return chunks, i |
| 625 | |
| 626 | def parse_patch(patch_text: str) -> PatchResult: |
| 627 | """Parse a ``*** Begin Patch`` / ``*** End Patch`` block. |
| 628 | |
| 629 | Ported from ShinkaEvolve ``shinka/edit/apply_patch.py``. |
| 630 | """ |
| 631 | lines = patch_text.strip().split("\n") |
| 632 | |
| 633 | begin_idx = -1 |
| 634 | end_idx = -1 |
| 635 | for i, line in enumerate(lines): |
| 636 | stripped = line.strip() |
| 637 | if stripped == "*** Begin Patch": |
| 638 | begin_idx = i |
| 639 | elif stripped == "*** End Patch": |
| 640 | end_idx = i |
| 641 | |
| 642 | if begin_idx == -1 or end_idx == -1 or begin_idx >= end_idx: |
| 643 | raise PatchParseError( |
| 644 | "Invalid patch format: missing or mis-ordered " |
| 645 | "*** Begin Patch / *** End Patch markers" |
| 646 | ) |
| 647 | |
| 648 | hunks: List[PatchHunk] = [] |
| 649 | i = begin_idx + 1 |
| 650 | |
| 651 | while i < end_idx: |
| 652 | header = _parse_patch_header(lines, i) |
| 653 | if header is None: |
| 654 | i += 1 |
| 655 | continue |
| 656 | |
| 657 | file_path, move_path, next_idx = header |
| 658 | |
| 659 | if lines[i].startswith("*** Add File:"): |
| 660 | content, next_idx = _parse_add_file_content(lines, next_idx) |
| 661 | hunks.append(PatchHunk(type="add", path=file_path, contents=content)) |
| 662 | i = next_idx |
| 663 | |
| 664 | elif lines[i].startswith("*** Delete File:"): |
| 665 | hunks.append(PatchHunk(type="delete", path=file_path)) |
| 666 | i = next_idx |
| 667 | |
| 668 | elif lines[i].startswith("*** Update File:"): |
| 669 | chunks, next_idx = _parse_update_chunks(lines, next_idx) |
| 670 | hunks.append(PatchHunk( |
| 671 | type="update", |
| 672 | path=file_path, |
| 673 | move_path=move_path, |
| 674 | chunks=chunks, |
| 675 | )) |
| 676 | i = next_idx |
| 677 | else: |
| 678 | i += 1 |
| 679 | |
| 680 | return PatchResult(hunks=hunks) |
| 681 | |
| 682 | def _compute_replacements( |
| 683 | original_lines: List[str], |
no test coverage detected