1#! /usr/bin/env python 2 3"Remote RCS -- command line interface" 4 5import sys 6import os 7import getopt 8import string 9import md5 10import tempfile 11from rcsclient import openrcsclient 12 13def main(): 14 sys.stdout = sys.stderr 15 try: 16 opts, rest = getopt.getopt(sys.argv[1:], 'h:p:d:qvL') 17 if not rest: 18 cmd = 'head' 19 else: 20 cmd, rest = rest[0], rest[1:] 21 if not commands.has_key(cmd): 22 raise getopt.error, "unknown command" 23 coptset, func = commands[cmd] 24 copts, files = getopt.getopt(rest, coptset) 25 except getopt.error, msg: 26 print msg 27 print "usage: rrcs [options] command [options] [file] ..." 28 print "where command can be:" 29 print " ci|put # checkin the given files" 30 print " co|get # checkout" 31 print " info # print header info" 32 print " head # print revision of head branch" 33 print " list # list filename if valid" 34 print " log # print full log" 35 print " diff # diff rcs file and work file" 36 print "if no files are given, all remote rcs files are assumed" 37 sys.exit(2) 38 x = openrcsclient(opts) 39 if not files: 40 files = x.listfiles() 41 for fn in files: 42 try: 43 func(x, copts, fn) 44 except (IOError, os.error), msg: 45 print "%s: %s" % (fn, msg) 46 47def checkin(x, copts, fn): 48 f = open(fn) 49 data = f.read() 50 f.close() 51 new = not x.isvalid(fn) 52 if not new and same(x, copts, fn, data): 53 print "%s: unchanged since last checkin" % fn 54 return 55 print "Checking in", fn, "..." 56 message = asklogmessage(new) 57 messages = x.put(fn, data, message) 58 if messages: 59 print messages 60 61def checkout(x, copts, fn): 62 data = x.get(fn) 63 f = open(fn, 'w') 64 f.write(data) 65 f.close() 66 67def lock(x, copts, fn): 68 x.lock(fn) 69 70def unlock(x, copts, fn): 71 x.unlock(fn) 72 73def info(x, copts, fn): 74 dict = x.info(fn) 75 keys = dict.keys() 76 keys.sort() 77 for key in keys: 78 print key + ':', dict[key] 79 print '='*70 80 81def head(x, copts, fn): 82 head = x.head(fn) 83 print fn, head 84 85def list(x, copts, fn): 86 if x.isvalid(fn): 87 print fn 88 89def log(x, copts, fn): 90 flags = '' 91 for o, a in copts: 92 flags = flags + ' ' + o + a 93 flags = flags[1:] 94 messages = x.log(fn, flags) 95 print messages 96 97def diff(x, copts, fn): 98 if same(x, copts, fn): 99 return 100 flags = '' 101 for o, a in copts: 102 flags = flags + ' ' + o + a 103 flags = flags[1:] 104 data = x.get(fn) 105 tf = tempfile.NamedTemporaryFile() 106 tf.write(data) 107 tf.flush() 108 print 'diff %s -r%s %s' % (flags, x.head(fn), fn) 109 sts = os.system('diff %s %s %s' % (flags, tf.name, fn)) 110 if sts: 111 print '='*70 112 113def same(x, copts, fn, data = None): 114 if data is None: 115 f = open(fn) 116 data = f.read() 117 f.close() 118 lsum = md5.new(data).digest() 119 rsum = x.sum(fn) 120 return lsum == rsum 121 122def asklogmessage(new): 123 if new: 124 print "enter description,", 125 else: 126 print "enter log message,", 127 print "terminate with single '.' or end of file:" 128 if new: 129 print "NOTE: This is NOT the log message!" 130 message = "" 131 while 1: 132 sys.stderr.write(">> ") 133 sys.stderr.flush() 134 line = sys.stdin.readline() 135 if not line or line == '.\n': break 136 message = message + line 137 return message 138 139def remove(fn): 140 try: 141 os.unlink(fn) 142 except os.error: 143 pass 144 145commands = { 146 'ci': ('', checkin), 147 'put': ('', checkin), 148 'co': ('', checkout), 149 'get': ('', checkout), 150 'info': ('', info), 151 'head': ('', head), 152 'list': ('', list), 153 'lock': ('', lock), 154 'unlock': ('', unlock), 155 'log': ('bhLRtd:l:r:s:w:V:', log), 156 'diff': ('c', diff), 157 } 158 159if __name__ == '__main__': 160 main() 161