mirror of
https://github.com/NCBM/plyngent.git
synced 2026-11-07 23:47:54 +08:00
cli: pretty printed summaries for file mutation tools
This commit is contained in:
@@ -44,6 +44,12 @@ _PRETTY_TOOLS = frozenset(
|
|||||||
"run_argv",
|
"run_argv",
|
||||||
"run_argv_batch",
|
"run_argv_batch",
|
||||||
"fetch",
|
"fetch",
|
||||||
|
"edit_replace",
|
||||||
|
"edit_lineno",
|
||||||
|
"write_file",
|
||||||
|
"copy_path",
|
||||||
|
"move_path",
|
||||||
|
"delete_path",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -384,6 +390,29 @@ def _fetch_pretty(args_json: str, result: str) -> str:
|
|||||||
return _pretty_line(f"* {method} {status} {url}", (detail, _http_status_fg(status)))
|
return _pretty_line(f"* {method} {status} {url}", (detail, _http_status_fg(status)))
|
||||||
|
|
||||||
|
|
||||||
|
_MUTATOR_VERBS: dict[str, str] = {
|
||||||
|
"edit_replace": "Edited",
|
||||||
|
"edit_lineno": "Edited",
|
||||||
|
"write_file": "Wrote",
|
||||||
|
"copy_path": "Copied",
|
||||||
|
"move_path": "Moved",
|
||||||
|
"delete_path": "Deleted",
|
||||||
|
}
|
||||||
|
|
||||||
|
_MUTATOR_LOWER_PREFIXES = ("wrote ", "copied ", "moved ", "deleted ")
|
||||||
|
|
||||||
|
|
||||||
|
def _mutator_pretty(name: str, result: str) -> str:
|
||||||
|
"""One-line summary for file-mutation tools: ``* Wrote 120 characters to src/x.py``."""
|
||||||
|
verb = _MUTATOR_VERBS[name]
|
||||||
|
if result.startswith("error:"):
|
||||||
|
return _pretty_line(f"* {verb} ", (f"({result})", "red"))
|
||||||
|
for prefix in _MUTATOR_LOWER_PREFIXES:
|
||||||
|
if result.startswith(prefix):
|
||||||
|
return _pretty_line(f"* {verb} {result[len(prefix) :]}")
|
||||||
|
return _pretty_line(f"* {verb}: {result}")
|
||||||
|
|
||||||
|
|
||||||
_PRETTY_BUILDERS: dict[str, Callable[[str, str], str]] = {
|
_PRETTY_BUILDERS: dict[str, Callable[[str, str], str]] = {
|
||||||
"read_file": _read_file_pretty,
|
"read_file": _read_file_pretty,
|
||||||
"tree": _tree_pretty,
|
"tree": _tree_pretty,
|
||||||
@@ -395,6 +424,12 @@ _PRETTY_BUILDERS: dict[str, Callable[[str, str], str]] = {
|
|||||||
"run_argv": _run_argv_pretty,
|
"run_argv": _run_argv_pretty,
|
||||||
"run_argv_batch": _run_argv_batch_pretty,
|
"run_argv_batch": _run_argv_batch_pretty,
|
||||||
"fetch": _fetch_pretty,
|
"fetch": _fetch_pretty,
|
||||||
|
"edit_replace": lambda _args, result: _mutator_pretty("edit_replace", result),
|
||||||
|
"edit_lineno": lambda _args, result: _mutator_pretty("edit_lineno", result),
|
||||||
|
"write_file": lambda _args, result: _mutator_pretty("write_file", result),
|
||||||
|
"copy_path": lambda _args, result: _mutator_pretty("copy_path", result),
|
||||||
|
"move_path": lambda _args, result: _mutator_pretty("move_path", result),
|
||||||
|
"delete_path": lambda _args, result: _mutator_pretty("delete_path", result),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -449,3 +449,33 @@ async def test_pretty_fetch_error(capsys: pytest.CaptureFixture[str]) -> None:
|
|||||||
)
|
)
|
||||||
out = capsys.readouterr().out
|
out = capsys.readouterr().out
|
||||||
assert "* GET (error: fetch failed: boom)" in out
|
assert "* GET (error: fetch failed: boom)" in out
|
||||||
|
|
||||||
|
|
||||||
|
async def test_pretty_mutators(capsys: pytest.CaptureFixture[str]) -> None:
|
||||||
|
cases = [
|
||||||
|
("write_file", "wrote 120 characters to src/x.py", "* Wrote 120 characters to src/x.py"),
|
||||||
|
(
|
||||||
|
"edit_replace",
|
||||||
|
"replaced 1 occurrence in src/a.py ('x' → 'y')",
|
||||||
|
"* Edited: replaced 1 occurrence in src/a.py ('x' → 'y')",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"edit_lineno",
|
||||||
|
"replaced lines 3-5 (3 lines; first: 'pass') with 2 lines in src/a.py",
|
||||||
|
"* Edited: replaced lines 3-5 (3 lines; first: 'pass') with 2 lines in src/a.py",
|
||||||
|
),
|
||||||
|
("copy_path", "copied file a.txt -> b.txt", "* Copied file a.txt -> b.txt"),
|
||||||
|
("move_path", "moved directory src -> dst", "* Moved directory src -> dst"),
|
||||||
|
("delete_path", "deleted file tmp/x.txt", "* Deleted file tmp/x.txt"),
|
||||||
|
]
|
||||||
|
for name, content, expected in cases:
|
||||||
|
await render_events(_aiter([_pretty_call(name, "{}"), _result(content)]))
|
||||||
|
out = capsys.readouterr().out
|
||||||
|
assert expected in out, f"{name}: expected {expected!r} in {out!r}"
|
||||||
|
assert "[tool ok]" not in out
|
||||||
|
|
||||||
|
|
||||||
|
async def test_pretty_mutator_error(capsys: pytest.CaptureFixture[str]) -> None:
|
||||||
|
await render_events(_aiter([_pretty_call("copy_path", "{}"), _result("error: source does not exist: x")]))
|
||||||
|
out = capsys.readouterr().out
|
||||||
|
assert "* Copied (error: source does not exist: x)" in out
|
||||||
|
|||||||
Reference in New Issue
Block a user