find_original_update_blocks now accepts fence param, raises on mangled <source>filename.ext #317

This commit is contained in:
Paul Gauthier 2023-11-02 12:05:39 -07:00
parent f0711d4b96
commit 2609ec1b06
2 changed files with 52 additions and 15 deletions

View file

@ -17,7 +17,7 @@ class EditBlockCoder(Coder):
content = self.partial_response_content content = self.partial_response_content
# might raise ValueError for malformed ORIG/UPD blocks # might raise ValueError for malformed ORIG/UPD blocks
edits = list(find_original_update_blocks(content)) edits = list(find_original_update_blocks(content, self.fence))
return edits return edits
@ -25,7 +25,7 @@ class EditBlockCoder(Coder):
for path, original, updated in edits: for path, original, updated in edits:
full_path = self.abs_root_path(path) full_path = self.abs_root_path(path)
content = self.io.read_text(full_path) content = self.io.read_text(full_path)
content = do_replace(full_path, content, original, updated) content = do_replace(full_path, content, original, updated, self.fence)
if content: if content:
self.io.write_text(full_path, content) self.io.write_text(full_path, content)
continue continue
@ -247,7 +247,10 @@ def replace_closest_edit_distance(whole_lines, part, part_lines, replace_lines):
return modified_whole return modified_whole
def strip_quoted_wrapping(res, fname=None, fence=None): DEFAULT_FENCE = ("`" * 3, "`" * 3)
def strip_quoted_wrapping(res, fname=None, fence=DEFAULT_FENCE):
""" """
Given an input string which may have extra "wrapping" around it, remove the wrapping. Given an input string which may have extra "wrapping" around it, remove the wrapping.
For example: For example:
@ -261,9 +264,6 @@ def strip_quoted_wrapping(res, fname=None, fence=None):
if not res: if not res:
return res return res
if not fence:
fence = ("```", "```")
res = res.splitlines() res = res.splitlines()
if fname and res[0].strip().endswith(Path(fname).name): if fname and res[0].strip().endswith(Path(fname).name):
@ -310,7 +310,23 @@ separators = "|".join([HEAD, DIVIDER, UPDATED])
split_re = re.compile(r"^((?:" + separators + r")[ ]*\n)", re.MULTILINE | re.DOTALL) split_re = re.compile(r"^((?:" + separators + r")[ ]*\n)", re.MULTILINE | re.DOTALL)
def find_original_update_blocks(content): missing_filename_err = f"Bad/missing filename. Filename should be alone on the line before {HEAD}"
def strip_filename(filename, fence):
filename = filename.strip()
if filename == "...":
return
start_fence = fence[0]
if filename.startswith(start_fence):
return
return filename
def find_original_update_blocks(content, fence=DEFAULT_FENCE):
# make sure we end with a newline, otherwise the regex will miss <<UPD on the last line # make sure we end with a newline, otherwise the regex will miss <<UPD on the last line
if not content.endswith("\n"): if not content.endswith("\n"):
content = content + "\n" content = content + "\n"
@ -337,22 +353,20 @@ def find_original_update_blocks(content):
processed.append(cur) # original_marker processed.append(cur) # original_marker
filename = processed[-2].splitlines()[-1].strip() filename = strip_filename(processed[-2].splitlines()[-1], fence)
try: try:
if not len(filename) or "`" in filename: if not filename:
filename = processed[-2].splitlines()[-2].strip() filename = strip_filename(processed[-2].splitlines()[-2], fence)
if not len(filename) or "`" in filename or filename == "...": if not filename:
if current_filename: if current_filename:
filename = current_filename filename = current_filename
else: else:
raise ValueError( raise ValueError(missing_filename_err)
f"Bad/missing filename. It should go right above the {HEAD}"
)
except IndexError: except IndexError:
if current_filename: if current_filename:
filename = current_filename filename = current_filename
else: else:
raise ValueError(f"Bad/missing filename. It should go right above the {HEAD}") raise ValueError(missing_filename_err)
current_filename = filename current_filename = filename

View file

@ -80,6 +80,29 @@ Hope you like it!
edits = list(eb.find_original_update_blocks(edit)) edits = list(eb.find_original_update_blocks(edit))
self.assertEqual(edits, [("foo.txt", "Two\n", "Tooooo\n")]) self.assertEqual(edits, [("foo.txt", "Two\n", "Tooooo\n")])
def test_find_original_update_blocks_mangled_filename_w_source_tag(self):
source = "source"
edit = """
Here's the change:
<%s>foo.txt
<<<<<<< SEARCH
One
=======
Two
>>>>>>> REPLACE
</%s>
Hope you like it!
""" % (source, source)
fence = ("<%s>" % source, "</%s>" % source)
with self.assertRaises(ValueError) as cm:
_edits = list(eb.find_original_update_blocks(edit, fence))
self.assertIn("missing filename", str(cm.exception))
def test_find_original_update_blocks_quote_below_filename(self): def test_find_original_update_blocks_quote_below_filename(self):
edit = """ edit = """
Here's the change: Here's the change: