rewritten using rcslib.py
This commit is contained in:
parent
40de53c3bd
commit
ab75eb244e
|
@ -7,33 +7,34 @@ The functionality is geared towards implementing some sort of
|
||||||
remote CVS like utility. It is modeled after the similar module
|
remote CVS like utility. It is modeled after the similar module
|
||||||
FSProxy.
|
FSProxy.
|
||||||
|
|
||||||
The module defines three classes:
|
The module defines two classes:
|
||||||
|
|
||||||
RCSProxyLocal -- used for local access
|
RCSProxyLocal -- used for local access
|
||||||
RCSProxyServer -- used on the server side of remote access
|
RCSProxyServer -- used on the server side of remote access
|
||||||
RCSProxyClient -- used on the client side of remote access
|
|
||||||
|
An additional class, RCSProxyClient, is defined in module rcsclient.
|
||||||
|
|
||||||
The remote classes are instantiated with an IP address and an optional
|
The remote classes are instantiated with an IP address and an optional
|
||||||
verbosity flag.
|
verbosity flag.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import server
|
import server
|
||||||
import client
|
|
||||||
import md5
|
import md5
|
||||||
import os
|
import os
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import string
|
import string
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import rcslib
|
||||||
|
|
||||||
|
|
||||||
okchars = string.letters + string.digits + '-_=+.'
|
class DirSupport:
|
||||||
|
|
||||||
|
|
||||||
class RCSProxyLocal:
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._dirstack = []
|
self._dirstack = []
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self._close()
|
||||||
|
|
||||||
def _close(self):
|
def _close(self):
|
||||||
while self._dirstack:
|
while self._dirstack:
|
||||||
self.back()
|
self.back()
|
||||||
|
@ -53,47 +54,6 @@ class RCSProxyLocal:
|
||||||
os.chdir(dir)
|
os.chdir(dir)
|
||||||
del self._dirstack[-1]
|
del self._dirstack[-1]
|
||||||
|
|
||||||
def _filter(self, files, pat = None):
|
|
||||||
if pat:
|
|
||||||
def keep(name, pat = pat):
|
|
||||||
return fnmatch.fnmatch(name, pat)
|
|
||||||
files = filter(keep, files)
|
|
||||||
files.sort()
|
|
||||||
return files
|
|
||||||
|
|
||||||
def isfile(self, name):
|
|
||||||
namev = name + ',v'
|
|
||||||
return os.path.isfile(namev) or \
|
|
||||||
os.path.isfile(os.path.join('RCS', namev))
|
|
||||||
|
|
||||||
def _unmangle(self, name):
|
|
||||||
if type(name) == type(''):
|
|
||||||
rev = ''
|
|
||||||
else:
|
|
||||||
name, rev = name
|
|
||||||
return name, rev
|
|
||||||
|
|
||||||
def checkfile(self, name):
|
|
||||||
name, rev = self._unmangle(name)
|
|
||||||
if not self.isfile(name):
|
|
||||||
raise os.error, 'not an rcs file %s' % `name`
|
|
||||||
for c in rev:
|
|
||||||
if c not in okchars:
|
|
||||||
raise ValueError, "bad char in rev"
|
|
||||||
return name, rev
|
|
||||||
|
|
||||||
def listfiles(self, pat = None):
|
|
||||||
def isrcs(name): return name[-2:] == ',v'
|
|
||||||
def striprcs(name): return name[:-2]
|
|
||||||
files = os.listdir(os.curdir)
|
|
||||||
files = filter(isrcs, files)
|
|
||||||
if os.path.isdir('RCS'):
|
|
||||||
files2 = os.listdir('RCS')
|
|
||||||
files2 = filter(isrcs, files2)
|
|
||||||
files = files + files2
|
|
||||||
files = map(striprcs, files)
|
|
||||||
return self._filter(files, pat)
|
|
||||||
|
|
||||||
def listsubdirs(self, pat = None):
|
def listsubdirs(self, pat = None):
|
||||||
files = os.listdir(os.curdir)
|
files = os.listdir(os.curdir)
|
||||||
files = filter(os.path.isdir, files)
|
files = filter(os.path.isdir, files)
|
||||||
|
@ -102,26 +62,31 @@ class RCSProxyLocal:
|
||||||
def isdir(self, name):
|
def isdir(self, name):
|
||||||
return os.path.isdir(name)
|
return os.path.isdir(name)
|
||||||
|
|
||||||
def _open(self, name, cmd = 'co -p'):
|
def mkdir(self, name):
|
||||||
name, rev = self.checkfile(name)
|
os.mkdir(name, 0777)
|
||||||
namev = name + ',v'
|
|
||||||
if rev:
|
|
||||||
cmd = cmd + ' -r' + rev
|
|
||||||
return os.popen('%s %s' % (cmd, `namev`))
|
|
||||||
|
|
||||||
def _closepipe(self, f):
|
def rmdir(self, name):
|
||||||
sts = f.close()
|
os.rmdir(name)
|
||||||
if sts:
|
|
||||||
raise IOError, "Exit status %d" % sts
|
|
||||||
|
|
||||||
def _remove(self, fn):
|
|
||||||
try:
|
|
||||||
os.unlink(fn)
|
|
||||||
except os.error:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def sum(self, name):
|
class RCSProxyLocal(rcslib.RCS, DirSupport):
|
||||||
f = self._open(name)
|
|
||||||
|
def __init__(self):
|
||||||
|
rcslib.RCS.__init__(self)
|
||||||
|
DirSupport.__init__(self)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
DirSupport.__del__(self)
|
||||||
|
rcslib.RCS.__del__(self)
|
||||||
|
|
||||||
|
def sumlist(self, list = None):
|
||||||
|
return self._list(self.sum, list)
|
||||||
|
|
||||||
|
def sumdict(self, list = None):
|
||||||
|
return self._dict(self.sum, list)
|
||||||
|
|
||||||
|
def sum(self, name_rev):
|
||||||
|
f = self._open(name_rev)
|
||||||
BUFFERSIZE = 1024*8
|
BUFFERSIZE = 1024*8
|
||||||
sum = md5.new()
|
sum = md5.new()
|
||||||
while 1:
|
while 1:
|
||||||
|
@ -132,7 +97,27 @@ class RCSProxyLocal:
|
||||||
self._closepipe(f)
|
self._closepipe(f)
|
||||||
return sum.digest()
|
return sum.digest()
|
||||||
|
|
||||||
def _list(self, function, list):
|
def get(self, name_rev):
|
||||||
|
f = self._open(name_rev)
|
||||||
|
data = f.read()
|
||||||
|
self._closepipe(f)
|
||||||
|
return data
|
||||||
|
|
||||||
|
def put(self, name_rev, data, message=None):
|
||||||
|
name, rev = self._unmangle(name_rev)
|
||||||
|
f = open(name, 'w')
|
||||||
|
f.write(data)
|
||||||
|
f.close()
|
||||||
|
self.checkin(name_rev, message)
|
||||||
|
|
||||||
|
def _list(self, function, list = None):
|
||||||
|
"""INTERNAL: apply FUNCTION to all files in LIST.
|
||||||
|
|
||||||
|
Return a list of the results.
|
||||||
|
|
||||||
|
The list defaults to all files in the directory if None.
|
||||||
|
|
||||||
|
"""
|
||||||
if list is None:
|
if list is None:
|
||||||
list = self.listfiles()
|
list = self.listfiles()
|
||||||
res = []
|
res = []
|
||||||
|
@ -143,10 +128,14 @@ class RCSProxyLocal:
|
||||||
res.append((name, None))
|
res.append((name, None))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def sumlist(self, list = None):
|
def _dict(self, function, list = None):
|
||||||
return self.list(self.sum, list)
|
"""INTERNAL: apply FUNCTION to all files in LIST.
|
||||||
|
|
||||||
def _dict(self, function, list):
|
Return a dictionary mapping files to results.
|
||||||
|
|
||||||
|
The list defaults to all files in the directory if None.
|
||||||
|
|
||||||
|
"""
|
||||||
if list is None:
|
if list is None:
|
||||||
list = self.listfiles()
|
list = self.listfiles()
|
||||||
dict = {}
|
dict = {}
|
||||||
|
@ -157,78 +146,6 @@ class RCSProxyLocal:
|
||||||
pass
|
pass
|
||||||
return dict
|
return dict
|
||||||
|
|
||||||
def sumdict(self, list = None):
|
|
||||||
return self.dict(self.sum, list)
|
|
||||||
|
|
||||||
def get(self, name):
|
|
||||||
f = self._open(name)
|
|
||||||
data = f.read()
|
|
||||||
self._closepipe(f)
|
|
||||||
return data
|
|
||||||
|
|
||||||
def info(self, name):
|
|
||||||
f = self._open(name, 'rlog -h')
|
|
||||||
dict = {}
|
|
||||||
while 1:
|
|
||||||
line = f.readline()
|
|
||||||
if not line: break
|
|
||||||
if line[0] == '\t':
|
|
||||||
continue # XXX lock details, later
|
|
||||||
i = string.find(line, ':')
|
|
||||||
if i > 0:
|
|
||||||
key, value = line[:i], string.strip(line[i+1:])
|
|
||||||
dict[key] = value
|
|
||||||
self._closepipe(f)
|
|
||||||
return dict
|
|
||||||
|
|
||||||
def head(self, name):
|
|
||||||
dict = self.info(name)
|
|
||||||
return dict['head']
|
|
||||||
|
|
||||||
def log(self, name, flags = ''):
|
|
||||||
f = self._open(name, 'rlog %s 2>&1' % flags)
|
|
||||||
log = f.read()
|
|
||||||
self._closepipe(f)
|
|
||||||
return log
|
|
||||||
|
|
||||||
def put(self, fullname, data, message = ""):
|
|
||||||
if message and message[-1] != '\n':
|
|
||||||
message = message + '\n'
|
|
||||||
name, rev = self._unmangle(fullname)
|
|
||||||
new = not self.isfile(name)
|
|
||||||
if new:
|
|
||||||
for c in name:
|
|
||||||
if c not in okchars:
|
|
||||||
raise ValueError, "bad char in name"
|
|
||||||
else:
|
|
||||||
self._remove(name)
|
|
||||||
f = open(name, 'w')
|
|
||||||
f.write(data)
|
|
||||||
f.close()
|
|
||||||
tf = tempfile.mktemp()
|
|
||||||
try:
|
|
||||||
if not new:
|
|
||||||
cmd = "rcs -l%s %s >>%s 2>&1" % (rev, name, tf)
|
|
||||||
sts = os.system(cmd)
|
|
||||||
if sts:
|
|
||||||
raise IOError, "rcs -l exit status %d" % sts
|
|
||||||
cmd = "ci -r%s %s >>%s 2>&1" % (rev, name, tf)
|
|
||||||
p = os.popen(cmd, 'w')
|
|
||||||
p.write(message)
|
|
||||||
sts = p.close()
|
|
||||||
if sts:
|
|
||||||
raise IOError, "ci exit status %d" % sts
|
|
||||||
messages = open(tf).read()
|
|
||||||
return messages or None
|
|
||||||
finally:
|
|
||||||
self._remove(tf)
|
|
||||||
|
|
||||||
def mkdir(self, name):
|
|
||||||
os.mkdir(name, 0777)
|
|
||||||
|
|
||||||
def rmdir(self, name):
|
|
||||||
os.rmdir(name)
|
|
||||||
|
|
||||||
|
|
||||||
class RCSProxyServer(RCSProxyLocal, server.SecureServer):
|
class RCSProxyServer(RCSProxyLocal, server.SecureServer):
|
||||||
|
|
||||||
|
@ -246,12 +163,6 @@ class RCSProxyServer(RCSProxyLocal, server.SecureServer):
|
||||||
while self._dirstack: self.back()
|
while self._dirstack: self.back()
|
||||||
|
|
||||||
|
|
||||||
class RCSProxyClient(client.SecureClient):
|
|
||||||
|
|
||||||
def __init__(self, address, verbose = client.VERBOSE):
|
|
||||||
client.SecureClient.__init__(self, address, verbose)
|
|
||||||
|
|
||||||
|
|
||||||
def test_server():
|
def test_server():
|
||||||
import string
|
import string
|
||||||
import sys
|
import sys
|
||||||
|
|
Loading…
Reference in New Issue