#!/usr/bin/env python # (c) 2005-2010 Chad Whitacre # This program is beerware. If you like it, buy me a beer someday. # No warranty is expressed or implied. import os, re, sys from glob import glob try: set except NameError: # pre-2.6 (post-2.3) from sets import Set as set from ConfigParser import RawConfigParser WINDOWS = sys.platform == 'win32' if WINDOWS: CONFIG = '~/Application Data/Subversion/config' else: CONFIG = '~/.subversion/config' nix = re.compile(r'(? 1: pattern = '*.%s' % parts[-1] else: pattern = parts[-1] globs.add(pattern) # Skip svn directories. if '.svn' in dirs: dirs.remove('.svn') globs = list(globs) globs.sort() print '[miscellany]' print 'enable-auto-props = yes' print print '[auto-props]' for pattern in globs: print "%s = svn:eol-style=native" % pattern.ljust(12) def clean(self, top, to_windows): """Given a tree root, clean up newlines in all text files. """ sys.stdout.write('scrubbing newlines ...') sys.stdout.flush() j = 0 for path in self._find(top): # Do the replacements. # ==================== textfile = file(path, 'r+') tmp = textfile.read() if to_windows: cleaned, k = nix.subn('\r\n', tmp) cleaned, l = mac.subn('\r\n', cleaned) else: cleaned, k = win.subn('\n', tmp) cleaned, l = mac.subn('\n', cleaned) # Indicate progress. # ================== if k + l > 0: textfile.seek(0) textfile.truncate() textfile.write(cleaned) textfile.close() j += 1 if j % 50 == 0: sys.stdout.write('.') sys.stdout.flush() print ' %s file%s cleaned' % (j, (j != 1) and 's' or '') def find_dirty(self, top, to_windows): """Given a tree root, find all text files that have unclean newlines. """ for path in self._find(top): tmp = file(path, 'r').read() if to_windows: if nix.search(tmp): print path elif mac.search(tmp): print path else: if win.search(tmp): print path elif mac.search(tmp): print path def find(self, top, to_windows_ignored): """Given a tree root, walk the tree and find all text files. """ for filepath in self._find(top): print filepath def _find(self, top): """Generator that yields paths of text files. """ globs = self._confglobs() for path, dirs, filenames in os.walk(top): for pattern in globs: fullpattern = '%s/%s' % (path, pattern) for textfile in glob(fullpattern): if not os.path.isfile(textfile): continue # could be dir, eh? yield textfile if '.svn' in dirs: dirs.remove('.svn') if __name__ == '__main__': # Get our subcommand. # =================== def print_usage(): print "svneol {clean,confgen,find_dirty,find} [-w] [path]" if not WINDOWS: print "see man 1 svneol for usage" subcommand = sys.argv[1:2] if not subcommand: print_usage() sys.exit(2) elif subcommand not in (['clean'], ['confgen'], ['find_dirty'], ['find']): print "'%s' command not available" % subcommand[0] print_usage() sys.exit(2) else: subcommand = subcommand[0] # Decide if we want to convert to windows newlines. # ================================================= to_windows = False if '-w' in sys.argv: to_windows = True sys.argv.remove('-w') # Determine the root of the tree. # =============================== arg = sys.argv[2:3] if arg: path = arg[0] else: path = '.' path = os.path.realpath(path) # Instantiate and invoke the toolkit. # =================================== toolkit = EOLToolkit() func = getattr(toolkit, subcommand) try: func(path, to_windows) except IOError: pass # play nice with less(1)