python:gpt-patcher
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| python:gpt-patcher [2025/11/05 12:42] – Wuff | python:gpt-patcher [2025/11/07 16:26] (current) – Wuff | ||
|---|---|---|---|
| Line 4: | Line 4: | ||
| The script below can help apply these patches. | The script below can help apply these patches. | ||
| - | It accepts file, stdin, clipboard or interactive manual paste as source for the patch, parses it for the target filename, checks if it can apply the patch and outputs the newly patched file. | + | It accepts file, stdin, clipboard or interactive manual paste as source for the patch, parses it for the target filename |
| Command line option -i can replace the original file immediately, | Command line option -i can replace the original file immediately, | ||
| Command line option -t can be used to patch a different filename. | Command line option -t can be used to patch a different filename. | ||
| Line 37: | Line 37: | ||
| else: | else: | ||
| clip = pyperclip.paste().strip() if pyperclip else "" | clip = pyperclip.paste().strip() if pyperclip else "" | ||
| - | if clip and PATCH_BEGIN in clip and PATCH_END in clip: | + | if clip: |
| print(" | print(" | ||
| data = clip | data = clip | ||
| else: | else: | ||
| - | print(" | + | |
| + | | ||
| print(" | print(" | ||
| try: | try: | ||
| Line 50: | Line 51: | ||
| - | def validate_patch_format(data: str): | + | def detect_patch_format(data: str): |
| - | """ | + | """ |
| - | | + | |
| - | sys.exit(" | + | |
| - | | + | return |
| - | sys.exit(" | + | |
| - | return | + | |
| - | def parse_patch(data: | + | def parse_patch(data: |
| """ | """ | ||
| match = re.search(r" | match = re.search(r" | ||
| - | if not match: | + | |
| - | | + | |
| - | filename = match.group(1).strip() | + | if not filename: |
| + | | ||
| + | if not filename: | ||
| + | sys.exit(" | ||
| + | # Extract hunks (between @@ markers) | ||
| hunks = [] | hunks = [] | ||
| current_hunk = [] | current_hunk = [] | ||
| in_hunk = False | in_hunk = False | ||
| - | |||
| for line in data.splitlines(): | for line in data.splitlines(): | ||
| if line.startswith(" | if line.startswith(" | ||
| Line 76: | Line 78: | ||
| current_hunk = [] | current_hunk = [] | ||
| in_hunk = True | in_hunk = True | ||
| - | elif line.strip() == PATCH_END: | ||
| - | if current_hunk: | ||
| - | hunks.append(current_hunk) | ||
| - | break | ||
| elif in_hunk: | elif in_hunk: | ||
| current_hunk.append(line) | current_hunk.append(line) | ||
| + | if current_hunk: | ||
| + | hunks.append(current_hunk) | ||
| return filename, hunks | return filename, hunks | ||
| Line 114: | Line 113: | ||
| match = re.search(pattern, | match = re.search(pattern, | ||
| if not match: | if not match: | ||
| - | # try without requiring both contexts (looser match) | + | # Try looser match |
| match = re.search(re.escape(old_block), | match = re.search(re.escape(old_block), | ||
| if not match: | if not match: | ||
| Line 139: | Line 138: | ||
| old_block = " | old_block = " | ||
| new_block = " | new_block = " | ||
| - | |||
| - | # extract leading and trailing context if available | ||
| context_before = " | context_before = " | ||
| context_after = " | context_after = " | ||
| Line 159: | Line 156: | ||
| def main(): | def main(): | ||
| - | parser = argparse.ArgumentParser(description=" | + | parser = argparse.ArgumentParser(description=" |
| parser.add_argument(" | parser.add_argument(" | ||
| parser.add_argument(" | parser.add_argument(" | ||
| Line 167: | Line 164: | ||
| data = read_patch_input(args.patchfile) | data = read_patch_input(args.patchfile) | ||
| - | | + | |
| - | patch_file, hunks = parse_patch(data) | + | |
| - | | + | |
| + | patch_file, hunks = parse_patch(data, | ||
| - | if not os.path.exists(target_file): | + | if not os.path.exists(patch_file): |
| - | sys.exit(f" | + | sys.exit(f" |
| - | result = apply_patch_to_file(target_file, hunks) | + | result = apply_patch_to_file(patch_file, hunks) |
| if args.in_place: | if args.in_place: | ||
| - | backup = make_backup(target_file) | + | backup = make_backup(patch_file) |
| - | with open(target_file, " | + | with open(patch_file, " |
| f.write(result) | f.write(result) | ||
| - | print(f" | + | print(f" |
| else: | else: | ||
| sys.stdout.write(result) | sys.stdout.write(result) | ||
| Line 188: | Line 185: | ||
| if __name__ == " | if __name__ == " | ||
| main() | main() | ||
| - | |||
| </ | </ | ||
python/gpt-patcher.1762346553.txt.gz · Last modified: by Wuff