| #! /usr/bin/env python | |
| "Remote RCS -- command line interface" | |
| import sys | |
| import os | |
| import getopt | |
| import string | |
| import md5 | |
| import tempfile | |
| from rcsclient import openrcsclient | |
| def main(): | |
| sys.stdout = sys.stderr | |
| try: | |
| opts, rest = getopt.getopt(sys.argv[1:], 'h:p:d:qvL') | |
| if not rest: | |
| cmd = 'head' | |
| else: | |
| cmd, rest = rest[0], rest[1:] | |
| if not commands.has_key(cmd): | |
| raise getopt.error, "unknown command" | |
| coptset, func = commands[cmd] | |
| copts, files = getopt.getopt(rest, coptset) | |
| except getopt.error, msg: | |
| print msg | |
| print "usage: rrcs [options] command [options] [file] ..." | |
| print "where command can be:" | |
| print " ci|put # checkin the given files" | |
| print " co|get # checkout" | |
| print " info # print header info" | |
| print " head # print revision of head branch" | |
| print " list # list filename if valid" | |
| print " log # print full log" | |
| print " diff # diff rcs file and work file" | |
| print "if no files are given, all remote rcs files are assumed" | |
| sys.exit(2) | |
| x = openrcsclient(opts) | |
| if not files: | |
| files = x.listfiles() | |
| for fn in files: | |
| try: | |
| func(x, copts, fn) | |
| except (IOError, os.error), msg: | |
| print "%s: %s" % (fn, msg) | |
| def checkin(x, copts, fn): | |
| f = open(fn) | |
| data = f.read() | |
| f.close() | |
| new = not x.isvalid(fn) | |
| if not new and same(x, copts, fn, data): | |
| print "%s: unchanged since last checkin" % fn | |
| return | |
| print "Checking in", fn, "..." | |
| message = asklogmessage(new) | |
| messages = x.put(fn, data, message) | |
| if messages: | |
| print messages | |
| def checkout(x, copts, fn): | |
| data = x.get(fn) | |
| f = open(fn, 'w') | |
| f.write(data) | |
| f.close() | |
| def lock(x, copts, fn): | |
| x.lock(fn) | |
| def unlock(x, copts, fn): | |
| x.unlock(fn) | |
| def info(x, copts, fn): | |
| dict = x.info(fn) | |
| keys = dict.keys() | |
| keys.sort() | |
| for key in keys: | |
| print key + ':', dict[key] | |
| print '='*70 | |
| def head(x, copts, fn): | |
| head = x.head(fn) | |
| print fn, head | |
| def list(x, copts, fn): | |
| if x.isvalid(fn): | |
| print fn | |
| def log(x, copts, fn): | |
| flags = '' | |
| for o, a in copts: | |
| flags = flags + ' ' + o + a | |
| flags = flags[1:] | |
| messages = x.log(fn, flags) | |
| print messages | |
| def diff(x, copts, fn): | |
| if same(x, copts, fn): | |
| return | |
| flags = '' | |
| for o, a in copts: | |
| flags = flags + ' ' + o + a | |
| flags = flags[1:] | |
| data = x.get(fn) | |
| tf = tempfile.NamedTemporaryFile() | |
| tf.write(data) | |
| tf.flush() | |
| print 'diff %s -r%s %s' % (flags, x.head(fn), fn) | |
| sts = os.system('diff %s %s %s' % (flags, tf.name, fn)) | |
| if sts: | |
| print '='*70 | |
| def same(x, copts, fn, data = None): | |
| if data is None: | |
| f = open(fn) | |
| data = f.read() | |
| f.close() | |
| lsum = md5.new(data).digest() | |
| rsum = x.sum(fn) | |
| return lsum == rsum | |
| def asklogmessage(new): | |
| if new: | |
| print "enter description,", | |
| else: | |
| print "enter log message,", | |
| print "terminate with single '.' or end of file:" | |
| if new: | |
| print "NOTE: This is NOT the log message!" | |
| message = "" | |
| while 1: | |
| sys.stderr.write(">> ") | |
| sys.stderr.flush() | |
| line = sys.stdin.readline() | |
| if not line or line == '.\n': break | |
| message = message + line | |
| return message | |
| def remove(fn): | |
| try: | |
| os.unlink(fn) | |
| except os.error: | |
| pass | |
| commands = { | |
| 'ci': ('', checkin), | |
| 'put': ('', checkin), | |
| 'co': ('', checkout), | |
| 'get': ('', checkout), | |
| 'info': ('', info), | |
| 'head': ('', head), | |
| 'list': ('', list), | |
| 'lock': ('', lock), | |
| 'unlock': ('', unlock), | |
| 'log': ('bhLRtd:l:r:s:w:V:', log), | |
| 'diff': ('c', diff), | |
| } | |
| if __name__ == '__main__': | |
| main() |