Apply a pseudo-patch file to target files with fuzzy matching. This function parses a structured patch file and applies changes to the specified files. It uses fuzzy matching to find the best location for each change, making it robust to minor variations in the target files. A
(
patch_path: str, threshold: float = 0.75, dry_run: bool = False, backup: bool = True
)
| 486 | |
| 487 | # --- Main Function --- |
| 488 | async def apply_patch( |
| 489 | patch_path: str, threshold: float = 0.75, dry_run: bool = False, backup: bool = True |
| 490 | ) -> dict: |
| 491 | """ |
| 492 | Apply a pseudo-patch file to target files with fuzzy matching. |
| 493 | |
| 494 | This function parses a structured patch file and applies changes to the |
| 495 | specified files. It uses fuzzy matching to find the best location for |
| 496 | each change, making it robust to minor variations in the target files. |
| 497 | |
| 498 | Args: |
| 499 | patch_path: Path to the patch file |
| 500 | threshold: Minimum similarity score for fuzzy matching (0.0 to 1.0) |
| 501 | Default: 0.75 (75% similarity required) |
| 502 | dry_run: If True, parse and match but don't write changes |
| 503 | backup: If True, create .bak backup before modifying files |
| 504 | |
| 505 | Returns: |
| 506 | dict: Result containing: |
| 507 | - patches_applied (int): Number of hunks successfully applied |
| 508 | - files_modified (list): List of modified file paths |
| 509 | - details (list): Detailed info for each hunk |
| 510 | - error (str): Error message if failed |
| 511 | """ |
| 512 | result = { |
| 513 | "patches_applied": 0, |
| 514 | "files_modified": [], |
| 515 | "details": [], |
| 516 | } |
| 517 | |
| 518 | try: |
| 519 | # Read and parse patch file |
| 520 | patch_file = filename_to_path(patch_path) |
| 521 | if not patch_file.exists(): |
| 522 | result["error"] = f"Patch file not found: {patch_path}" |
| 523 | return result |
| 524 | |
| 525 | patch_content = patch_file.read_text(encoding="utf-8") |
| 526 | |
| 527 | # Parse hunks |
| 528 | hunks = _parse_patch_file(patch_content) |
| 529 | |
| 530 | if not hunks: |
| 531 | result["error"] = "No valid patch hunks found in file" |
| 532 | return result |
| 533 | |
| 534 | result["details"].append(f"Parsed {len(hunks)} hunk(s) from patch file") |
| 535 | |
| 536 | # Group hunks by file |
| 537 | files_to_modify: Dict[str, List[PatchHunk]] = {} |
| 538 | for hunk in hunks: |
| 539 | if hunk.filepath not in files_to_modify: |
| 540 | files_to_modify[hunk.filepath] = [] |
| 541 | files_to_modify[hunk.filepath].append(hunk) |
| 542 | |
| 543 | # Process each file |
| 544 | for filepath, file_hunks in files_to_modify.items(): |
| 545 | try: |
nothing calls this directly
no test coverage detected