|
1 #! /usr/bin/env python |
|
2 |
|
3 "Remote RCS -- command line interface" |
|
4 |
|
5 import sys |
|
6 import os |
|
7 import getopt |
|
8 import string |
|
9 import md5 |
|
10 import tempfile |
|
11 from rcsclient import openrcsclient |
|
12 |
|
13 def 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 |
|
47 def 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 |
|
61 def checkout(x, copts, fn): |
|
62 data = x.get(fn) |
|
63 f = open(fn, 'w') |
|
64 f.write(data) |
|
65 f.close() |
|
66 |
|
67 def lock(x, copts, fn): |
|
68 x.lock(fn) |
|
69 |
|
70 def unlock(x, copts, fn): |
|
71 x.unlock(fn) |
|
72 |
|
73 def 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 |
|
81 def head(x, copts, fn): |
|
82 head = x.head(fn) |
|
83 print fn, head |
|
84 |
|
85 def list(x, copts, fn): |
|
86 if x.isvalid(fn): |
|
87 print fn |
|
88 |
|
89 def 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 |
|
97 def 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 |
|
113 def 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 |
|
122 def 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 |
|
139 def remove(fn): |
|
140 try: |
|
141 os.unlink(fn) |
|
142 except os.error: |
|
143 pass |
|
144 |
|
145 commands = { |
|
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 |
|
159 if __name__ == '__main__': |
|
160 main() |