Kaydet (Commit) ab75eb24 authored tarafından Guido van Rossum's avatar Guido van Rossum

rewritten using rcslib.py

üst 40de53c3
...@@ -7,279 +7,190 @@ The functionality is geared towards implementing some sort of ...@@ -7,279 +7,190 @@ 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
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(rcslib.RCS, DirSupport):
okchars = string.letters + string.digits + '-_=+.' def __init__(self):
rcslib.RCS.__init__(self)
DirSupport.__init__(self)
class RCSProxyLocal:
def __del__(self):
def __init__(self): DirSupport.__del__(self)
self._dirstack = [] rcslib.RCS.__del__(self)
def _close(self): def sumlist(self, list = None):
while self._dirstack: return self._list(self.sum, list)
self.back()
def sumdict(self, list = None):
def pwd(self): return self._dict(self.sum, list)
return os.getcwd()
def sum(self, name_rev):
def cd(self, name): f = self._open(name_rev)
save = os.getcwd() BUFFERSIZE = 1024*8
os.chdir(name) sum = md5.new()
self._dirstack.append(save) while 1:
buffer = f.read(BUFFERSIZE)
def back(self): if not buffer:
if not self._dirstack: break
raise os.error, "empty directory stack" sum.update(buffer)
dir = self._dirstack[-1] self._closepipe(f)
os.chdir(dir) return sum.digest()
del self._dirstack[-1]
def get(self, name_rev):
def _filter(self, files, pat = None): f = self._open(name_rev)
if pat: data = f.read()
def keep(name, pat = pat): self._closepipe(f)
return fnmatch.fnmatch(name, pat) return data
files = filter(keep, files)
files.sort() def put(self, name_rev, data, message=None):
return files name, rev = self._unmangle(name_rev)
f = open(name, 'w')
def isfile(self, name): f.write(data)
namev = name + ',v' f.close()
return os.path.isfile(namev) or \ self.checkin(name_rev, message)
os.path.isfile(os.path.join('RCS', namev))
def _list(self, function, list = None):
def _unmangle(self, name): """INTERNAL: apply FUNCTION to all files in LIST.
if type(name) == type(''):
rev = '' Return a list of the results.
else:
name, rev = name The list defaults to all files in the directory if None.
return name, rev
"""
def checkfile(self, name): if list is None:
name, rev = self._unmangle(name) list = self.listfiles()
if not self.isfile(name): res = []
raise os.error, 'not an rcs file %s' % `name` for name in list:
for c in rev: try:
if c not in okchars: res.append((name, function(name)))
raise ValueError, "bad char in rev" except (os.error, IOError):
return name, rev res.append((name, None))
return res
def listfiles(self, pat = None):
def isrcs(name): return name[-2:] == ',v' def _dict(self, function, list = None):
def striprcs(name): return name[:-2] """INTERNAL: apply FUNCTION to all files in LIST.
files = os.listdir(os.curdir)
files = filter(isrcs, files) Return a dictionary mapping files to results.
if os.path.isdir('RCS'):
files2 = os.listdir('RCS') The list defaults to all files in the directory if None.
files2 = filter(isrcs, files2)
files = files + files2 """
files = map(striprcs, files) if list is None:
return self._filter(files, pat) list = self.listfiles()
dict = {}
def listsubdirs(self, pat = None): for name in list:
files = os.listdir(os.curdir) try:
files = filter(os.path.isdir, files) dict[name] = function(name)
return self._filter(files, pat) except (os.error, IOError):
pass
def isdir(self, name): return dict
return os.path.isdir(name)
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`))
def _closepipe(self, f):
sts = f.close()
if sts:
raise IOError, "Exit status %d" % sts
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)
class RCSProxyServer(RCSProxyLocal, server.SecureServer): class RCSProxyServer(RCSProxyLocal, server.SecureServer):
def __init__(self, address, verbose = server.VERBOSE): def __init__(self, address, verbose = server.VERBOSE):
RCSProxyLocal.__init__(self) RCSProxyLocal.__init__(self)
server.SecureServer.__init__(self, address, verbose) server.SecureServer.__init__(self, address, verbose)
def _close(self): def _close(self):
server.SecureServer._close(self) server.SecureServer._close(self)
RCSProxyLocal._close(self) RCSProxyLocal._close(self)
def _serve(self): def _serve(self):
server.SecureServer._serve(self) server.SecureServer._serve(self)
# Retreat into start directory # Retreat into start directory
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
if sys.argv[1:]: if sys.argv[1:]:
port = string.atoi(sys.argv[1]) port = string.atoi(sys.argv[1])
else: else:
port = 4127 port = 4127
proxy = RCSProxyServer(('', port)) proxy = RCSProxyServer(('', port))
proxy._serverloop() proxy._serverloop()
def test(): def test():
import sys import sys
if not sys.argv[1:] or sys.argv[1] and sys.argv[1][0] in '0123456789': if not sys.argv[1:] or sys.argv[1] and sys.argv[1][0] in '0123456789':
test_server() test_server()
sys.exit(0) sys.exit(0)
proxy = RCSProxyLocal() proxy = RCSProxyLocal()
what = sys.argv[1] what = sys.argv[1]
if hasattr(proxy, what): if hasattr(proxy, what):
attr = getattr(proxy, what) attr = getattr(proxy, what)
if callable(attr): if callable(attr):
print apply(attr, tuple(sys.argv[2:])) print apply(attr, tuple(sys.argv[2:]))
else:
print `attr`
else: else:
print "%s: no such attribute" % what print `attr`
sys.exit(2) else:
print "%s: no such attribute" % what
sys.exit(2)
if __name__ == '__main__': if __name__ == '__main__':
test() test()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment