allow multiple string replacements
This commit is contained in:
parent
c9f3f37ca3
commit
0b621b6008
|
|
@ -39,14 +39,15 @@ def format_string_for_display(s: str, threshold: int = 30) -> str:
|
|||
|
||||
|
||||
@tool
|
||||
def file_str_replace(filepath: str, old_str: str, new_str: str) -> Dict[str, any]:
|
||||
def file_str_replace(filepath: str, old_str: str, new_str: str, *, replace_all: bool = False) -> Dict[str, any]:
|
||||
"""Replace an exact string match in a file with a new string.
|
||||
Only performs replacement if the old string appears exactly once.
|
||||
Only performs replacement if the old string appears exactly once, or replace_all is True.
|
||||
|
||||
Args:
|
||||
filepath: Path to the file to modify
|
||||
old_str: Exact string to replace
|
||||
new_str: String to replace with
|
||||
replace_all: If True, replace all occurrences of the string (default: False)
|
||||
"""
|
||||
try:
|
||||
path = Path(filepath)
|
||||
|
|
@ -62,24 +63,33 @@ def file_str_replace(filepath: str, old_str: str, new_str: str) -> Dict[str, any
|
|||
msg = f"String not found: {truncate_display_str(old_str)}"
|
||||
print_error(msg)
|
||||
return {"success": False, "message": msg}
|
||||
elif count > 1:
|
||||
msg = f"String appears {count} times - must be unique"
|
||||
elif count > 1 and not replace_all:
|
||||
msg = f"String appears {count} times - must be unique (use replace_all=True to replace all occurrences)"
|
||||
print_error(msg)
|
||||
return {"success": False, "message": msg}
|
||||
|
||||
new_content = content.replace(old_str, new_str)
|
||||
path.write_text(new_content)
|
||||
|
||||
replacement_msg = f"Replaced in {filepath}:"
|
||||
if count > 1 and replace_all:
|
||||
replacement_msg = f"Replaced {count} occurrences in {filepath}:"
|
||||
|
||||
console.print(
|
||||
Panel(
|
||||
f"Replaced in {filepath}:\n{format_string_for_display(old_str)} → {format_string_for_display(new_str)}",
|
||||
f"{replacement_msg}\n{format_string_for_display(old_str)} → {format_string_for_display(new_str)}",
|
||||
title="✓ String Replaced",
|
||||
border_style="bright_blue",
|
||||
)
|
||||
)
|
||||
|
||||
success_msg = f"Successfully replaced '{old_str}' with '{new_str}' in {filepath}"
|
||||
if count > 1 and replace_all:
|
||||
success_msg = f"Successfully replaced {count} occurrences of '{old_str}' with '{new_str}' in {filepath}"
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"message": f"Successfully replaced '{old_str}' with '{new_str}' in {filepath}",
|
||||
"message": success_msg,
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -53,17 +53,32 @@ def test_string_not_found(temp_test_dir):
|
|||
|
||||
|
||||
def test_multiple_occurrences(temp_test_dir):
|
||||
"""Test handling of multiple string occurrences."""
|
||||
"""Test handling of multiple string occurrences with replace_all=False."""
|
||||
test_file = temp_test_dir / "test.txt"
|
||||
test_file.write_text("test test test")
|
||||
|
||||
result = file_str_replace.invoke(
|
||||
{"filepath": str(test_file), "old_str": "test", "new_str": "replacement"}
|
||||
{"filepath": str(test_file), "old_str": "test", "new_str": "replacement", "replace_all": False}
|
||||
)
|
||||
|
||||
assert result["success"] is False
|
||||
assert "appears" in result["message"]
|
||||
assert "must be unique" in result["message"]
|
||||
assert "use replace_all=True" in result["message"]
|
||||
|
||||
|
||||
def test_multiple_occurrences_replace_all(temp_test_dir):
|
||||
"""Test replacing all occurrences when replace_all is True."""
|
||||
test_file = temp_test_dir / "test.txt"
|
||||
test_file.write_text("test test test")
|
||||
|
||||
result = file_str_replace.invoke(
|
||||
{"filepath": str(test_file), "old_str": "test", "new_str": "replacement", "replace_all": True}
|
||||
)
|
||||
|
||||
assert result["success"] is True
|
||||
assert "Successfully replaced 3 occurrences" in result["message"]
|
||||
assert test_file.read_text() == "replacement replacement replacement"
|
||||
|
||||
|
||||
def test_empty_strings(temp_test_dir):
|
||||
|
|
@ -165,4 +180,4 @@ def test_long_string_truncation(temp_test_dir):
|
|||
)
|
||||
|
||||
assert result["success"] is True
|
||||
assert test_file.read_text() == "prefix replaced suffix"
|
||||
assert test_file.read_text() == "prefix replaced suffix"
|
||||
Loading…
Reference in New Issue