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,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