Guido van Rossum | f06ee5f | 1996-11-27 19:52:01 +0000 | [diff] [blame] | 1 | #! /usr/bin/env python |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 2 | |
Guido van Rossum | 4d4ee8b | 1995-04-27 18:07:20 +0000 | [diff] [blame] | 3 | "Remote RCS -- command line interface" |
| 4 | |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 5 | import sys |
| 6 | import os |
| 7 | import getopt |
| 8 | import string |
| 9 | import md5 |
| 10 | import tempfile |
Guido van Rossum | 4d4ee8b | 1995-04-27 18:07:20 +0000 | [diff] [blame] | 11 | from rcsclient import openrcsclient |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 12 | |
| 13 | def main(): |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 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:] |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame] | 21 | if cmd not in commands: |
| 22 | raise getopt.error("unknown command") |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 23 | coptset, func = commands[cmd] |
| 24 | copts, files = getopt.getopt(rest, coptset) |
Guido van Rossum | b940e11 | 2007-01-10 16:19:56 +0000 | [diff] [blame] | 25 | except getopt.error as msg: |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame] | 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") |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 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) |
Guido van Rossum | b940e11 | 2007-01-10 16:19:56 +0000 | [diff] [blame] | 44 | except (IOError, os.error) as msg: |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame] | 45 | print("%s: %s" % (fn, msg)) |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 46 | |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 47 | def checkin(x, copts, fn): |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 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): |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame] | 53 | print("%s: unchanged since last checkin" % fn) |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 54 | return |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame] | 55 | print("Checking in", fn, "...") |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 56 | message = asklogmessage(new) |
| 57 | messages = x.put(fn, data, message) |
| 58 | if messages: |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame] | 59 | print(messages) |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 60 | |
| 61 | def checkout(x, copts, fn): |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 62 | data = x.get(fn) |
| 63 | f = open(fn, 'w') |
| 64 | f.write(data) |
| 65 | f.close() |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 66 | |
Guido van Rossum | ff99a72 | 1995-07-18 18:40:41 +0000 | [diff] [blame] | 67 | def lock(x, copts, fn): |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 68 | x.lock(fn) |
Guido van Rossum | ff99a72 | 1995-07-18 18:40:41 +0000 | [diff] [blame] | 69 | |
| 70 | def unlock(x, copts, fn): |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 71 | x.unlock(fn) |
Guido van Rossum | ff99a72 | 1995-07-18 18:40:41 +0000 | [diff] [blame] | 72 | |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 73 | def info(x, copts, fn): |
Skip Montanaro | 1e8ce58 | 2007-08-06 21:07:53 +0000 | [diff] [blame] | 74 | info_dict = x.info(fn) |
| 75 | for key in sorted(info_dict.keys()): |
| 76 | print(key + ':', info_dict[key]) |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame] | 77 | print('='*70) |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 78 | |
| 79 | def head(x, copts, fn): |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 80 | head = x.head(fn) |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame] | 81 | print(fn, head) |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 82 | |
| 83 | def list(x, copts, fn): |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 84 | if x.isvalid(fn): |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame] | 85 | print(fn) |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 86 | |
| 87 | def log(x, copts, fn): |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 88 | flags = '' |
| 89 | for o, a in copts: |
| 90 | flags = flags + ' ' + o + a |
| 91 | flags = flags[1:] |
| 92 | messages = x.log(fn, flags) |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame] | 93 | print(messages) |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 94 | |
| 95 | def diff(x, copts, fn): |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 96 | if same(x, copts, fn): |
| 97 | return |
| 98 | flags = '' |
| 99 | for o, a in copts: |
| 100 | flags = flags + ' ' + o + a |
| 101 | flags = flags[1:] |
| 102 | data = x.get(fn) |
| 103 | tf = tempfile.NamedTemporaryFile() |
| 104 | tf.write(data) |
| 105 | tf.flush() |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame] | 106 | print('diff %s -r%s %s' % (flags, x.head(fn), fn)) |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 107 | sts = os.system('diff %s %s %s' % (flags, tf.name, fn)) |
| 108 | if sts: |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame] | 109 | print('='*70) |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 110 | |
| 111 | def same(x, copts, fn, data = None): |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 112 | if data is None: |
| 113 | f = open(fn) |
| 114 | data = f.read() |
| 115 | f.close() |
| 116 | lsum = md5.new(data).digest() |
| 117 | rsum = x.sum(fn) |
| 118 | return lsum == rsum |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 119 | |
| 120 | def asklogmessage(new): |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 121 | if new: |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame] | 122 | print("enter description,", end=' ') |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 123 | else: |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame] | 124 | print("enter log message,", end=' ') |
| 125 | print("terminate with single '.' or end of file:") |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 126 | if new: |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame] | 127 | print("NOTE: This is NOT the log message!") |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 128 | message = "" |
| 129 | while 1: |
| 130 | sys.stderr.write(">> ") |
| 131 | sys.stderr.flush() |
| 132 | line = sys.stdin.readline() |
| 133 | if not line or line == '.\n': break |
| 134 | message = message + line |
| 135 | return message |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 136 | |
| 137 | def remove(fn): |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 138 | try: |
| 139 | os.unlink(fn) |
| 140 | except os.error: |
| 141 | pass |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 142 | |
| 143 | commands = { |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 144 | 'ci': ('', checkin), |
| 145 | 'put': ('', checkin), |
| 146 | 'co': ('', checkout), |
| 147 | 'get': ('', checkout), |
| 148 | 'info': ('', info), |
| 149 | 'head': ('', head), |
| 150 | 'list': ('', list), |
| 151 | 'lock': ('', lock), |
| 152 | 'unlock': ('', unlock), |
| 153 | 'log': ('bhLRtd:l:r:s:w:V:', log), |
| 154 | 'diff': ('c', diff), |
| 155 | } |
Guido van Rossum | 5f07b84 | 1995-04-26 22:57:11 +0000 | [diff] [blame] | 156 | |
Guido van Rossum | 547e8d8 | 1995-04-27 21:28:20 +0000 | [diff] [blame] | 157 | if __name__ == '__main__': |
Tim Peters | e6ddc8b | 2004-07-18 05:56:09 +0000 | [diff] [blame] | 158 | main() |