#! /usr/bin/env python """ Usage: dumpstructure.py [-rREV] filename.repo [hostname fspath] Create or update the given structural repository dump file up to the given revision, or HEAD if unspecified. When creating a dump, the hostname holding the repository and the filesystem path to the repository must be given. Example: dumpstructure.py codespeak.repo codespeak.net /svn """ import sys, os import repos, cPickle REVSTEPS = 10000 def loadrepo(filename): f = os.popen("gunzip -c '%s'" % (filename.replace("'", "'\\''"),), 'rb') repo = cPickle.load(f) f.close() return repo def saverepo(repo, filename): f = os.popen("gzip > '%s'" % (filename.replace("'", "'\\''"),), 'wb') cPickle.dump(repo, f, 1) f.close() def update(repo, filename, rev='HEAD'): if rev == 'HEAD': g = repos.execute(repo.hostname, "svnlook youngest %s" % repo.fspath) rev = g.read().strip() g.close() rev = int(rev) if rev <= repo.getrev(): print "%s is already at revision %d." % (filename, repo.getrev()) return print "updating %s to revision %d..." % (filename, rev) sleep = False while rev > repo.getrev(): if sleep: print "sleeping a bit to avoid excessive traffic..." import time; time.sleep(10) else: sleep = True nextrev = min(rev, repo.getrev() + REVSTEPS) repos.dump_and_parse(repo, lastrev=nextrev) print 'writing %s...' % filename saverepo(repo, filename) print 'wrote %.2f MB' % (os.stat(filename).st_size / 1024.0 / 1024.0,) print "done." # ____________________________________________________________ def main(args): def error(msg): print >> sys.stderr, msg sys.exit(1) rev = 'HEAD' for i in range(len(args)): if args[i].startswith('-r'): rev = args[i][2:] del args[i] break if len(args) not in (1, 3): print __doc__ sys.exit(2) filename = args[0] if os.path.exists(filename): repo = loadrepo(filename) if len(args) == 3: if args[1] != repo.hostname: error("hostname %r differs from %r stored in the dump file" % (args[1], repo.hostname)) if args[2] != repo.fspath: error("fspath %r differs from %r stored in the dump file" % (args[2], repo.fspath)) else: if len(args) != 3: error("dump file %r not found, please provide hostname/fspath" % filename) repo = repos.Repository(args[1], args[2]) update(repo, filename, rev) if __name__ == '__main__': main(sys.argv[1:])