1 | #!/usr/bin/env python
|
---|
2 | """This is for cleaning up binary files improperly added to CVS.
|
---|
3 | This script scans the given path to find binary files; then
|
---|
4 | check with CVS to see if the sticky options are set to -kb;
|
---|
5 | finally if sticky options are not -kb then use 'cvs admin' to
|
---|
6 | set the -kb option. It ignores CVS directories, symbolic links,
|
---|
7 | and files not known under CVS control (cvs status is 'Unknown').
|
---|
8 |
|
---|
9 | Run this on a CHECKED OUT module sandbox, not on the repository itself.
|
---|
10 | After if fixes the sticky options on any files you should manually do
|
---|
11 | a 'cvs commit' to accept the changes. Then be sure to have all users do
|
---|
12 | a 'cvs up -A' to update the Sticky Option status.
|
---|
13 |
|
---|
14 | Noah Spurrier
|
---|
15 | 20030426
|
---|
16 | """
|
---|
17 | import os, sys, time
|
---|
18 | import pexpect
|
---|
19 |
|
---|
20 | VERBOSE = 1
|
---|
21 |
|
---|
22 | def is_binary (filename):
|
---|
23 | """Assume that any file with a character where
|
---|
24 | the 8th bit is set is binary.
|
---|
25 | """
|
---|
26 | fin = open(filename, 'rb')
|
---|
27 | wholething = fin.read()
|
---|
28 | fin.close()
|
---|
29 | for c in wholething:
|
---|
30 | if ord(c) & 0x80:
|
---|
31 | return 1
|
---|
32 | return 0
|
---|
33 |
|
---|
34 | def is_kb_sticky (filename):
|
---|
35 | """This checks if 'cvs status' reports '-kb' for Sticky options.
|
---|
36 | If the Sticky Option status is '-ks' then this returns 1.
|
---|
37 | If the status is 'Unknown' then it returns 1.
|
---|
38 | Otherwise 0 is returned.
|
---|
39 | """
|
---|
40 | try:
|
---|
41 | s = pexpect.spawn ('cvs status %s' % filename)
|
---|
42 | i = s.expect (['Sticky Options:\s*(.*)\r\n', 'Status: Unknown'])
|
---|
43 | if i==1 and VERBOSE:
|
---|
44 | print 'File not part of CVS repository:', filename
|
---|
45 | return 1 # Pretend it's OK.
|
---|
46 | if s.match.group(1) == '-kb':
|
---|
47 | return 1
|
---|
48 | s = None
|
---|
49 | except:
|
---|
50 | print 'Something went wrong trying to run external cvs command.'
|
---|
51 | print ' cvs status %s' % filename
|
---|
52 | print 'The cvs command returned:'
|
---|
53 | print s.before
|
---|
54 | return 0
|
---|
55 |
|
---|
56 | def cvs_admin_kb (filename):
|
---|
57 | """This uses 'cvs admin' to set the '-kb' sticky option.
|
---|
58 | """
|
---|
59 | s = pexpect.run ('cvs admin -kb %s' % filename)
|
---|
60 | # There is a timing issue. If I run 'cvs admin' too quickly
|
---|
61 | # cvs sometimes has trouble obtaining the directory lock.
|
---|
62 | time.sleep(1)
|
---|
63 |
|
---|
64 | def walk_and_clean_cvs_binaries (arg, dirname, names):
|
---|
65 | """This contains the logic for processing files.
|
---|
66 | This is the os.path.walk callback.
|
---|
67 | This skips dirnames that end in CVS.
|
---|
68 | """
|
---|
69 | if len(dirname)>3 and dirname[-3:]=='CVS':
|
---|
70 | return
|
---|
71 | for n in names:
|
---|
72 | fullpath = os.path.join (dirname, n)
|
---|
73 | if os.path.isdir(fullpath) or os.path.islink(fullpath):
|
---|
74 | continue
|
---|
75 | if is_binary(fullpath):
|
---|
76 | if not is_kb_sticky (fullpath):
|
---|
77 | if VERBOSE: print fullpath
|
---|
78 | cvs_admin_kb (fullpath)
|
---|
79 |
|
---|
80 | def main ():
|
---|
81 | if len(sys.argv) == 1:
|
---|
82 | root = '.'
|
---|
83 | else:
|
---|
84 | root = sys.argv[1]
|
---|
85 | os.path.walk (root, walk_and_clean_cvs_binaries, None)
|
---|
86 |
|
---|
87 | if __name__ == '__main__':
|
---|
88 | main ()
|
---|
89 |
|
---|