allow multiple string replacements

This commit is contained in:
AI Christianson 2025-03-04 21:34:29 -05:00
parent c9f3f37ca3
commit 0b621b6008
2 changed files with 34 additions and 9 deletions

View File

@ -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:

View File

@ -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"