Add example
This commit is contained in:
parent
545be141d8
commit
92e0697b05
4 changed files with 90 additions and 1 deletions
|
|
@ -104,7 +104,7 @@ result = reconcile(parent, left, right)
|
||||||
print(result["text"]) # "Hi beautiful world"
|
print(result["text"]) # "Hi beautiful world"
|
||||||
```
|
```
|
||||||
|
|
||||||
See the [advanced Python examples](docs/advanced-python.md) for cursor tracking, change provenance, and compact diffs.
|
See the [merge-file example](examples/merge_file.py) for a file-merging CLI, or the [advanced examples document](docs/advanced-python.md) for cursor tracking, change provenance, and compact diffs.
|
||||||
|
|
||||||
## Motivation
|
## Motivation
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,3 +86,7 @@ assert reconstructed == changed
|
||||||
```
|
```
|
||||||
|
|
||||||
Diff entries are positive integers (retain N characters), negative integers (delete N characters), and strings (insert text).
|
Diff entries are positive integers (retain N characters), negative integers (delete N characters), and strings (insert text).
|
||||||
|
|
||||||
|
## File Merging Example
|
||||||
|
|
||||||
|
For a complete file-merging CLI (a trivial `git merge-file`), see [`examples/merge_file.py`](../examples/merge_file.py).
|
||||||
|
|
|
||||||
38
examples/merge_file.py
Normal file
38
examples/merge_file.py
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
"""Merge three versions of a file: mine, base, and theirs.
|
||||||
|
|
||||||
|
A trivial version of git merge-file (https://git-scm.com/docs/git-merge-file).
|
||||||
|
|
||||||
|
Run it with:
|
||||||
|
uv run --directory reconcile-python \
|
||||||
|
python ../examples/merge_file.py my.txt base.txt their.txt [output.txt]
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from reconcile_text import reconcile
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
args = sys.argv[1:]
|
||||||
|
|
||||||
|
if len(args) < 3 or len(args) > 4:
|
||||||
|
print("Usage: merge_file.py <mine> <base> <theirs> [output]", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
mine = Path(args[0]).read_text()
|
||||||
|
base = Path(args[1]).read_text()
|
||||||
|
theirs = Path(args[2]).read_text()
|
||||||
|
|
||||||
|
result = reconcile(base, mine, theirs)
|
||||||
|
|
||||||
|
if len(args) == 4:
|
||||||
|
Path(args[3]).write_text(result["text"])
|
||||||
|
else:
|
||||||
|
print(result["text"], end="")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from reconcile_text import diff, reconcile, reconcile_with_history, undiff
|
from reconcile_text import diff, reconcile, reconcile_with_history, undiff
|
||||||
|
|
||||||
|
EXAMPLES_DIR = Path(__file__).resolve().parent.parent.parent / "examples"
|
||||||
RESOURCES_DIR = Path(__file__).resolve().parent.parent.parent / "tests" / "resources"
|
RESOURCES_DIR = Path(__file__).resolve().parent.parent.parent / "tests" / "resources"
|
||||||
|
|
||||||
FILES = ["pride_and_prejudice.txt", "room_with_a_view.txt", "blns.txt"]
|
FILES = ["pride_and_prejudice.txt", "room_with_a_view.txt", "blns.txt"]
|
||||||
|
|
@ -118,6 +121,50 @@ class TestUndiff:
|
||||||
undiff("short", [100])
|
undiff("short", [100])
|
||||||
|
|
||||||
|
|
||||||
|
class TestExamples:
|
||||||
|
def test_merge_file_stdout(self, tmp_path: Path) -> None:
|
||||||
|
(tmp_path / "base.txt").write_text("Hello world")
|
||||||
|
(tmp_path / "mine.txt").write_text("Hello beautiful world")
|
||||||
|
(tmp_path / "theirs.txt").write_text("Hi world")
|
||||||
|
|
||||||
|
result = subprocess.run(
|
||||||
|
[
|
||||||
|
sys.executable,
|
||||||
|
str(EXAMPLES_DIR / "merge_file.py"),
|
||||||
|
str(tmp_path / "mine.txt"),
|
||||||
|
str(tmp_path / "base.txt"),
|
||||||
|
str(tmp_path / "theirs.txt"),
|
||||||
|
],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result.stdout == "Hi beautiful world"
|
||||||
|
|
||||||
|
def test_merge_file_output_file(self, tmp_path: Path) -> None:
|
||||||
|
(tmp_path / "base.txt").write_text("Hello world")
|
||||||
|
(tmp_path / "mine.txt").write_text("Hello beautiful world")
|
||||||
|
(tmp_path / "theirs.txt").write_text("Hi world")
|
||||||
|
output = tmp_path / "output.txt"
|
||||||
|
|
||||||
|
subprocess.run(
|
||||||
|
[
|
||||||
|
sys.executable,
|
||||||
|
str(EXAMPLES_DIR / "merge_file.py"),
|
||||||
|
str(tmp_path / "mine.txt"),
|
||||||
|
str(tmp_path / "base.txt"),
|
||||||
|
str(tmp_path / "theirs.txt"),
|
||||||
|
str(output),
|
||||||
|
],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert output.read_text() == "Hi beautiful world"
|
||||||
|
|
||||||
|
|
||||||
class TestDiffUndiffInverse:
|
class TestDiffUndiffInverse:
|
||||||
"""Verify diff/undiff roundtrip across large real-world texts."""
|
"""Verify diff/undiff roundtrip across large real-world texts."""
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue