Add support for rewriting hunks if only specific lines match

This commit is contained in:
Sven van Heugten 2026-03-05 20:22:59 +01:00
parent 56d1f03c83
commit 8ebcba623e
No known key found for this signature in database
GPG key ID: D612F88666F4F660
2 changed files with 87 additions and 22 deletions

View file

@ -4,9 +4,9 @@ import re
import sys
def should_include_change(
def filter_change_block(
change_lines: list[str], search: str, replace: str
) -> bool:
) -> tuple[list[str] | None, bool]:
removed_lines = []
added_lines = []
phase = "minus"
@ -23,33 +23,66 @@ def should_include_change(
added_lines.append(line[1:])
continue
raise ValueError("Unexpected non-change line in change block.")
transformed_removed = [
re.sub(search, replace, line) for line in removed_lines
]
return transformed_removed == added_lines
if transformed_removed == added_lines:
return change_lines, False
if len(removed_lines) != len(added_lines):
return None, True
kept_lines = []
for removed, added in zip(removed_lines, added_lines):
if re.sub(search, replace, removed) == added:
kept_lines.append(f"-{removed}")
kept_lines.append(f"+{added}")
else:
kept_lines.append(f" {removed}")
if not kept_lines:
return None, True
return kept_lines, True
def should_include_hunk(hunk_text: str, search: str, replace: str) -> bool:
lines = hunk_text.splitlines()
if not lines:
return True
def filter_hunk(
hunk_lines: list[str], search: str, replace: str
) -> tuple[list[str] | None, bool]:
if not hunk_lines:
return None, False
change = []
for line in lines[1:]:
header = hunk_lines[0]
body = hunk_lines[1:]
output_body: list[str] = []
left_out = False
i = 0
while i < len(body):
line = body[i]
if line.startswith(("+", "-")):
change.append(line)
block = []
while i < len(body) and body[i].startswith(("+", "-")):
block.append(body[i])
i += 1
kept_block, block_left_out = filter_change_block(
block, search, replace
)
if kept_block:
output_body.extend(kept_block)
else:
left_out = True
if block_left_out:
left_out = True
continue
output_body.append(line)
i += 1
if change:
if not should_include_change(change, search, replace):
return False
change = []
if not any(line.startswith(("+", "-")) for line in output_body):
return None, True
if change:
if not should_include_change(change, search, replace):
return False
return True
return [header] + output_body, left_out
def main() -> None:
@ -97,11 +130,15 @@ def main() -> None:
kept_hunks = []
for hunk_lines in section["hunks"]:
hunk_text = "".join(hunk_lines)
if should_include_hunk(hunk_text, search, replace):
kept_hunks.append(hunk_lines)
filtered, hunk_left_out = filter_hunk(
hunk_lines, search, replace
)
if filtered:
kept_hunks.append(filtered)
else:
left_out = True
if hunk_left_out:
left_out = True
if not kept_hunks:
continue