123 lines
4.2 KiB
Python
Raw Normal View History

2025-11-04 08:09:12 +01:00
import difflib
2025-11-04 05:17:27 +01:00
import os
import subprocess
2025-11-04 08:09:12 +01:00
import tempfile
from ..ui.diff_display import display_diff, get_diff_stats
2025-11-04 05:17:27 +01:00
def apply_patch(filepath, patch_content, db_conn=None):
"""Apply a patch to a file.
Args:
filepath: Path to the file to patch.
patch_content: The patch content as a string.
db_conn: Database connection (optional).
Returns:
Dict with status and output.
"""
2025-11-04 05:17:27 +01:00
try:
path = os.path.expanduser(filepath)
if db_conn:
from pr.tools.database import db_get
2025-11-04 08:09:12 +01:00
2025-11-04 05:17:27 +01:00
read_status = db_get("read:" + path, db_conn)
2025-11-04 08:10:37 +01:00
if read_status.get("status") != "success" or read_status.get("value") != "true":
2025-11-04 08:09:12 +01:00
return {
"status": "error",
"error": "File must be read before writing. Please read the file first.",
}
2025-11-04 05:17:27 +01:00
# Write patch to temp file
2025-11-04 08:09:12 +01:00
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".patch") as f:
2025-11-04 05:17:27 +01:00
f.write(patch_content)
patch_file = f.name
# Run patch command
2025-11-04 08:09:12 +01:00
result = subprocess.run(
["patch", path, patch_file],
capture_output=True,
text=True,
cwd=os.path.dirname(path),
)
2025-11-04 05:17:27 +01:00
os.unlink(patch_file)
if result.returncode == 0:
return {"status": "success", "output": result.stdout.strip()}
else:
return {"status": "error", "error": result.stderr.strip()}
except Exception as e:
return {"status": "error", "error": str(e)}
2025-11-04 08:09:12 +01:00
def create_diff(
file1, file2, fromfile="file1", tofile="file2", visual=False, format_type="unified"
):
"""Create a unified diff between two files.
Args:
file1: Path to the first file.
file2: Path to the second file.
fromfile: Label for the first file.
tofile: Label for the second file.
visual: Whether to include visual diff.
format_type: Diff format type.
Returns:
Dict with status and diff content.
"""
2025-11-04 05:17:27 +01:00
try:
path1 = os.path.expanduser(file1)
path2 = os.path.expanduser(file2)
2025-11-04 08:09:12 +01:00
with open(path1) as f1, open(path2) as f2:
2025-11-04 05:17:27 +01:00
content1 = f1.read()
content2 = f2.read()
if visual:
visual_diff = display_diff(content1, content2, fromfile, format_type)
stats = get_diff_stats(content1, content2)
lines1 = content1.splitlines(keepends=True)
lines2 = content2.splitlines(keepends=True)
2025-11-04 08:09:12 +01:00
plain_diff = list(
difflib.unified_diff(lines1, lines2, fromfile=fromfile, tofile=tofile)
)
2025-11-04 05:17:27 +01:00
return {
"status": "success",
2025-11-04 08:09:12 +01:00
"diff": "".join(plain_diff),
2025-11-04 05:17:27 +01:00
"visual_diff": visual_diff,
2025-11-04 08:09:12 +01:00
"stats": stats,
2025-11-04 05:17:27 +01:00
}
else:
lines1 = content1.splitlines(keepends=True)
lines2 = content2.splitlines(keepends=True)
2025-11-04 08:10:37 +01:00
diff = list(difflib.unified_diff(lines1, lines2, fromfile=fromfile, tofile=tofile))
2025-11-04 08:09:12 +01:00
return {"status": "success", "diff": "".join(diff)}
2025-11-04 05:17:27 +01:00
except Exception as e:
return {"status": "error", "error": str(e)}
2025-11-04 08:09:12 +01:00
def display_file_diff(filepath1, filepath2, format_type="unified", context_lines=3):
2025-11-04 05:17:27 +01:00
try:
path1 = os.path.expanduser(filepath1)
path2 = os.path.expanduser(filepath2)
2025-11-04 08:09:12 +01:00
with open(path1) as f1:
2025-11-04 05:17:27 +01:00
old_content = f1.read()
2025-11-04 08:09:12 +01:00
with open(path2) as f2:
2025-11-04 05:17:27 +01:00
new_content = f2.read()
visual_diff = display_diff(old_content, new_content, filepath1, format_type)
stats = get_diff_stats(old_content, new_content)
2025-11-04 08:09:12 +01:00
return {"status": "success", "visual_diff": visual_diff, "stats": stats}
2025-11-04 05:17:27 +01:00
except Exception as e:
return {"status": "error", "error": str(e)}
2025-11-04 08:10:37 +01:00
def display_content_diff(old_content, new_content, filename="file", format_type="unified"):
2025-11-04 05:17:27 +01:00
try:
visual_diff = display_diff(old_content, new_content, filename, format_type)
stats = get_diff_stats(old_content, new_content)
2025-11-04 08:09:12 +01:00
return {"status": "success", "visual_diff": visual_diff, "stats": stats}
2025-11-04 05:17:27 +01:00
except Exception as e:
2025-11-04 08:09:12 +01:00
return {"status": "error", "error": str(e)}