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