blob: 74bce56ff0143dbb1e478e3b7b9a2e7fc9ec4f11 [file] [log] [blame]
Guido van Rossum5f07b841995-04-26 22:57:11 +00001#! /usr/local/bin/python
2
3import sys
4import os
5import getopt
6import string
7import md5
8import tempfile
9
10def 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
43def 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
67def 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
80def checkout(x, copts, fn):
81 data = x.get(fn)
82 f = open(fn, 'w')
83 f.write(data)
84 f.close()
85
86def 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
94def head(x, copts, fn):
95 head = x.head(fn)
96 print fn, head
97
98def list(x, copts, fn):
99 if x.isfile(fn):
100 print fn
101
102def 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
110def 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
130def 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
139def 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
156def remove(fn):
157 try:
158 os.unlink(fn)
159 except os.error:
160 pass
161
162commands = {
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
174main()