2 import errno, posixpath, weakref
3 from time import time as now
4 from stat import S_IFDIR, S_IFREG, S_IFMT
5 from cStringIO import StringIO
6 from handler import Handler
7 from pathfs import PathFs
8 from pysvn.ra_filesystem import SvnRepositoryFilesystem
14 def __init__(self, svnurl, root=''):
15 super(SvnFS, self).__init__(root)
17 self.openfiles = weakref.WeakValueDictionary()
18 self.creationtimes = {}
21 def do_open(self, rev='HEAD'):
22 self.fs = SvnRepositoryFilesystem(svnurl, rev)
24 def do_commit(self, msg):
25 rev = self.fs.commit(msg)
29 print '* checked in revision %d.' % (rev,)
32 def do_status(self, path=''):
35 if path and not path.endswith('/'):
37 for delta in self.fs._compute_deltas():
38 if delta.path.startswith(path):
39 if delta.oldrev is None:
41 elif delta.newrev is None:
45 result.append(' %s %s\n' % (c, delta.path[len(path):]))
46 return ''.join(result)
48 def getattr(self, path):
49 stat = self.fs.stat(path)
50 if stat['svn:entry:kind'] == 'dir':
57 time = pysvn.date.decode(stat['svn:entry:committed-date'])
60 time = self.creationtimes[path]
62 time = self.creationtimes[path] = now()
63 return self.mkattr(path,
64 size = stat.get('svn:entry:size', 0),
69 def setattr(self, path, mode, uid, gid, size, atime, mtime):
71 data = self.fs.read(path)
73 self.fs.write(path, data[:size])
74 elif size > len(data):
75 self.fs.write(path, data + '\x00' * (size - len(data)))
77 def listdir(self, path):
78 for name in self.fs.listdir(path):
79 kind = self.fs.check_path(posixpath.join(path, name))
85 def check_path(self, path):
86 kind = self.fs.check_path(path)
87 return kind is not None
89 def open(self, path, mode):
91 of = self.openfiles[path]
93 of = self.openfiles[path] = OpenFile(self.fs.read(path))
94 return of, FOPEN_KEEP_CACHE
96 def modified(self, path):
98 of = self.openfiles[path]
102 self.fs.write(path, of.f.getvalue())
104 def mknod_path(self, path, mode):
107 def mkdir_path(self, path, mode):
110 def unlink_path(self, path):
113 def rmdir_path(self, path):
116 def rename_path(self, oldpath, newpath):
117 kind = self.fs.check_path(oldpath)
120 self.fs.move(oldpath, newpath, kind)
123 def getxattrs(self, path):
124 return XAttrs(self, path)
128 def __init__(self, data=''):
137 return self.f.read(sz)
139 def write(self, buf):
144 def __init__(self, svnfs, path):
151 def __getitem__(self, key):
153 return self.svnfs.do_status(self.path)
156 def __setitem__(self, key, value):
157 if key == 'commit' and self.path == '':
158 self.svnfs.do_commit(value)
159 elif key == 'update' and self.path == '':
160 if self.svnfs.fs.modified():
161 raise IOError(errno.EPERM, "there are local changes")
168 raise IOError(errno.EPERM, "invalid revision number")
169 self.svnfs.do_open(rev)
173 def __delitem__(self, key):
177 if __name__ == '__main__':
179 svnurl, mountpoint = sys.argv[1:]
180 handler = Handler(mountpoint, SvnFS(svnurl))
181 handler.loop_forever()