import os
import tempfile
import subprocess
import difflib
from ..ui.diff_display import display_diff, get_diff_stats, DiffDisplay
def apply_patch(filepath, patch_content, db_conn=None):
try:
path = os.path.expanduser(filepath)
if db_conn:
from pr.tools.database import db_get
read_status = db_get("read:" + path, db_conn)
if read_status.get("status") != "success" or read_status.get("value") != "true":
return {"status": "error", "error": "File must be read before writing. Please read the file first."}
# Write patch to temp file
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.patch') as f:
f.write(patch_content)
patch_file = f.name
# Run patch command
result = subprocess.run(['patch', path, patch_file], capture_output=True, text=True, cwd=os.path.dirname(path))
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)}
def create_diff(file1, file2, fromfile='file1', tofile='file2', visual=False, format_type='unified'):
try:
path1 = os.path.expanduser(file1)
path2 = os.path.expanduser(file2)
with open(path1, 'r') as f1, open(path2, 'r') as f2:
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)
plain_diff = list(difflib.unified_diff(lines1, lines2, fromfile=fromfile, tofile=tofile))
return {
"status": "success",
"diff": ''.join(plain_diff),
"visual_diff": visual_diff,
"stats": stats
}
else:
lines1 = content1.splitlines(keepends=True)
lines2 = content2.splitlines(keepends=True)
diff = list(difflib.unified_diff(lines1, lines2, fromfile=fromfile, tofile=tofile))
return {"status": "success", "diff": ''.join(diff)}
except Exception as e:
return {"status": "error", "error": str(e)}
def display_file_diff(filepath1, filepath2, format_type='unified', context_lines=3):
try:
path1 = os.path.expanduser(filepath1)
path2 = os.path.expanduser(filepath2)
with open(path1, 'r') as f1:
old_content = f1.read()
with open(path2, 'r') as f2:
new_content = f2.read()
visual_diff = display_diff(old_content, new_content, filepath1, format_type)
stats = get_diff_stats(old_content, new_content)
return {
"status": "success",
"visual_diff": visual_diff,
"stats": stats
}
except Exception as e:
return {"status": "error", "error": str(e)}
def display_content_diff(old_content, new_content, filename='file', format_type='unified'):
try:
visual_diff = display_diff(old_content, new_content, filename, format_type)
stats = get_diff_stats(old_content, new_content)
return {
"status": "success",
"visual_diff": visual_diff,
"stats": stats
}
except Exception as e:
return {"status": "error", "error": str(e)}