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