[meld] Remove old-style patch-based file retrieval, moving into CVS
- From: Kai Willadsen <kaiw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [meld] Remove old-style patch-based file retrieval, moving into CVS
- Date: Fri, 21 Jun 2013 22:04:21 +0000 (UTC)
commit 5be1c94c838326125a36f625ece3431c73361f52
Author: Kai Willadsen <kai willadsen gmail com>
Date: Sun Jun 16 08:34:08 2013 +1000
Remove old-style patch-based file retrieval, moving into CVS
The old-style patching has been removed for every VC that gives us
direct access to files. CVS is the only hold-out, so it gets to suffer
the missing error messages.
meld/vc/_vc.py | 9 ---
meld/vc/bzr.py | 1 -
meld/vc/cvs.py | 51 +++++++++++++++
meld/vc/darcs.py | 2 -
meld/vc/fossil.py | 1 -
meld/vc/monotone.py | 1 -
meld/vc/svk.py | 1 -
meld/vc/svn.py | 9 +---
meld/vcview.py | 169 +++++++++++----------------------------------------
9 files changed, 88 insertions(+), 156 deletions(-)
---
diff --git a/meld/vc/_vc.py b/meld/vc/_vc.py
index e7590af..121c593 100644
--- a/meld/vc/_vc.py
+++ b/meld/vc/_vc.py
@@ -99,8 +99,6 @@ class File(Entry):
class Vc(object):
- PATCH_STRIP_NUM = 0
- PATCH_INDEX_RE = ''
VC_DIR = None
VC_ROOT_WALK = True
VC_METADATA = None
@@ -144,9 +142,6 @@ class Vc(object):
def resolved_command(self):
raise NotImplementedError()
- def patch_command(self, workdir):
- return ["patch", "-p%i" % self.PATCH_STRIP_NUM, "-R", "-d", workdir]
-
# Prototyping VC interface version 2
def get_files_to_commit(self, paths):
@@ -230,10 +225,6 @@ class Vc(object):
"""
pass
- def get_patch_files(self, patch):
- regex = re.compile(self.PATCH_INDEX_RE, re.M)
- return [f.strip() for f in regex.findall(patch)]
-
# Determine if a directory is a valid git/svn/hg/cvs/etc repository
def valid_repo(self):
return True
diff --git a/meld/vc/bzr.py b/meld/vc/bzr.py
index 8e83d6a..49662ac 100644
--- a/meld/vc/bzr.py
+++ b/meld/vc/bzr.py
@@ -38,7 +38,6 @@ class Vc(_vc.CachedVc):
CMDARGS = ["--no-aliases", "--no-plugins"]
NAME = "Bazaar"
VC_DIR = ".bzr"
- PATCH_INDEX_RE = "^=== modified file '(.*)'.*$"
CONFLICT_RE = "conflict in (.*)$"
commit_statuses = (
diff --git a/meld/vc/cvs.py b/meld/vc/cvs.py
index 4a9c898..7afbff1 100644
--- a/meld/vc/cvs.py
+++ b/meld/vc/cvs.py
@@ -26,12 +26,19 @@ import logging
import os
from gettext import gettext as _
import re
+import shutil
+import tempfile
import time
from meld import misc
from . import _vc
+class FakeErrorStream(object):
+ def error(self, error):
+ pass
+
+
class Vc(_vc.Vc):
CMD = "cvs"
# CVSNT is a drop-in replacement for CVS; if found, it is used instead
@@ -39,6 +46,7 @@ class Vc(_vc.Vc):
NAME = "CVS"
VC_DIR = "CVS"
VC_ROOT_WALK = False
+ PATCH_STRIP_NUM = 0
PATCH_INDEX_RE = "^Index:(.*)$"
VC_COLUMNS = (_vc.DATA_NAME, _vc.DATA_STATE, _vc.DATA_REVISION,
@@ -74,6 +82,49 @@ class Vc(_vc.Vc):
else:
return False
+ def get_path_for_repo_file(self, path, commit=None):
+ if commit is not None:
+ raise NotImplementedError
+
+ if not path.startswith(self.root + os.path.sep):
+ raise _vc.InvalidVCPath(self, path, "Path not in repository")
+ path = path[len(self.root) + 1:]
+
+ diffiter = misc.read_pipe_iter(self.diff_command() + [path],
+ FakeErrorStream(), workdir=self.root)
+ patch = None
+ while patch is None:
+ patch = next(diffiter)
+
+ tmpdir = tempfile.mkdtemp("-meld")
+ destfile = os.path.join(tmpdir, os.path.basename(path))
+
+ try:
+ shutil.copyfile(os.path.join(self.root, path), destfile)
+ except IOError:
+ # For missing files, create a new empty file
+ open(destfile, "w").close()
+
+ patchcmd = ["patch", "-R", "-d", tmpdir]
+ try:
+ with open(os.devnull, "w") as NULL:
+ result = misc.write_pipe(patchcmd, patch, error=NULL)
+ assert result == 0
+
+ with open(destfile) as patched_file:
+ with tempfile.NamedTemporaryFile(prefix='meld-tmp',
+ delete=False) as temp_file:
+ shutil.copyfileobj(patched_file, temp_file)
+
+ return temp_file.name
+ except (OSError, AssertionError):
+ return
+ finally:
+ if os.path.exists(destfile):
+ os.remove(destfile)
+ if os.path.exists(destfile):
+ os.rmdir(tmpdir)
+
def _get_dirsandfiles(self, directory, dirs, files):
log = logging.getLogger(__name__)
diff --git a/meld/vc/darcs.py b/meld/vc/darcs.py
index 0860516..a5073d8 100644
--- a/meld/vc/darcs.py
+++ b/meld/vc/darcs.py
@@ -35,8 +35,6 @@ class Vc(_vc.CachedVc):
CMD = "darcs"
NAME = "Darcs"
VC_DIR = "_darcs"
- PATCH_STRIP_NUM = 1
- PATCH_INDEX_RE = "--- old.+?/(.+?)\\t+.*[0-9]{4}$"
state_map = {
"a": _vc.STATE_NONE,
"A": _vc.STATE_NEW,
diff --git a/meld/vc/fossil.py b/meld/vc/fossil.py
index 3f08f76..344332e 100644
--- a/meld/vc/fossil.py
+++ b/meld/vc/fossil.py
@@ -38,7 +38,6 @@ class Vc(_vc.CachedVc):
CMD = "fossil"
NAME = "Fossil"
VC_METADATA = [".fslckout", "_FOSSIL_", ".fos"] # One or the other
- PATCH_INDEX_RE = "^--- (.*)$"
VC_COLUMNS = (_vc.DATA_NAME, _vc.DATA_STATE, _vc.DATA_REVISION)
diff --git a/meld/vc/monotone.py b/meld/vc/monotone.py
index 384f106..e2812b7 100644
--- a/meld/vc/monotone.py
+++ b/meld/vc/monotone.py
@@ -36,7 +36,6 @@ class Vc(_vc.CachedVc):
CMD = "mtn"
NAME = "Monotone"
VC_DIR = "_MTN"
- PATCH_INDEX_RE = "^[+]{3,3} ([^ ]*)\t[0-9a-f]{40,40}$"
state_map_6 = {
'added known rename_source' : _vc.STATE_NEW,
diff --git a/meld/vc/svk.py b/meld/vc/svk.py
index 76c377c..e7b7e86 100644
--- a/meld/vc/svk.py
+++ b/meld/vc/svk.py
@@ -49,7 +49,6 @@ class Vc(svn.Vc):
CMD = "svk"
NAME = "SVK"
- PATCH_INDEX_RE = "^=== (.*)$"
def check_repo_root(self, location):
try:
diff --git a/meld/vc/svn.py b/meld/vc/svn.py
index 8b27275..dad97d6 100644
--- a/meld/vc/svn.py
+++ b/meld/vc/svn.py
@@ -38,7 +38,6 @@ class Vc(_vc.CachedVc):
NAME = "Subversion"
VC_DIR = ".svn"
VC_ROOT_WALK = False
- PATCH_INDEX_RE = "^Index:(.*)$"
VC_COLUMNS = (_vc.DATA_NAME, _vc.DATA_STATE, _vc.DATA_REVISION)
@@ -56,10 +55,7 @@ class Vc(_vc.CachedVc):
def commit_command(self, message):
return [self.CMD,"commit","-m",message]
def diff_command(self):
- if hasattr(self, "external_diff"):
- return [self.CMD, "diff", "--diff-cmd", self.external_diff]
- else:
- return [self.CMD, "diff"]
+ return [self.CMD, "diff"]
def update_command(self):
return [self.CMD,"update"]
@@ -170,9 +166,6 @@ class Vc(_vc.CachedVc):
content = f.readline().strip()
return self._repo_version_support(int(content))
- def switch_to_external_diff(self):
- self.external_diff = "diff"
-
def _update_tree_state_cache(self, path, tree_state):
while 1:
try:
diff --git a/meld/vcview.py b/meld/vcview.py
index 0ea58ba..12219b6 100644
--- a/meld/vcview.py
+++ b/meld/vcview.py
@@ -570,71 +570,43 @@ class VcView(melddoc.MeldDoc, gnomeglade.Component):
path = self.model.value_path(it, 0)
self.run_diff([path])
- def run_diff_iter(self, path_list):
- silent_error = hasattr(self.vc, 'switch_to_external_diff')
- retry_diff = True
- while retry_diff:
- retry_diff = False
-
- yield _("[%s] Fetching differences") % self.label_text
- diffiter = self._command_iter(self.vc.diff_command(), path_list, 0)
- diff = None
- while type(diff) != type(()):
- diff = next(diffiter)
- yield 1
- prefix, patch = diff[0], diff[1]
-
- yield _("[%s] Applying patch") % self.label_text
- if patch:
- applied = self.show_patch(prefix, patch, silent=silent_error)
- if not applied and silent_error:
- silent_error = False
- self.vc.switch_to_external_diff()
- retry_diff = True
- else:
- for path in path_list:
- self.emit("create-diff", [path], {})
-
def run_diff(self, path_list):
- try:
- for path in path_list:
- if os.path.isdir(path):
- self.emit("create-diff", [path], {})
- continue
-
- kwargs = {}
- vc_file = self.vc.lookup_files(
- [], [(os.path.basename(path), path)])[1][0]
- if vc_file.state == tree.STATE_CONFLICT:
- # We use auto merge, so we create a new temp file
- # for other, base and this, then set the output to
- # the current file.
-
- conflicts = (tree.CONFLICT_OTHER, tree.CONFLICT_MERGED,
- tree.CONFLICT_THIS)
- diffs = [self.vc.get_path_for_conflict(path, conflict=c)
- for c in conflicts]
- for conflict_path, is_temp in diffs:
- # If this is the actual file, don't touch it.
- if conflict_path != path and is_temp:
- os.chmod(conflict_path, 0o444)
- _temp_files.append(conflict_path)
- # create-diff expects only the paths
- diffs = [p for p, is_temp in diffs]
-
- # If we want to use auto-merge or use the merged
- # output given by the VCS
- kwargs['auto_merge'] = False
- kwargs['merge_output'] = path
- else:
- comp_path = self.vc.get_path_for_repo_file(path)
- os.chmod(comp_path, 0o444)
- _temp_files.append(comp_path)
- diffs = [comp_path, path]
- self.emit("create-diff", diffs, kwargs)
- except NotImplementedError:
- for path in path_list:
- self.scheduler.add_task(self.run_diff_iter([path]), atfront=1)
+ for path in path_list:
+ if os.path.isdir(path):
+ self.emit("create-diff", [path], {})
+ continue
+
+ kwargs = {}
+ vc_file = self.vc.lookup_files(
+ [], [(os.path.basename(path), path)])[1][0]
+ if vc_file.state == tree.STATE_CONFLICT and \
+ hasattr(self.vc, 'get_path_for_conflict'):
+ # We use auto merge, so we create a new temp file
+ # for other, base and this, then set the output to
+ # the current file.
+
+ conflicts = (tree.CONFLICT_OTHER, tree.CONFLICT_MERGED,
+ tree.CONFLICT_THIS)
+ diffs = [self.vc.get_path_for_conflict(path, conflict=c)
+ for c in conflicts]
+ for conflict_path, is_temp in diffs:
+ # If this is the actual file, don't touch it.
+ if conflict_path != path and is_temp:
+ os.chmod(conflict_path, 0o444)
+ _temp_files.append(conflict_path)
+ # create-diff expects only the paths
+ diffs = [p for p, is_temp in diffs]
+
+ # If we want to use auto-merge or use the merged
+ # output given by the VCS
+ kwargs['auto_merge'] = False
+ kwargs['merge_output'] = path
+ else:
+ comp_path = self.vc.get_path_for_repo_file(path)
+ os.chmod(comp_path, 0o444)
+ _temp_files.append(comp_path)
+ diffs = [comp_path, path]
+ self.emit("create-diff", diffs, kwargs)
def on_treeview_popup_menu(self, treeview):
time = gtk.get_current_event_time()
@@ -828,75 +800,6 @@ class VcView(melddoc.MeldDoc, gnomeglade.Component):
def open_external(self):
self._open_files(self._get_selected_files())
- def show_patch(self, prefix, patch, silent=False):
- if vc._vc.call(["which", "patch"]):
- primary = _("Patch tool not found")
- secondary = _("Meld needs the <i>patch</i> tool to be installed "
- "to perform comparisons in %s repositories. Please "
- "install <i>patch</i> and try again.") % self.vc.NAME
-
- msgarea = self.msgarea_mgr.new_from_text_and_icon(
- gtk.STOCK_DIALOG_ERROR, primary, secondary)
- msgarea.add_button(_("Hi_de"), gtk.RESPONSE_CLOSE)
- msgarea.connect("response", lambda *args: self.msgarea_mgr.clear())
- msgarea.show_all()
- return False
-
- tmpdir = tempfile.mkdtemp("-meld")
- _temp_dirs.append(tmpdir)
-
- diffs = []
- for fname in self.vc.get_patch_files(patch):
- destfile = os.path.join(tmpdir, fname)
- destdir = os.path.dirname(destfile)
-
- if not os.path.exists(destdir):
- os.makedirs(destdir)
- pathtofile = os.path.join(prefix, fname)
- try:
- shutil.copyfile(pathtofile, destfile)
- except IOError:
- # it is missing, create empty file
- open(destfile, "w").close()
- diffs.append((destfile, pathtofile))
-
- patchcmd = self.vc.patch_command(tmpdir)
- try:
- with open(os.devnull, "w") as NULL:
- result = misc.write_pipe(patchcmd, patch, error=NULL)
- except OSError:
- result = 1
-
- if result == 0:
- for d in diffs:
- os.chmod(d[0], 0o444)
- self.emit("create-diff", d, {})
- return True
- elif not silent:
- primary = _("Error fetching original comparison file")
- secondary = _("Meld couldn't obtain the original version of your "
- "comparison file. If you are using the most recent "
- "version of Meld, please report a bug, including as "
- "many details as possible.")
-
- msgarea = self.msgarea_mgr.new_from_text_and_icon(
- gtk.STOCK_DIALOG_ERROR, primary, secondary)
- msgarea.add_button(_("Hi_de"), gtk.RESPONSE_CLOSE)
- msgarea.add_button(_("Report a bug"), gtk.RESPONSE_OK)
-
- def patch_error_cb(msgarea, response):
- if response == gtk.RESPONSE_OK:
- bug_url = "https://bugzilla.gnome.org/enter_bug.cgi?" + \
- "product=meld"
- misc.open_uri(bug_url)
- else:
- self.msgarea_mgr.clear()
-
- msgarea.connect("response", patch_error_cb)
- msgarea.show_all()
-
- return False
-
def refresh(self):
self.set_location(self.model.value_path(self.model.get_iter_root(), 0))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]