!/usr/bin/env python # @file aeolus.py # @author Krzysztof Danile Ciba (Krzysztof.Ciba@NOSPAMgmail.com) # @brief svn pre-commit hook for checking correct line endings import os, sys import re import svn import svn.fs import svn.repos import svn.core import getopt ## usage and exit, help, ero messages def usage_and_exit(error_msg=None): import os.path stream = error_msg and sys.stderr or sys.stdout if error_msg: stream.write("ERROR: %s\n\n" % error_msg ) stream.write("USAGE: %s -t TXN_NAME REPOS\n" % (os.path.basename(sys.argv[0]))) sys.exit(error_msg and 1 or 0) ## # @class aeolus # @author Krzysztof Daniel Ciba (Krztysztof.Ciba@NOSPAMgmail.com) # @brief blocks commit to repo if property svn:eol-style is not set or is not correct (ne LF) class Aeolus: reText = re.compile(".+\.h$|.+\.cpp$|.+\.cxx$|.+\.hh$|.+\.icc$|.+\.C$|.+\.c$|.+\.py$|.+\.f$|.+\.F$|.+\.f90$|.+\.F90$|.+\.java$|.+\.php$|.+\.sh$|.+\.csh$|.+\.tex$|.+ChangeLog$|.+\.cmt$|.+requirements$|.+\.txt$|.+\.xml$|.+\.css$.+\.html$") ## c'tor # @param self "Me, myself and Irene" def __init__(self): self.repos_path = None self.txn_name = None try: opts, args = getopt.getopt(sys.argv[1:], 't:h?', ["help"]) except: usage_and_exit("problem processing arguments / options.") for opt, value in opts: if opt == '--help' or opt == '-h' or opt == '-?': usage_and_exit() elif opt == '-t': self.txn_name = value else: usage_and_exit("unknown option '%s'." % opt ) if self.txn_name is None: usage_and_exit("must provide -t argument") if len(args) != 1: usage_and_exit("only one argument allowed (the repository).") self.repos_path = svn.core.svn_path_canonicalize( args[0] ) self.fs = svn.repos.svn_repos_fs( svn.repos.svn_repos_open( self.repos_path ) ) self.txn = svn.fs.svn_fs_open_txn ( self.fs, self.txn_name ) self.txn_root = svn.fs.svn_fs_txn_root( self.txn ) changed_paths = svn.fs.paths_changed( self.txn_root ) for path, change in changed_paths.iteritems(): if ( svn.fs.svn_fs_is_file( self.txn_root, path ) == 1 ): if ( self.reText.match( path ) ): node_props = svn.fs.node_proplist( self.txn_root, path ) if ( "svn:eol-style" in node_props ): if ( node_props["svn:eol-style"] != "LF" ): sys.stderr.write("ERROR: file " + path + " has got wrong line endings!\n\n") sys.stderr.write("In this repository only UNIX/Linux(=LF) line endings are allowed,\n") sys.stderr.write("but this file is using " + node_props["svn:eol-style"] + " line endigs.\n\n") sys.stderr.write("You should modify 'svn:eol-style' property:\n\n") sys.stderr.write("[1] using command:\n") sys.stderr.write(" shell> svn propset svn:eol-style LF WORKING_COPY/FILENAME\n\n" ) sys.stderr.write("[2] by changing your svn client settings (usualy stored in $HOME/.subversion/config file):\n") sys.stderr.write(" - in section [miscellany] make sure that 'enable-auto-props' is set to 'yes'\n" ) sys.stderr.write(" [miscellany]\n") sys.stderr.write(" enable-auto-props = yes\n" ) sys.stderr.write(" - in section [auto-props] add pattern for your source file (i.e. *.py for python source file)\n") sys.stderr.write(" [auto-props]\n") sys.stderr.write(" *.py = svn:eol-style=LF\n\n") sys.stderr.write("Contact librarian ('librarian@somewhere') for details.\n") sys.exit(1) else: # silently set eol-style prop to LF svn.fs.change_node_prop( self.txn_root, path, "svn:eol-style", "LF" ) sys.exit(0) ## execution if __name__ == "__main__": Aeolus()