Strony

czwartek, 26 listopada 2009

eol once again

Here is another pre-commit hook I wrote for Subversion repositories. Let's assume many people (not always smart enough) accessing and committing to your Subversion repository. They don't know how to configure their svn client, but you want to be sure, that all text files have the same line endings (e.g. Unix = LF). So, to be sure that all line endings are consistent, you could run this hook, which blocks commit operation if svn:eol-style is not set to required one.

!/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()
view raw Aeolus.py hosted with ❤ by GitHub
As always you should modify also your pre-commit file, usually stored in repo/hooks directory, e.g.:

#!/bin/sh
REPOS="$1"
TXN="$2"
AEOLUS=/PATH/TO/REPO/hooks/aeolus.py
#line endings
$AEOLUS -t "$TXN" "$REPOS" || exit 1
exit 0
view raw aeolus.sh hosted with ❤ by GitHub
And that's it! ;)

Brak komentarzy:

Prześlij komentarz