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()
161