STYLE: date
[OpenFOAM-2.0.x.git] / bin / tools / pre-commit-hook
blob94018f90b7fff4649360ae3ca6601439052836e6
1 #!/bin/bash
2 #---------------------------------*- sh -*-------------------------------------
3 # ========= |
4 # \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 # \\ / O peration |
6 # \\ / A nd | Copyright (C) 2010-2011 OpenCFD Ltd.
7 # \\/ M anipulation |
8 #------------------------------------------------------------------------------
9 # License
10 # This file is part of OpenFOAM.
12 # OpenFOAM is free software: you can redistribute it and/or modify it
13 # under the terms of the GNU General Public License as published by
14 # the Free Software Foundation, either version 3 of the License, or
15 # (at your option) any later version.
17 # OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
18 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 # for more details.
22 # You should have received a copy of the GNU General Public License
23 # along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 # Script
26 # pre-commit-hook
28 # Description
29 # pre-commit hook for git.
30 # Copy or link this file as ".git/hooks/pre-commit"
32 # Eg,
33 # (
34 # cd $WM_PROJECT_DIR/.git/hooks &&
35 # ln -sf ../../bin/tools/pre-commit-hook pre-commit
36 # )
38 # Hook receives: empty
40 # Checks for
41 # - illegal code, e.g. <TAB>
42 # - columns greater than 80 for *.[CH] files
44 # Note
45 # Using "git commit --no-verify" it is possible to override the hook.
47 # By supplying arguments to the hook, it can also be used to manually
48 # test the specified files/directories for standards conformance.
50 #------------------------------------------------------------------------------
51 hookName="pre-commit"
52 die()
54 echo "$hookName hook failure" 1>&2
55 echo '-----------------------------------' 1>&2
56 echo '' 1>&2
57 echo "$@" 1>&2
58 echo '' 1>&2
59 exit 1
62 #-----------------------------------------------------------------------------
63 # Check content that will be added by this commit.
65 if git rev-parse --verify HEAD > /dev/null 2>&1
66 then
67 against=HEAD
68 else
69 # Initial commit: diff against an empty tree object
70 against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
73 # called manually with arguments for the files/directories to be tested?
74 if [ "$#" -gt 0 ]
75 then
76 case "$1" in
77 -h | -help)
78 die "interactive usage: supply list of files/directories to check"
80 esac
82 # obtain list of all specified files/directories
83 fileList=$(git ls-files -- $@ 2>/dev/null)
84 else
85 # list of all files to be committed
86 fileList=$(git diff-index --cached --name-only $against --)
90 # no files changed: can skip all the checks
91 # this usage can correspond to a 'git commit --amend'
93 [ -n "$fileList" ] || exit 0
96 unset badFiles
97 # join list of files with this amount of space
98 Indent=" "
101 # report bad files and die if there are any
103 dieOnBadFiles()
105 if [ -n "$badFiles" ]
106 then
107 echo "$hookName hook failure" 1>&2
108 echo '-----------------------------------' 1>&2
109 echo "$@" 1>&2
110 echo '' 1>&2
111 echo "File(s):" 1>&2
112 echo "$badFiles" 1>&2
113 echo '' 1>&2
114 exit 1
120 # qualify 'git grep' to check cached value or from a specific commit
122 gitScope()
124 if [ "$#" -gt 0 ]
125 then
126 echo "$1:"
127 else
128 echo "--cached -- "
134 # check for bad strings, characters, etc
136 checkIllegalCode()
138 echo "$hookName: check bad strings/characters etc ..." 1>&2
140 reBad="("$'\t'")"
141 msgBad="<TAB>"
143 scope=$(gitScope $@)
145 badFiles=$(
146 for f in $fileList
148 case "$f" in
149 # exclude potential makefiles
150 (*[Mm]akefile* | wmake/rules/*)
153 # parse line numbers from grep output:
154 # <lineNr>: contents
155 lines=$(git grep -E -hn -e "$reBad" $scope"$f" |
156 sed -e 's@:.*@@' |
157 tr '\n' ' '
159 [ -n "$lines" ] && echo "$Indent$f -- lines: $lines"
161 esac
162 done
165 dieOnBadFiles "Remove/correct bad '$msgBad' references"
170 # limit line length to 80-columns
172 checkLineLength()
174 echo "$hookName: check line lengths ..." 1>&2
176 scope=$(gitScope $@)
178 badFiles=$(
179 for f in $fileList
181 # limit to *.[CH] files
182 case "$f" in
183 (*.[CH])
184 # parse line numbers from grep output:
185 # <lineNr>: contents
186 lines=$(git grep -hn -e '^.\{81,\}' $scope"$f" |
187 sed -e 's@:.*@@' |
188 tr '\n' ' '
190 [ -n "$lines" ] && echo "$Indent$f -- lines: $lines"
192 esac
193 done
196 dieOnBadFiles "Limit code to 80 columns before pushing"
201 # limit line length to 80-columns, except C++ comment lines
203 checkLineLengthNonComments()
205 echo "$hookName: check line lengths ..." 1>&2
207 scope=$(gitScope $@)
209 badFiles=$(
210 for f in $fileList
212 # limit to *.[CH] files
213 case "$f" in
214 (*.[CH])
215 # parse line numbers from grep output:
216 # <lineNr>: contents
217 lines=$(git grep -hn -e '^.\{81,\}' \
218 --and --not -e '^ *//' \
219 $scope"$f" |
220 sed -e 's@:.*@@' |
221 tr '\n' ' '
223 [ -n "$lines" ] && echo "$Indent$f -- lines: $lines"
225 esac
226 done
229 dieOnBadFiles "Limit code to 80 columns before pushing"
234 # limit line length to 80-columns, except #directive lines
236 checkLineLengthNonDirective()
238 echo "$hookName: check line lengths ..." 1>&2
240 scope=$(gitScope $@)
242 badFiles=$(
243 for f in $fileList
245 # limit to *.[CH] files
246 case "$f" in
247 (*.[CH])
248 # parse line numbers from grep output:
249 # <lineNr>: contents
250 lines=$(git grep -hn -e '^.\{81,\}' \
251 --and --not -e '^ *#' \
252 $scope"$f" |
253 sed -e 's@:.*@@' |
254 tr '\n' ' '
256 [ -n "$lines" ] && echo "$Indent$f -- lines: $lines"
258 esac
259 done
262 dieOnBadFiles "Limit code to 80 columns before pushing"
266 #------------------------------------------------------------------------------
267 # Main code : do all checks
270 # builtin whitespace check to avoid trailing space, including CR-LF endings
271 bad=$(git diff-index --cached --check $against --) || die "$bad"
273 # check for illegal code, e.g. <TAB>, etc
274 checkIllegalCode
276 # ensure code conforms to 80 columns max
277 checkLineLengthNonDirective
280 exit 0
281 #------------------------------------------------------------------------------