rewritten using rcslib.py

This commit is contained in:
Guido van Rossum 1995-06-23 22:07:17 +00:00
parent 40de53c3bd
commit ab75eb244e
1 changed files with 149 additions and 238 deletions

View File

@ -7,279 +7,190 @@ The functionality is geared towards implementing some sort of
remote CVS like utility. It is modeled after the similar module
FSProxy.
The module defines three classes:
The module defines two classes:
RCSProxyLocal -- used for local 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
verbosity flag.
"""
import server
import client
import md5
import os
import fnmatch
import string
import tempfile
import rcslib
okchars = string.letters + string.digits + '-_=+.'
class DirSupport:
def __init__(self):
self._dirstack = []
def __del__(self):
self._close()
def _close(self):
while self._dirstack:
self.back()
def pwd(self):
return os.getcwd()
def cd(self, name):
save = os.getcwd()
os.chdir(name)
self._dirstack.append(save)
def back(self):
if not self._dirstack:
raise os.error, "empty directory stack"
dir = self._dirstack[-1]
os.chdir(dir)
del self._dirstack[-1]
def listsubdirs(self, pat = None):
files = os.listdir(os.curdir)
files = filter(os.path.isdir, files)
return self._filter(files, pat)
def isdir(self, name):
return os.path.isdir(name)
def mkdir(self, name):
os.mkdir(name, 0777)
def rmdir(self, name):
os.rmdir(name)
class RCSProxyLocal:
class RCSProxyLocal(rcslib.RCS, DirSupport):
def __init__(self):
self._dirstack = []
def __init__(self):
rcslib.RCS.__init__(self)
DirSupport.__init__(self)
def _close(self):
while self._dirstack:
self.back()
def __del__(self):
DirSupport.__del__(self)
rcslib.RCS.__del__(self)
def pwd(self):
return os.getcwd()
def sumlist(self, list = None):
return self._list(self.sum, list)
def cd(self, name):
save = os.getcwd()
os.chdir(name)
self._dirstack.append(save)
def sumdict(self, list = None):
return self._dict(self.sum, list)
def back(self):
if not self._dirstack:
raise os.error, "empty directory stack"
dir = self._dirstack[-1]
os.chdir(dir)
del self._dirstack[-1]
def sum(self, name_rev):
f = self._open(name_rev)
BUFFERSIZE = 1024*8
sum = md5.new()
while 1:
buffer = f.read(BUFFERSIZE)
if not buffer:
break
sum.update(buffer)
self._closepipe(f)
return sum.digest()
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 get(self, name_rev):
f = self._open(name_rev)
data = f.read()
self._closepipe(f)
return data
def isfile(self, name):
namev = name + ',v'
return os.path.isfile(namev) or \
os.path.isfile(os.path.join('RCS', namev))
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 _unmangle(self, name):
if type(name) == type(''):
rev = ''
else:
name, rev = name
return name, rev
def _list(self, function, list = None):
"""INTERNAL: apply FUNCTION to all files in LIST.
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
Return a list of the results.
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)
The list defaults to all files in the directory if None.
def listsubdirs(self, pat = None):
files = os.listdir(os.curdir)
files = filter(os.path.isdir, files)
return self._filter(files, pat)
"""
if list is None:
list = self.listfiles()
res = []
for name in list:
try:
res.append((name, function(name)))
except (os.error, IOError):
res.append((name, None))
return res
def isdir(self, name):
return os.path.isdir(name)
def _dict(self, function, list = None):
"""INTERNAL: apply FUNCTION to all files in LIST.
def _open(self, name, cmd = 'co -p'):
name, rev = self.checkfile(name)
namev = name + ',v'
if rev:
cmd = cmd + ' -r' + rev
return os.popen('%s %s' % (cmd, `namev`))
Return a dictionary mapping files to results.
def _closepipe(self, f):
sts = f.close()
if sts:
raise IOError, "Exit status %d" % sts
The list defaults to all files in the directory if None.
def _remove(self, fn):
try:
os.unlink(fn)
except os.error:
pass
def sum(self, name):
f = self._open(name)
BUFFERSIZE = 1024*8
sum = md5.new()
while 1:
buffer = f.read(BUFFERSIZE)
if not buffer:
break
sum.update(buffer)
self._closepipe(f)
return sum.digest()
def _list(self, function, list):
if list is None:
list = self.listfiles()
res = []
for name in list:
try:
res.append((name, function(name)))
except (os.error, IOError):
res.append((name, None))
return res
def sumlist(self, list = None):
return self.list(self.sum, list)
def _dict(self, function, list):
if list is None:
list = self.listfiles()
dict = {}
for name in list:
try:
dict[name] = function(name)
except (os.error, IOError):
pass
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)
"""
if list is None:
list = self.listfiles()
dict = {}
for name in list:
try:
dict[name] = function(name)
except (os.error, IOError):
pass
return dict
class RCSProxyServer(RCSProxyLocal, server.SecureServer):
def __init__(self, address, verbose = server.VERBOSE):
RCSProxyLocal.__init__(self)
server.SecureServer.__init__(self, address, verbose)
def __init__(self, address, verbose = server.VERBOSE):
RCSProxyLocal.__init__(self)
server.SecureServer.__init__(self, address, verbose)
def _close(self):
server.SecureServer._close(self)
RCSProxyLocal._close(self)
def _close(self):
server.SecureServer._close(self)
RCSProxyLocal._close(self)
def _serve(self):
server.SecureServer._serve(self)
# Retreat into start directory
while self._dirstack: self.back()
class RCSProxyClient(client.SecureClient):
def __init__(self, address, verbose = client.VERBOSE):
client.SecureClient.__init__(self, address, verbose)
def _serve(self):
server.SecureServer._serve(self)
# Retreat into start directory
while self._dirstack: self.back()
def test_server():
import string
import sys
if sys.argv[1:]:
port = string.atoi(sys.argv[1])
else:
port = 4127
proxy = RCSProxyServer(('', port))
proxy._serverloop()
import string
import sys
if sys.argv[1:]:
port = string.atoi(sys.argv[1])
else:
port = 4127
proxy = RCSProxyServer(('', port))
proxy._serverloop()
def test():
import sys
if not sys.argv[1:] or sys.argv[1] and sys.argv[1][0] in '0123456789':
test_server()
sys.exit(0)
proxy = RCSProxyLocal()
what = sys.argv[1]
if hasattr(proxy, what):
attr = getattr(proxy, what)
if callable(attr):
print apply(attr, tuple(sys.argv[2:]))
else:
print `attr`
import sys
if not sys.argv[1:] or sys.argv[1] and sys.argv[1][0] in '0123456789':
test_server()
sys.exit(0)
proxy = RCSProxyLocal()
what = sys.argv[1]
if hasattr(proxy, what):
attr = getattr(proxy, what)
if callable(attr):
print apply(attr, tuple(sys.argv[2:]))
else:
print "%s: no such attribute" % what
sys.exit(2)
print `attr`
else:
print "%s: no such attribute" % what
sys.exit(2)
if __name__ == '__main__':
test()
test()