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