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