|
1 #! /usr/bin/env python |
|
2 |
|
3 # xxci |
|
4 # |
|
5 # check in files for which rcsdiff returns nonzero exit status |
|
6 |
|
7 import sys |
|
8 import os |
|
9 from stat import * |
|
10 import commands |
|
11 import fnmatch |
|
12 |
|
13 EXECMAGIC = '\001\140\000\010' |
|
14 |
|
15 MAXSIZE = 200*1024 # Files this big must be binaries and are skipped. |
|
16 |
|
17 def getargs(): |
|
18 args = sys.argv[1:] |
|
19 if args: |
|
20 return args |
|
21 print 'No arguments, checking almost *, in "ls -t" order' |
|
22 list = [] |
|
23 for file in os.listdir(os.curdir): |
|
24 if not skipfile(file): |
|
25 list.append((getmtime(file), file)) |
|
26 list.sort() |
|
27 if not list: |
|
28 print 'Nothing to do -- exit 1' |
|
29 sys.exit(1) |
|
30 list.sort() |
|
31 list.reverse() |
|
32 for mtime, file in list: args.append(file) |
|
33 return args |
|
34 |
|
35 def getmtime(file): |
|
36 try: |
|
37 st = os.stat(file) |
|
38 return st[ST_MTIME] |
|
39 except os.error: |
|
40 return -1 |
|
41 |
|
42 badnames = ['tags', 'TAGS', 'xyzzy', 'nohup.out', 'core'] |
|
43 badprefixes = ['.', ',', '@', '#', 'o.'] |
|
44 badsuffixes = \ |
|
45 ['~', '.a', '.o', '.old', '.bak', '.orig', '.new', '.prev', '.not', \ |
|
46 '.pyc', '.fdc', '.rgb', '.elc', ',v'] |
|
47 ignore = [] |
|
48 |
|
49 def setup(): |
|
50 ignore[:] = badnames |
|
51 for p in badprefixes: |
|
52 ignore.append(p + '*') |
|
53 for p in badsuffixes: |
|
54 ignore.append('*' + p) |
|
55 try: |
|
56 f = open('.xxcign', 'r') |
|
57 except IOError: |
|
58 return |
|
59 ignore[:] = ignore + f.read().split() |
|
60 |
|
61 def skipfile(file): |
|
62 for p in ignore: |
|
63 if fnmatch.fnmatch(file, p): return 1 |
|
64 try: |
|
65 st = os.lstat(file) |
|
66 except os.error: |
|
67 return 1 # Doesn't exist -- skip it |
|
68 # Skip non-plain files. |
|
69 if not S_ISREG(st[ST_MODE]): return 1 |
|
70 # Skip huge files -- probably binaries. |
|
71 if st[ST_SIZE] >= MAXSIZE: return 1 |
|
72 # Skip executables |
|
73 try: |
|
74 data = open(file, 'r').read(len(EXECMAGIC)) |
|
75 if data == EXECMAGIC: return 1 |
|
76 except: |
|
77 pass |
|
78 return 0 |
|
79 |
|
80 def badprefix(file): |
|
81 for bad in badprefixes: |
|
82 if file[:len(bad)] == bad: return 1 |
|
83 return 0 |
|
84 |
|
85 def badsuffix(file): |
|
86 for bad in badsuffixes: |
|
87 if file[-len(bad):] == bad: return 1 |
|
88 return 0 |
|
89 |
|
90 def go(args): |
|
91 for file in args: |
|
92 print file + ':' |
|
93 if differing(file): |
|
94 showdiffs(file) |
|
95 if askyesno('Check in ' + file + ' ? '): |
|
96 sts = os.system('rcs -l ' + file) # ignored |
|
97 sts = os.system('ci -l ' + file) |
|
98 |
|
99 def differing(file): |
|
100 cmd = 'co -p ' + file + ' 2>/dev/null | cmp -s - ' + file |
|
101 sts = os.system(cmd) |
|
102 return sts != 0 |
|
103 |
|
104 def showdiffs(file): |
|
105 cmd = 'rcsdiff ' + file + ' 2>&1 | ${PAGER-more}' |
|
106 sts = os.system(cmd) |
|
107 |
|
108 def askyesno(prompt): |
|
109 s = raw_input(prompt) |
|
110 return s in ['y', 'yes'] |
|
111 |
|
112 if __name__ == '__main__': |
|
113 try: |
|
114 setup() |
|
115 go(getargs()) |
|
116 except KeyboardInterrupt: |
|
117 print '[Intr]' |