pmacs3/method/cvs.py

224 lines
7.6 KiB
Python

import os, commands, re, sets, tempfile
from subprocess import Popen, PIPE, STDOUT
import buffer, default, dirutil, regex, util, window
from point import Point
from method import DATATYPES, Method, Argument
class CvsCommit(Method):
'''diff the current file with the version in CVS'''
args = [Argument("msg", type=type(""), prompt="Commit Message: ")]
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
cwd = os.getcwd() + os.path.sep
path = w.buffer.path
if path.startswith(cwd):
path = path[len(cwd):]
cmd = "cvs ci -m %r %r" % (vargs['msg'], path)
(status, data) = commands.getstatusoutput(cmd)
status = status >> 8
lines = data.split('\n')
if status == 0:
for line in lines:
m = self.regex.match(line)
if m:
w.set_error("Committed [%s -> %s]" % (m.group(2), m.group(1)))
return
w.set_error("Up-to-date")
else:
w.set_error("Problems with CVS commit: %d" % status)
w.application.data_buffer("*Commit*", data, switch_to=True)
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):]
cmd = "cvs status %r" % path
(status, data) = commands.getstatusoutput(cmd)
status = status >> 8
if status != 0:
w.set_error("Problems with CVS status: %d" % status)
return
lines = data.split('\n')
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)
w.set_error('%s %s %s/%s [%s|%s|%s]' % (ffile, fstatus,
wrev, rrev, stag,
sdate, soptions))
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):]
cmd = "cvs diff -u %r" % path
(status, data) = commands.getstatusoutput(cmd)
status = status >> 8
if status == 0:
w.set_error("No difference found")
else:
w.application.data_buffer("*Diff*", data, switch_to=True, modename='diff')
w.set_error("Differences were found")
class CvsDiff2(Method):
'''diff the current file with the version in CVS'''
rev_regex = re.compile('^[0-9]+\.[0-9]+$')
args = [Argument("revision", type=type(""), prompt="Old Revision: ")]
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):]
cmd = "cvs diff -r %s -u %r" % (rev, path)
(status, data) = commands.getstatusoutput(cmd)
status = status >> 8
if status == 0:
w.set_error("No difference found")
else:
w.application.data_buffer("*Diff*", data, switch_to=True, modename='diff')
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]+$')
args = [Argument("revision1", type=type(""), prompt="Old Revision: "),
Argument("revision2", type=type(""), prompt="New Revision: ")]
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):]
cmd = "cvs diff -r %s -r %s -u %r" % (rev1, rev2, path)
(status, data) = commands.getstatusoutput(cmd)
status = status >> 8
if status == 0:
w.set_error("No difference found")
else:
w.application.data_buffer("*Diff*", data, switch_to=True, modename='diff')
w.set_error("Differences were found")
class CvsBlame(Method):
'''show blame output for the current version in SVN'''
line_re = re.compile('^([0-9.]+) +\(*([a-zA-Z0-9_]+) +([-0-9A-Za-z]+)\): (.*)$')
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):]
cmd = ("/usr/bin/cvs", 'annotate', path)
pipe = Popen(cmd, stdout=PIPE)
tokens = []
max_rev = 0
max_user = 0
for line in pipe.stdout:
m = self.line_re.match(line)
if not m:
raise Exception, line
(rev, user, date, content) = m.groups()
max_rev = max(max_rev, len(rev))
max_user = max(max_user, len(user))
tokens.append((rev, user, date, content))
lines = []
fmt = "%%-%ds %%-%ds %%9s %%s\n" % (max_rev, max_user)
for (rev, user, date, content) in tokens:
lines.append(fmt % (rev, user, date, content))
data = ''.join(lines)
status = pipe.wait() >> 8
if status == 0:
w.application.data_buffer("*Blame*", data, switch_to=True, modename='blame')
else:
w.set_error("There was an error (%s)" % (status))