/usr/share/pyshared/bzrlib/mergetools.py is in python-bzrlib 2.6.0~bzr6526-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | # Copyright (C) 2010 Canonical Ltd.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
"""Utility functions for managing external merge tools such as kdiff3."""
from __future__ import absolute_import
import os
import shutil
import subprocess
import sys
import tempfile
from bzrlib.lazy_import import lazy_import
lazy_import(globals(), """
from bzrlib import (
cmdline,
osutils,
trace,
)
""")
known_merge_tools = {
'bcompare': 'bcompare {this} {other} {base} {result}',
'kdiff3': 'kdiff3 {base} {this} {other} -o {result}',
'xdiff': 'xxdiff -m -O -M {result} {this} {base} {other}',
'meld': 'meld {base} {this_temp} {other}',
'opendiff': 'opendiff {this} {other} -ancestor {base} -merge {result}',
'winmergeu': 'winmergeu {result}',
}
def check_availability(command_line):
cmd_list = cmdline.split(command_line)
exe = cmd_list[0]
if sys.platform == 'win32':
exe = _get_executable_path(exe)
if exe is None:
return False
base, ext = os.path.splitext(exe)
path_ext = [unicode(s.lower())
for s in os.getenv('PATHEXT', '').split(os.pathsep)]
return os.path.exists(exe) and ext in path_ext
else:
return (os.access(exe, os.X_OK)
or osutils.find_executable_on_path(exe) is not None)
def invoke(command_line, filename, invoker=None):
"""Invokes the given merge tool command line, substituting the given
filename according to the embedded substitution markers. Optionally, it
will use the given invoker function instead of the default
subprocess_invoker.
"""
if invoker is None:
invoker = subprocess_invoker
cmd_list = cmdline.split(command_line)
exe = _get_executable_path(cmd_list[0])
if exe is not None:
cmd_list[0] = exe
args, tmp_file = _subst_filename(cmd_list, filename)
def cleanup(retcode):
if tmp_file is not None:
if retcode == 0: # on success, replace file with temp file
shutil.move(tmp_file, filename)
else: # otherwise, delete temp file
os.remove(tmp_file)
return invoker(args[0], args[1:], cleanup)
def _get_executable_path(exe):
if os.path.isabs(exe):
return exe
return osutils.find_executable_on_path(exe)
def _subst_filename(args, filename):
subst_names = {
'base': filename + u'.BASE',
'this': filename + u'.THIS',
'other': filename + u'.OTHER',
'result': filename,
}
tmp_file = None
subst_args = []
for arg in args:
if '{this_temp}' in arg and not 'this_temp' in subst_names:
fh, tmp_file = tempfile.mkstemp(u"_bzr_mergetools_%s.THIS" %
os.path.basename(filename))
trace.mutter('fh=%r, tmp_file=%r', fh, tmp_file)
os.close(fh)
shutil.copy(filename + u".THIS", tmp_file)
subst_names['this_temp'] = tmp_file
arg = _format_arg(arg, subst_names)
subst_args.append(arg)
return subst_args, tmp_file
# This would be better implemented using format() from python 2.6
def _format_arg(arg, subst_names):
arg = arg.replace('{base}', subst_names['base'])
arg = arg.replace('{this}', subst_names['this'])
arg = arg.replace('{other}', subst_names['other'])
arg = arg.replace('{result}', subst_names['result'])
if subst_names.has_key('this_temp'):
arg = arg.replace('{this_temp}', subst_names['this_temp'])
return arg
def subprocess_invoker(executable, args, cleanup):
retcode = subprocess.call([executable] + args)
cleanup(retcode)
return retcode
|