Applies the parsed PatchActions to the corresponding files.
(self, edits: List[PatchAction])
| 547 | return action, index |
| 548 | |
| 549 | def apply_edits(self, edits: List[PatchAction]): |
| 550 | """ |
| 551 | Applies the parsed PatchActions to the corresponding files. |
| 552 | """ |
| 553 | if not edits: |
| 554 | return |
| 555 | |
| 556 | # Group edits by original path? Not strictly needed if processed sequentially. |
| 557 | |
| 558 | # Edits are now List[Tuple[str, PatchAction]] |
| 559 | for _path_tuple_element, action in edits: |
| 560 | # action is the PatchAction object |
| 561 | # action.path is the canonical path within the action logic |
| 562 | full_path = self.abs_root_path(action.path) |
| 563 | path_obj = pathlib.Path(full_path) |
| 564 | |
| 565 | try: |
| 566 | if action.type == ActionType.ADD: |
| 567 | # Check existence *before* writing |
| 568 | if path_obj.exists(): |
| 569 | raise DiffError(f"ADD Error: File already exists: {action.path}") |
| 570 | if action.new_content is None: |
| 571 | # Parser should ensure this doesn't happen |
| 572 | raise DiffError(f"ADD change for {action.path} has no content") |
| 573 | |
| 574 | self.io.tool_output(f"Adding {action.path}") |
| 575 | path_obj.parent.mkdir(parents=True, exist_ok=True) |
| 576 | # Ensure single trailing newline, matching reference behavior |
| 577 | content_to_write = action.new_content |
| 578 | if not content_to_write.endswith("\n"): |
| 579 | content_to_write += "\n" |
| 580 | self.io.write_text(full_path, content_to_write) |
| 581 | |
| 582 | elif action.type == ActionType.DELETE: |
| 583 | self.io.tool_output(f"Deleting {action.path}") |
| 584 | if not path_obj.exists(): |
| 585 | self.io.tool_warning( |
| 586 | f"DELETE Warning: File not found, skipping: {action.path}" |
| 587 | ) |
| 588 | else: |
| 589 | path_obj.unlink() |
| 590 | |
| 591 | elif action.type == ActionType.UPDATE: |
| 592 | if not path_obj.exists(): |
| 593 | raise DiffError(f"UPDATE Error: File does not exist: {action.path}") |
| 594 | |
| 595 | current_content = self.io.read_text(full_path) |
| 596 | if current_content is None: |
| 597 | # Should have been caught during parsing if file was needed |
| 598 | raise DiffError(f"Could not read file for UPDATE: {action.path}") |
| 599 | |
| 600 | # Apply the update logic using the parsed chunks |
| 601 | new_content = self._apply_update(current_content, action, action.path) |
| 602 | |
| 603 | target_full_path = ( |
| 604 | self.abs_root_path(action.move_path) if action.move_path else full_path |
| 605 | ) |
| 606 | target_path_obj = pathlib.Path(target_full_path) |
nothing calls this directly
no test coverage detected