2008-11-08 10:30:04 -05:00
|
|
|
import os, commands, re, tempfile
|
2008-03-17 02:17:51 -04:00
|
|
|
from subprocess import Popen, PIPE, STDOUT
|
|
|
|
|
2008-03-31 12:14:37 -04:00
|
|
|
import buffer, default, dirutil, lex, regex, util, window
|
2008-03-17 02:17:51 -04:00
|
|
|
from point import Point
|
|
|
|
|
2008-11-08 11:18:48 -05:00
|
|
|
from method import Method, Argument, arg
|
2008-03-17 02:17:51 -04:00
|
|
|
|
|
|
|
class CvsCommit(Method):
|
|
|
|
'''diff the current file with the version in CVS'''
|
2008-03-18 10:51:47 -04:00
|
|
|
args = [arg("msg", t=type(""), p="Commit Message: ",
|
|
|
|
h="commit message to send to CVS")]
|
2008-03-17 02:17:51 -04:00
|
|
|
regex = re.compile('^new revision: ([0-9.]+); previous revision: ([0-9.]+)$')
|
|
|
|
def _execute(self, w, **vargs):
|
|
|
|
if not hasattr(w.buffer, 'path'):
|
|
|
|
w.set_error("Buffer has no corresponding file")
|
|
|
|
return
|
|
|
|
|
2009-11-10 16:30:35 -05:00
|
|
|
cwd = os.getcwd() + os.path.sep
|
2008-03-17 02:17:51 -04:00
|
|
|
path = w.buffer.path
|
|
|
|
if path.startswith(cwd):
|
|
|
|
path = path[len(cwd):]
|
|
|
|
|
2009-11-10 16:30:35 -05:00
|
|
|
cmd = ["cvs", "ci", "-m", vargs['msg'], path]
|
2009-08-26 10:07:58 -04:00
|
|
|
status, out, err = util.communicate(cmd)
|
2008-03-17 02:17:51 -04:00
|
|
|
|
2009-11-10 16:30:35 -05:00
|
|
|
if status != 0:
|
2008-03-17 02:17:51 -04:00
|
|
|
w.set_error("Problems with CVS commit: %d" % status)
|
2009-11-10 16:30:35 -05:00
|
|
|
w.application.data_buffer("*Commit*", err, switch_to=True)
|
|
|
|
return
|
|
|
|
|
|
|
|
for line in out.split('\n'):
|
|
|
|
m = self.regex.match(line)
|
|
|
|
if not m:
|
|
|
|
continue
|
|
|
|
w.set_error("Committed [%s -> %s]" % (m.group(2), m.group(1)))
|
|
|
|
return
|
|
|
|
w.set_error("Up-to-date")
|
2008-03-17 02:17:51 -04:00
|
|
|
|
|
|
|
class CvsStatus(Method):
|
|
|
|
regex1 = re.compile('^File: (.+?) *\tStatus: (.*?)$')
|
|
|
|
regex2 = re.compile('^ Working revision:\t([0-9\.]+)$')
|
|
|
|
regex3 = re.compile('^ Repository revision:\t([0-9\.]+)\t(.*)$')
|
|
|
|
regex4 = re.compile('^ Sticky Tag:\t\t\((.*)\)$')
|
|
|
|
regex5 = re.compile('^ Sticky Date:\t\t\((.*)\)$')
|
|
|
|
regex6 = re.compile('^ Sticky Options:\t\((.*)\)$')
|
|
|
|
def _execute(self, w, **vargs):
|
|
|
|
if not hasattr(w.buffer, 'path'):
|
|
|
|
w.set_error("Buffer has no corresponding file")
|
|
|
|
return
|
|
|
|
|
|
|
|
cwd = os.getcwd() + os.path.sep
|
|
|
|
path = w.buffer.path
|
|
|
|
if path.startswith(cwd):
|
|
|
|
path = path[len(cwd):]
|
|
|
|
|
2009-11-10 16:30:35 -05:00
|
|
|
#cmd = "cvs status %r" % path
|
|
|
|
cmd = ['cvs', 'status', path]
|
2009-08-26 10:07:58 -04:00
|
|
|
status, out, err = util.communicate(cmd)
|
2008-03-17 02:17:51 -04:00
|
|
|
|
|
|
|
if status != 0:
|
|
|
|
w.set_error("Problems with CVS status: %d" % status)
|
|
|
|
return
|
|
|
|
|
2009-08-26 10:07:58 -04:00
|
|
|
lines = out.split('\n')
|
2008-03-17 02:17:51 -04:00
|
|
|
|
|
|
|
if lines[0].startswith('cvs status: nothing known about '):
|
|
|
|
w.set_error('File is not under CVS control')
|
|
|
|
return
|
|
|
|
|
|
|
|
m = self.regex1.match(lines[1])
|
|
|
|
assert m, "regex1 %r" % lines[1]
|
|
|
|
ffile = m.group(1)
|
|
|
|
fstatus = m.group(2)
|
|
|
|
|
|
|
|
m = self.regex2.match(lines[3])
|
|
|
|
assert m, "regex2 %r" % lines[3]
|
|
|
|
wrev = m.group(1)
|
|
|
|
|
|
|
|
m = self.regex3.match(lines[4])
|
|
|
|
assert m, "regex3 %r" % lines[4]
|
|
|
|
rrev = m.group(1)
|
|
|
|
rpath = m.group(2)
|
|
|
|
|
|
|
|
m = self.regex4.match(lines[5])
|
|
|
|
assert m, "regex4 %r" % lines[5]
|
|
|
|
stag = m.group(1)
|
|
|
|
|
|
|
|
m = self.regex5.match(lines[6])
|
|
|
|
assert m, "regex5 %r" % lines[6]
|
|
|
|
sdate = m.group(1)
|
|
|
|
|
|
|
|
m = self.regex6.match(lines[7])
|
|
|
|
assert m, "regex6 %r" % lines[7]
|
|
|
|
soptions = m.group(1)
|
|
|
|
|
2009-03-04 14:44:41 -05:00
|
|
|
w.buffer.metadata['cvs-filename'] = ffile
|
|
|
|
w.buffer.metadata['cvs-status'] = fstatus
|
|
|
|
w.buffer.metadata['cvs-wrev'] = wrev
|
|
|
|
w.buffer.metadata['cvs-rrev'] = rrev
|
|
|
|
w.buffer.metadata['cvs-tag'] = stag
|
|
|
|
w.buffer.metadata['cvs-date'] = sdate
|
|
|
|
w.buffer.metadata['vc-info'] = '[cvs:%s/%s]' % (wrev, rrev)
|
|
|
|
|
|
|
|
tpl = (ffile, fstatus, wrev, rrev, stag, sdate, soptions)
|
|
|
|
w.set_error('%s %s %s/%s [%s|%s|%s]' % tpl)
|
2008-03-17 02:17:51 -04:00
|
|
|
|
2008-09-18 14:12:29 -04:00
|
|
|
class CvsLog(Method):
|
|
|
|
'''diff the current file with the version in CVS'''
|
|
|
|
def _execute(self, w, **vargs):
|
|
|
|
if not hasattr(w.buffer, 'path'):
|
|
|
|
w.set_error("Buffer has no corresponding file")
|
|
|
|
return
|
|
|
|
|
|
|
|
cwd = os.getcwd() + os.path.sep
|
|
|
|
path = w.buffer.path
|
|
|
|
if path.startswith(cwd):
|
|
|
|
path = path[len(cwd):]
|
|
|
|
|
2009-11-10 16:30:35 -05:00
|
|
|
#cmd = "cvs log %r" % path
|
|
|
|
cmd = ['cvs', 'log', path]
|
2009-08-26 10:07:58 -04:00
|
|
|
status, out, err = util.communicate(cmd)
|
|
|
|
w.application.data_buffer("*Log*", out, switch_to=True)
|
2008-09-18 14:12:29 -04:00
|
|
|
w.set_error("cvs log exited with %d" % status)
|
|
|
|
|
2008-03-17 02:17:51 -04:00
|
|
|
class CvsDiff(Method):
|
|
|
|
'''diff the current file with the version in CVS'''
|
|
|
|
def _execute(self, w, **vargs):
|
|
|
|
if not hasattr(w.buffer, 'path'):
|
|
|
|
w.set_error("Buffer has no corresponding file")
|
|
|
|
return
|
|
|
|
|
|
|
|
cwd = os.getcwd() + os.path.sep
|
|
|
|
path = w.buffer.path
|
|
|
|
if path.startswith(cwd):
|
|
|
|
path = path[len(cwd):]
|
|
|
|
|
2009-11-10 16:30:35 -05:00
|
|
|
#cmd = "cvs diff -u %r" % path
|
|
|
|
cmd = ['cvs', 'diff', '-u', path]
|
2009-08-26 10:07:58 -04:00
|
|
|
status, out, err = util.communicate(cmd)
|
2008-03-17 02:17:51 -04:00
|
|
|
|
|
|
|
if status == 0:
|
|
|
|
w.set_error("No difference found")
|
|
|
|
else:
|
2009-08-26 10:07:58 -04:00
|
|
|
w.application.data_buffer("*Diff*", out, switch_to=True, modename='diff')
|
2008-03-17 02:17:51 -04:00
|
|
|
w.set_error("Differences were found")
|
|
|
|
class CvsDiff2(Method):
|
2008-03-18 10:51:47 -04:00
|
|
|
'''diff the current file's contents with a version in CVS'''
|
2008-03-17 02:17:51 -04:00
|
|
|
rev_regex = re.compile('^[0-9]+\.[0-9]+$')
|
2008-03-18 10:51:47 -04:00
|
|
|
args = [arg("revision", t=type(""), p="Old Revision: ",
|
|
|
|
h="revision number")]
|
2008-03-17 02:17:51 -04:00
|
|
|
def _execute(self, w, **vargs):
|
|
|
|
if not hasattr(w.buffer, 'path'):
|
|
|
|
w.set_error("Buffer has no corresponding file")
|
|
|
|
return
|
|
|
|
|
|
|
|
rev = vargs['revision']
|
|
|
|
if not self.rev_regex.match(rev):
|
|
|
|
w.set_error("Could not parse revision: %r" % rev)
|
|
|
|
return
|
|
|
|
|
|
|
|
cwd = os.getcwd() + os.path.sep
|
|
|
|
path = w.buffer.path
|
|
|
|
if path.startswith(cwd):
|
|
|
|
path = path[len(cwd):]
|
|
|
|
|
2009-11-10 16:30:35 -05:00
|
|
|
#cmd = "cvs diff -r %s -u %r" % (rev, path)
|
|
|
|
cmd = ["cvs", "diff", "-r", rev, "-u", path]
|
2009-08-26 10:07:58 -04:00
|
|
|
status, out, err = util.communicate(cmd)
|
2008-03-17 02:17:51 -04:00
|
|
|
|
|
|
|
if status == 0:
|
|
|
|
w.set_error("No difference found")
|
|
|
|
else:
|
2009-08-26 10:07:58 -04:00
|
|
|
w.application.data_buffer("*Diff*", out, switch_to=True, modename='diff')
|
2008-03-17 02:17:51 -04:00
|
|
|
w.set_error("Differences were found")
|
|
|
|
class CvsDiff3(Method):
|
|
|
|
'''diff the current file with the version in CVS'''
|
|
|
|
rev_regex = re.compile('^[0-9]+\.[0-9]+$')
|
2008-03-18 10:51:47 -04:00
|
|
|
args = [arg("revision1", t=type(""), p="Old Revision: ", h='old revision number'),
|
|
|
|
arg("revision2", t=type(""), p="New Revision: ", h='new revision number')]
|
2008-03-17 02:17:51 -04:00
|
|
|
def _execute(self, w, **vargs):
|
|
|
|
if not hasattr(w.buffer, 'path'):
|
|
|
|
w.set_error("Buffer has no corresponding file")
|
|
|
|
return
|
|
|
|
|
|
|
|
rev1 = vargs['revision1']
|
|
|
|
if not self.rev_regex.match(rev1):
|
|
|
|
w.set_error("Could not parse revision1: %r" % rev)
|
|
|
|
return
|
|
|
|
|
|
|
|
rev2 = vargs['revision2']
|
|
|
|
if not self.rev_regex.match(rev2):
|
|
|
|
w.set_error("Could not parse revision2: %r" % rev)
|
|
|
|
return
|
|
|
|
|
|
|
|
cwd = os.getcwd() + os.path.sep
|
|
|
|
path = w.buffer.path
|
|
|
|
if path.startswith(cwd):
|
|
|
|
path = path[len(cwd):]
|
|
|
|
|
2009-11-10 16:30:35 -05:00
|
|
|
#cmd = "cvs diff -r %s -r %s -u %r" % (rev1, rev2, path)
|
|
|
|
cmd = ["cvs", "diff", "-r", rev1, "-r", rev2, "-u", path]
|
2009-08-26 10:07:58 -04:00
|
|
|
status, out, err = util.communicate(cmd)
|
2008-03-17 02:17:51 -04:00
|
|
|
|
|
|
|
if status == 0:
|
|
|
|
w.set_error("No difference found")
|
|
|
|
else:
|
2009-08-26 10:07:58 -04:00
|
|
|
w.application.data_buffer("*Diff*", out, switch_to=True, modename='diff')
|
2008-03-17 02:17:51 -04:00
|
|
|
w.set_error("Differences were found")
|
2008-03-31 12:14:37 -04:00
|
|
|
|
2008-03-17 02:17:51 -04:00
|
|
|
class CvsBlame(Method):
|
2009-07-20 19:08:27 -04:00
|
|
|
'''show blame output for the current version in CVS'''
|
2008-03-17 02:17:51 -04:00
|
|
|
line_re = re.compile('^([0-9.]+) +\(*([a-zA-Z0-9_]+) +([-0-9A-Za-z]+)\): (.*)$')
|
2009-07-20 19:08:27 -04:00
|
|
|
def _get_path(self, w, **vargs):
|
2008-03-31 12:14:37 -04:00
|
|
|
cwd = os.getcwd() + os.path.sep
|
|
|
|
path = w.buffer.path
|
|
|
|
if path.startswith(cwd):
|
|
|
|
path = path[len(cwd):]
|
2009-07-20 19:08:27 -04:00
|
|
|
return path
|
|
|
|
|
|
|
|
def _get_cmd(self, w, **vargs):
|
|
|
|
path = self._get_path(w, **vargs)
|
|
|
|
return ("/usr/bin/cvs", 'annotate', path)
|
2008-03-31 12:14:37 -04:00
|
|
|
|
2009-07-20 19:08:27 -04:00
|
|
|
def _execute(self, w, **vargs):
|
|
|
|
if not hasattr(w.buffer, 'path'):
|
|
|
|
w.set_error("Buffer has no corresponding file")
|
|
|
|
return
|
|
|
|
|
|
|
|
cmd = self._get_cmd(w, **vargs)
|
2009-11-10 16:30:35 -05:00
|
|
|
status, out, err = util.communicate(cmd)
|
2008-03-31 12:14:37 -04:00
|
|
|
|
|
|
|
linetokens = []
|
|
|
|
max_rev = 0
|
|
|
|
max_user = 0
|
2009-08-26 10:07:58 -04:00
|
|
|
for line in out.split('\n'):
|
|
|
|
if not line:
|
|
|
|
continue
|
2008-03-31 12:14:37 -04:00
|
|
|
m = self.line_re.match(line)
|
|
|
|
if not m:
|
2009-08-26 10:07:58 -04:00
|
|
|
raise Exception(repr(line))
|
2008-03-31 12:14:37 -04:00
|
|
|
(rev, user, date, content) = m.groups()
|
|
|
|
max_rev = max(max_rev, len(rev))
|
|
|
|
max_user = max(max_user, len(user))
|
|
|
|
linetokens.append([rev, user, date, content, []])
|
|
|
|
|
|
|
|
lines = [x[3] for x in linetokens]
|
|
|
|
if w.mode.grammar:
|
|
|
|
lexer = lex.Lexer(w.mode, w.mode.grammar)
|
|
|
|
lextokens = [[] for l in lines]
|
|
|
|
for t in lexer.lex(lines):
|
|
|
|
linetokens[t.y][4].append(t)
|
|
|
|
|
|
|
|
lines = []
|
|
|
|
for linetoken in linetokens:
|
|
|
|
(rev, user, date, content, lextokens) = linetoken
|
|
|
|
prefix = '[b:d:*]%-8s [c:d:*]%-10s [b:d:*]%10s[d:d:*]' % (rev, user, date)
|
|
|
|
if lextokens:
|
|
|
|
suffixes = []
|
|
|
|
for lt in lextokens:
|
|
|
|
s = lt.string.replace('\\', '\\\\')
|
|
|
|
s = s.replace('[', '\\[').replace(']', '\\]')
|
|
|
|
suffixes.append('[%s:%s:*]%s' % (lt.color[0], lt.color[1], s))
|
|
|
|
suffix = ''.join(suffixes)
|
|
|
|
else:
|
|
|
|
suffix = content + '\n'
|
|
|
|
lines.append('%s %s' % (prefix, suffix))
|
|
|
|
data = ''.join(lines)
|
|
|
|
|
|
|
|
if status == 0:
|
|
|
|
w.application.color_data_buffer("*Blame*", data, switch_to=True)
|
|
|
|
else:
|
|
|
|
w.set_error("There was an error (%s)" % (status))
|
2009-07-20 19:08:27 -04:00
|
|
|
|
|
|
|
class CvsBlame2(CvsBlame):
|
|
|
|
'''show blame output for the current version in CVS'''
|
|
|
|
args = [arg("revision", t=type(""), p="Revision: ", h="revision number")]
|
|
|
|
line_re = re.compile('^([0-9.]+) +\(*([a-zA-Z0-9_]+) +([-0-9A-Za-z]+)\): (.*)$')
|
|
|
|
def _get_cmd(self, w, **vargs):
|
|
|
|
path = self._get_path(w, **vargs)
|
|
|
|
return ("/usr/bin/cvs", 'annotate', '-r', vargs['revision'], path)
|
2009-07-28 18:08:45 -04:00
|
|
|
|
|
|
|
class CvsRevView(Method):
|
|
|
|
'''show blame output for the current version in CVS'''
|
|
|
|
args = [arg("revision", t=type(""), p="Revision: ", h="revision number")]
|
|
|
|
def _get_path(self, w, **vargs):
|
|
|
|
cwd = os.getcwd() + os.path.sep
|
|
|
|
path = w.buffer.path
|
|
|
|
if path.startswith(cwd):
|
|
|
|
path = path[len(cwd):]
|
|
|
|
return path
|
|
|
|
|
|
|
|
def _get_cmd(self, w, **vargs):
|
|
|
|
path = self._get_path(w, **vargs)
|
|
|
|
return ("/usr/bin/cvs", 'up', '-p', '-r', vargs['revision'], path)
|
|
|
|
|
|
|
|
def _get_name(self, w, **vargs):
|
|
|
|
return '*CVS:%s-%s' % (w.buffer.name(), vargs['revision'])
|
|
|
|
|
|
|
|
def _execute(self, w, **vargs):
|
|
|
|
if not hasattr(w.buffer, 'path'):
|
|
|
|
w.set_error("Buffer has no corresponding file")
|
|
|
|
return
|
|
|
|
|
2009-08-26 10:07:58 -04:00
|
|
|
cmd = self._get_cmd(w, **vargs)
|
|
|
|
name = self._get_name(w, **vargs)
|
|
|
|
mname = w.mode.name.lower()
|
2009-11-10 16:30:35 -05:00
|
|
|
status, out, err = util.communicate(cmd)
|
2009-07-28 18:08:45 -04:00
|
|
|
|
2009-08-26 10:07:58 -04:00
|
|
|
w.application.data_buffer(name, out, switch_to=True, modename=mname)
|
2009-07-28 18:08:45 -04:00
|
|
|
|
|
|
|
class CvsDateView(CvsRevView):
|
|
|
|
'''show blame output for the current version in CVS'''
|
|
|
|
args = [arg("date", t=type(""), p="Date: ", h="date specifier")]
|
|
|
|
def _get_cmd(self, w, **vargs):
|
|
|
|
path = self._get_path(w, **vargs)
|
|
|
|
return ("/usr/bin/cvs", 'up', '-p', '-D', vargs['date'], path)
|
|
|
|
|
|
|
|
def _get_name(self, w, **vargs):
|
|
|
|
return '*CVS:%s-%s' % (w.buffer.name(), vargs['date'])
|