[421] | 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 | |
---|