hooks: Refactor

The hook functions now all work in terms of local variables and argument
passing. They return error codes rather than exiting. Fixing issues
(updating copyright and correcting ifndef/define names) is now optional.
The "interactive" aspect of the pre-recieve hook has been removed and
placed into a new interactive-hook script that can be used for checking
without commiting. The pre-recieve-hook has been updated to include all
the newer checking added to pre-commit-hook.
This commit is contained in:
Will Bainbridge
2019-03-13 12:40:25 +00:00
parent fec55234b6
commit 0ce996ffd4
4 changed files with 501 additions and 427 deletions

View File

@ -2,7 +2,7 @@
# ========= | # ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox # \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration | Website: https://openfoam.org # \\ / O peration | Website: https://openfoam.org
# \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation # \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation
# \\/ M anipulation | # \\/ M anipulation |
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# License # License
@ -29,11 +29,9 @@
# #
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
headerSeparator="-----------------------------------" if [ -z "$sourceBanner" ]
then
echoIndent=" " sourceBanner="(\
sourceBanner="(\
/\*---------------------------------------------------------------------------\*\\\\|\ /\*---------------------------------------------------------------------------\*\\\\|\
/\*--------------------------------\*- C\+\+ -\*----------------------------------\*\\\\|\ /\*--------------------------------\*- C\+\+ -\*----------------------------------\*\\\\|\
/\*---------------------------------\*- C -\*-----------------------------------\*\\\\) /\*---------------------------------\*- C -\*-----------------------------------\*\\\\)
@ -61,8 +59,11 @@ License
(.| (.|
)*? )*?
\\\\\*---------------------------------------------------------------------------\*/" \\\\\*---------------------------------------------------------------------------\*/"
fi
scriptBanner="(\ if [ -z "$scriptBanner" ]
then
scriptBanner="(\
#------------------------------------------------------------------------------|\ #------------------------------------------------------------------------------|\
#---------------------------------\*- sh -\*-------------------------------------|\ #---------------------------------\*- sh -\*-------------------------------------|\
#----------------------------------\*-sh-\*--------------------------------------|\ #----------------------------------\*-sh-\*--------------------------------------|\
@ -91,8 +92,11 @@ scriptBanner="(\
(.| (.|
)*? )*?
#------------------------------------------------------------------------------" #------------------------------------------------------------------------------"
fi
dictBanner="(\ if [ -z "$dictBanner" ]
then
dictBanner="(\
/\*---------------------------------------------------------------------------\*\\\\|\ /\*---------------------------------------------------------------------------\*\\\\|\
/\*--------------------------------\*- C\+\+ -\*----------------------------------\*\\\\) /\*--------------------------------\*- C\+\+ -\*----------------------------------\*\\\\)
========= \| ========= \|
@ -102,373 +106,349 @@ dictBanner="(\
\\\\\\\\/ M anipulation \|(.| \\\\\\\\/ M anipulation \|(.|
)*? )*?
\\\\\*---------------------------------------------------------------------------\*/" \\\\\*---------------------------------------------------------------------------\*/"
fi
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# gitIsRevision() # commit
# report failure and exit
#
die()
{ {
echo "$hookName hook failure" 1>&2 git rev-parse --verify "$1" > /dev/null 2>&1
echo $headerSeparator 1>&2 return $?
echo '' 1>&2
echo "$@" 1>&2
echo '' 1>&2
exit 1
} }
# scopeGit() # scope, cacheScope
# report failure, listing bad files and exit
#
dieOnBadFiles()
{ {
if [ -n "$badFiles" ] if [ "$1" == "--cached" ]
then then
echo "$hookName hook failure" 1>&2 echo "$2"
echo $headerSeparator 1>&2 elif gitIsRevision "$1"
echo "$@" 1>&2 then
echo '' 1>&2 echo "$1:"
echo "File(s):" 1>&2 else
echo "$badFiles" 1>&2 echo "$(basename "$0"): $1 is not a valid scope"
echo '' 1>&2
exit 1 exit 1
fi fi
} }
# scopeGitGrep() # scope
# qualify 'git grep' to check cached value or from a specific commit
#
gitScopeGrep()
{ {
if [ "$#" -gt 0 ] scopeGit "$1" "--cached -- "
}
scopeGitShow() # scope
{
scopeGit "$1" ":"
}
reportStart() # startMessage
{
echo -n "$1 ... " 1>&2
}
reportEnd() # failMessage, errorCount, errorMessages...
{
local failMessage errorCount
failMessage=$1
shift
errorCount=$1
shift
if [ "$errorCount" -eq 0 ]
then then
echo "$1:" echo PASSED 1>&2
else else
echo "--cached -- " echo "FAILED with $errorCount errors:" 1>&2
echo "$failMessage" | sed "s/^/ /g" 1>&2
for errorMessage in "$@"
do
echo "$errorMessage" | sed "s/^/ /g" 1>&2
done
fi fi
} }
# checkPattern() # scope, pattern, include, exclude, files...
# qualify 'git show' to check cached value or from a specific commit
#
gitScopeShow()
{ {
if [ "$#" -gt 0 ] local scope pattern include exclude lines errorCount=0
scope=$(scopeGitGrep "$1")
shift
pattern="$1"
shift
include="$1"
shift
exclude="$1"
shift
# Loop files, accumulating errors
for file in "$@"
do
case "$file" in
($exclude)
;;
($include)
if [ "$(file -b "$file")" != "data" ]
then then
echo "$1:" lines=$( \
else eval git grep -E -hn $pattern $scope"$file" \
echo ":" | sed -e "s/:.*//" \
fi | tr "\n" " " \
} )
if [ -n "$lines" ]
#
# check for bad strings, characters, etc
#
checkIllegalCode()
{
echo "$hookName: check bad strings/characters etc ..." 1>&2
reBad="("$'\t'")"
msgBad="<TAB>"
scope=$(gitScopeGrep $@)
badFiles=$(
for f in $fileList
do
case "$f" in
# exclude potential makefiles
(*[Mm]akefile* | wmake/rules/* | bin/tools/gtagsrc | *.f* | *.v[cf]proj | *.pdf | *.png | *.html | *.gif | *.css | *.gz)
;;
(*)
fileType=`file -b $f`
if [ "$fileType" != "data" ]
then then
# parse line numbers from grep output: echo "$file: Lines $lines"
# <lineNr>: contents ((++errorCount))
lines=$(git grep -E -hn -e "$reBad" $scope"$f" | fi
sed -e 's@:.*@@' |
tr '\n' ' '
)
[ -n "$lines" ] && echo "$echoIndent$f -- lines: $lines"
fi fi
;; ;;
esac esac
done done
)
dieOnBadFiles "Remove/correct bad '$msgBad' references" return $errorCount
} }
# checkTabs() # scope, files...
# limit line length to 80-columns
#
checkLineLength()
{ {
echo "$hookName: check line lengths ..." 1>&2 reportStart "Check for tabs"
scope=$(gitScopeGrep $@) local scope pattern include exclude errorCount errorMessages
badFiles=$( scope=$1
for f in $fileList shift
do pattern="-e $'\t'"
# limit to *.[CH] files include="*"
case "$f" in exclude="*[Mm]akefile* | wmake/rules/* | bin/tools/gtagsrc | *.f* | *.v[cf]proj | *.pdf | *.png | *.html | *.gif | *.css | *.gz"
(*.[CH])
# parse line numbers from grep output:
# <lineNr>: contents
lines=$(git grep -hn -e '^.\{81,\}' $scope"$f" |
sed -e 's@:.*@@' |
tr '\n' ' '
)
[ -n "$lines" ] && echo "$echoIndent$f -- lines: $lines"
;;
esac
done
)
dieOnBadFiles "Limit code to 80 columns before pushing" errorMessages="$(checkPattern "$scope" "$pattern" "$include" "$exclude" "$@")"
errorCount=$?
reportEnd "Remove <TAB> characters from the following files:" $errorCount "$errorMessages"
return $errorCount
} }
# checkLineEnds() # scope, files...
# limit line length to 80-columns, except C++ comment lines
#
checkLineLengthNonComments()
{ {
echo "$hookName: check line lengths ..." 1>&2 reportStart "Check for bad line endings"
scope=$(gitScopeGrep $@) local scope pattern include exclude errorCount errorMessages
badFiles=$( scope=$1
for f in $fileList shift
do pattern="-e \"[ ]+$\" --or -e $'\r'"
# limit to *.[CH] files include="*"
case "$f" in exclude="*.md"
(*.[CH])
# parse line numbers from grep output:
# <lineNr>: contents
lines=$(git grep -hn -e '^.\{81,\}' \
--and --not -e '^ *//' \
$scope"$f" |
sed -e 's@:.*@@' |
tr '\n' ' '
)
[ -n "$lines" ] && echo "$echoIndent$f -- lines: $lines"
;;
esac
done
)
dieOnBadFiles "Limit code to 80 columns before pushing" errorMessages="$(checkPattern "$scope" "$pattern" "$include" "$exclude" "$@")"
errorCount=$?
reportEnd "Remove trailing whitespace and <CR> characters in the following files:" $errorCount "$errorMessages"
return $errorCount
} }
# checkLineLength() # scope, files...
# limit line length to 80-columns, except #directive lines
#
checkLineLengthNonDirective()
{ {
echo "$hookName: check line lengths ..." 1>&2 reportStart "Check line lengths"
scope=$(gitScopeGrep $@) local scope pattern include exclude errorCount errorMessages
badFiles=$( scope=$1
for f in $fileList shift
do pattern="-e \"^.{81,}\" --and --not -e \"^ *#\""
# limit to *.[CH] files include="*.[CH]"
case "$f" in exclude=""
(*.[CH])
# parse line numbers from grep output:
# <lineNr>: contents
lines=$(git grep -hn -e '^.\{81,\}' \
--and --not -e '^ *#' \
$scope"$f" |
sed -e 's@:.*@@' |
tr '\n' ' '
)
[ -n "$lines" ] && echo "$echoIndent$f -- lines: $lines"
;;
esac
done
)
dieOnBadFiles "Limit code to 80 columns before pushing" errorMessages="$(checkPattern "$scope" "$pattern" "$include" "$exclude" "$@")"
errorCount=$?
reportEnd "Limit lines to 80 characters in the following files:" $errorCount "$errorMessages"
return $errorCount
} }
# checkNonStandardCode() # scope, files...
# check for non-standard code patterns
#
checkNonStandardCodePatterns()
{ {
echo "$hookName: checking for non-standard code ..." 1>&2 reportStart "Check for non-standard code"
scope=$(gitScopeGrep $@) local scope pattern include exclude errorCount errorMessages
badFiles=$( scope=$1
for f in $fileList shift
do pattern="-e \"> >\" --or -e \"NULL\""
# limit to *.[CH] files include="*.[CH]"
case "$f" in exclude=""
(*.[CH])
# Directly report the incorrect markers
git grep -n --color -e '> >' \
--or -w -e 'NULL' \
$scope"$f"
;;
esac
done
)
dieOnBadFiles "$(cat<<MESSAGE errorMessages="$(checkPattern "$scope" "$pattern" "$include" "$exclude" "$@")"
Please revise the files reported below for the following non-standard code: errorCount=$?
1. Spaced ending of multi-level template parameters are not allowed, such as: reportEnd "$(cat << EOF
The following is considerd non-standard code:
1. Spaced ending of multi-level template parameters. For example,
List<List<scalar> > List<List<scalar> >
which instead should be: should instead be written:
List<List<scalar>> List<List<scalar>>
2. The use of the 'NULL' macro should be replaced by 'nullptr' 2. The 'NULL' macro. This should be replaced by 'nullptr'.
$headerSeparator Remove these patterns from the following files:
MESSAGE EOF
)" )" $errorCount "$errorMessages"
return $errorCount
} }
# checkHeaderIfndefNames() # scope, fix, files...
# check that header files respect the policy of file names matching the
# #ifndef/#define bounds
#
checkHeaderIfndefNames()
{ {
echo "$hookName: check header files #ifndef/#define names ..." 1>&2 reportStart "Check header file #ifndef/#define names"
scope=$(gitScopeGrep $@) local scopeGrep fix correctDefine currentDefine failMessage errorCount=0 errorMessages=()
badFiles=$( scopeGrep=$(scopeGitGrep "$1")
for f in $fileList shift
fix=$1
shift
for file in "$@"
do do
# limit to *.H files case "$file" in
case "$f" in
(*.H) (*.H)
fileName=$(basename $f) correctDefine=$(basename "$file" | sed 's/\./_/')
correctMangledName=$(basename $f | sed 's=\.=_=')
if git grep -q -e "#ifndef.*_H" $scope"$f" && \ if git grep -q -e "#ifndef.*_H" --and --not -e "#ifndef.*[ _]$correctDefine" $scopeGrep"$file"
! git grep -q -e "#ifndef.*[ _]$correctMangledName" $scope"$f"
then then
echo "Updated #ifndef/#define for: $f" 1>&2 ((++errorCount))
echo $f errorMessages+=("$file")
currentMangled=$(grep "#ifndef.*_H" $f | sed 's=#ifndef\s*==') currentDefine=$(grep "#ifndef.*_H" "$file" | sed 's/#ifndef\s*//')
sed -i -e 's='$currentMangled'='$correctMangledName'=' $f if $fix
then
sed -i -e "s/$currentDefine/$correctDefine/" "$file"
fi
fi fi
;; ;;
esac esac
done done
)
dieOnBadFiles "Some header files were automatically updated to respect #ifndef naming convention; Please check these before pushing" if $fix
then
failMessage="The following files have been automatically updated so that the
#ifndef/#define statements match the file name. Check and re-add them
before pushing:"
else
failMessage="
Revise the following files so that the #ifndef/#define statements match
the file name:"
fi
reportEnd "$failMessage" $errorCount "${errorMessages[@]}"
return $errorCount
} }
# checkBanner() # scope, files...
# check that the banners are correctly formatted
#
checkBanner()
{ {
echo "$hookName: check banner ..." 1>&2 reportStart "Check banners"
scopeGrep=$(gitScopeGrep $@) local scopeGrep scopeShow fileName fileExtension errorCount=0 errorMessages=()
scopeShow=$(gitScopeShow $@)
badFiles=$( scopeGrep=$(scopeGitGrep "$1")
for f in $fileList scopeShow=$(scopeGitShow "$1")
shift
for file in "$@"
do do
fFile="${f##*/}" fileName=$(basename "$file")
[[ "$fFile" = *.* ]] && fExt="${fFile##*.}" || fExt="" fileExtension=${fileName##*.}
# Skip links # Skip links
if [ -h "$f" ] if [ -h "$file" ]
then then
: :
# Copyrighted source and script files # Copyrighted source and script files
elif git grep -q -e "Copyright (C) [0-9-]\+ OpenFOAM Foundation" $scopeGrep"$f" elif git grep -q -e "Copyright (C) [0-9-]\+ OpenFOAM Foundation" $scopeGrep"$file"
then then
case "$fExt" in case "$fileExtension" in
(c|C|Cver|cxx|dox|H|h|l|L) (c|C|Cver|cxx|dox|H|h|l|L)
if ! git show $scopeShow"$f" | pcregrep -q -M "$sourceBanner" if ! git show $scopeShow"$file" | pcregrep -q -M "$sourceBanner"
then then
echo $f ((++errorCount))
errorMessages+=("$file")
fi fi
;; ;;
(''|awk|csh|gnuplot|sed|sh) (''|awk|csh|gnuplot|sed|sh)
if ! git show $scopeShow"$f" | pcregrep -q -M "$scriptBanner" if ! git show $scopeShow"$file" | pcregrep -q -M "$scriptBanner"
then then
echo $f ((++errorCount))
errorMessages+=("$file")
fi fi
;; ;;
(*) (*)
# Unknown extension :
echo "Banner not checked for copyrighted file $f" 1>&2 #((++errorCount))
#errorMessages+=("$file: Unknown extension")
;; ;;
esac esac
# Versioned case files # Versioned case files
elif git grep -q -e "Version: \(dev\|[0-9.]+\)" $scopeGrep"$f" elif git grep -q -e "Version: \(dev\|[0-9.]+\)" $scopeGrep"$file"
then then
if ! git show $scopeShow"$f" | pcregrep -q -M "$dictBanner" if ! git show $scopeShow"$file" | pcregrep -q -M "$dictBanner"
then then
echo $f ((++errorCount))
errorMessages+=("$file")
fi fi
# Unknown files # Unknown files
elif git grep -q -e "OpenFOAM: The Open Source CFD Toolbox" $scopeGrep"$f" elif git grep -q -e "OpenFOAM: The Open Source CFD Toolbox" $scopeGrep"$file"
then then
: #echo "Banner not checked for file $f" 1>&2 :
#((++errorCount))
#errorMessages+=("$file: Missing copyright or version")
fi fi
done done
)
dieOnBadFiles "Fix banner formatting before pushing" reportEnd "Correct the banner formating in the following files:" $errorCount "${errorMessages[@]}"
return $errorCount
} }
# checkCopyright() # scope, fix, files...
# check that OpenFOAM Foundation copyright is current
#
checkCopyright()
{ {
echo "$hookName: check copyright ..." 1>&2 reportStart "Check copyright"
scope=$(gitScopeGrep $@) local scopeGrep fix year startYear endYear errorCount=0 errorMessages=() failMessage
scopeGrep=$(scopeGitGrep "$1")
shift
fix=$1
shift
year=$(date +%Y) year=$(date +%Y)
badFiles=$( for file in "$@"
for f in $fileList
do do
startYear=$( startYear=$( \
git grep -h -e "Copyright.*OpenFOAM" $scope"$f" | \ git grep -h -e "Copyright.*OpenFOAM" $scopeGrep"$file" \
head -n 1 | \ | head -n 1 \
sed 's/[^0-9]*\([0-9]*\).*/\1/g' | sed 's/[^0-9]*\([0-9]*\).*/\1/g'
) )
endYear=$( endYear=$( \
git grep -h -e "Copyright.*-.*OpenFOAM" $scope"$f" | \ git grep -h -e "Copyright.*-.*OpenFOAM" $scopeGrep"$file" \
head -n 1 | \ | head -n 1 \
sed 's/[^-]*-\([0-9]*\).*/\1/g' | sed 's/[^-]*-\([0-9]*\).*/\1/g'
) )
if [ "$startYear" != "" ] if [ "$startYear" != "" ]
@ -478,25 +458,89 @@ checkCopyright()
# Date is of type 2011-2012 OpenFOAM Foundation # Date is of type 2011-2012 OpenFOAM Foundation
if [ "$year" != "$endYear" ] if [ "$year" != "$endYear" ]
then then
echo "Updated copyright for: $f" 1>&2 ((++errorCount))
echo "$f" errorMessages+=("$file")
sed -i -e "s/$startYear-$endYear OpenFOAM/$startYear-$year OpenFOAM/g" $f if $fix
then
sed -i -e "s/$startYear-$endYear OpenFOAM/$startYear-$year OpenFOAM/g" "$file"
fi
fi fi
else else
# Date is of type 2011 OpenFOAM Foundation # Date is of type 2011 OpenFOAM Foundation
if [ "$year" != "$startYear" ] if [ "$year" != "$startYear" ]
then then
echo "$f" ((++errorCount))
echo "Updated copyright for: $f" 1>&2 errorMessages+=("$file")
sed -i -e "s/$startYear OpenFOAM/$startYear-$year OpenFOAM/g" $f if $fix
then
sed -i -e "s/$startYear OpenFOAM/$startYear-$year OpenFOAM/g" "$file"
fi
fi fi
fi fi
fi fi
done done
)
dieOnBadFiles "Some copyright dates were automatically updated; Please check these before pushing" if $fix
then
failMessage="The following files have had their copyright dates automatically
updated. Check and re-add them before pushing:"
else
failMessage="Update the copyright dates in the following files:"
fi
reportEnd "$failMessage" $errorCount "${errorMessages[@]}"
return $errorCount
} }
checkAllNoCopyright() # scope, fix, files...
{
local scope fix returnCode=0
scope="$1"
shift
fix="$1"
shift
# Check for tabs
checkTabs "$scope" "$@" || returnCode=1
# Check line endings
checkLineEnds "$scope" "$@" || returnCode=1
# Ensure code line lengths do not exceed 80 columns
checkLineLength "$scope" "$@" || returnCode=1
# Check for non-standard code patterns
checkNonStandardCode "$scope" "$@" || returnCode=1
# Check if #ifndef/#define bounds are named correctly
checkHeaderIfndefNames "$scope" "$fix" "$@" || returnCode=1
# Check banner
checkBanner "$scope" "$@" || returnCode=1
return $returnCode
}
checkAll() # scope, fix, files...
{
local scope fix returnCode=0
scope="$1"
shift
fix="$1"
shift
# Check all except copyright
checkAllNoCopyright "$scope" "$fix" "$@" || returnCode=1
# Check copyright
checkCopyright "$scope" "$fix" "$@" || returnCode=1
return $returnCode
}
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------

92
bin/tools/interactive-hook Executable file
View File

@ -0,0 +1,92 @@
#!/bin/bash
#---------------------------------*- sh -*-------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration | Website: https://openfoam.org
# \\ / A nd | Copyright (C) 2019 OpenFOAM Foundation
# \\/ M anipulation |
#------------------------------------------------------------------------------
# License
# This file is part of OpenFOAM.
#
# OpenFOAM is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
#
# Script
# interactive-hook
#
# Description
# Script to interactively run the checks performed by the pre-commit and
# pre-recieve hooks.
#
#------------------------------------------------------------------------------
. $WM_PROJECT_DIR/bin/tools/HookFunctions || exit 1
usage() {
cat << EOF
Usage: ${0##*/} [OPTION] <path-0> <path-1> ...
Options:
-h, -help print this usage
-s, -scope which commit to check, or "--cached" for staged changes
-f, -fix additionally fix files where possible
-c, -copyright also check that the copyright date is up to date
EOF
}
error() {
usage 1>&2
exit 1
}
scope=HEAD
fix=false
copyright=false
paths=()
while [ "$#" -gt 0 ]
do
case "$1" in
(-h | -help)
usage && exit 0
;;
(-s | -scope)
scope="$2"
shift 2
;;
(-f | -fix)
fix=true
shift
;;
(-c | -copyright)
copyright=true
shift
;;
-*)
error
;;
(*)
paths+=("$1")
shift
;;
esac
done
[ "${#paths[@]}" -gt 0 ] || paths=(".")
readarray -t files < <(git ls-files -- "${paths[@]}")
$copyright && check=checkAll || check=checkAllNoCopyright
$check "$scope" $fix "${files[@]}" && exit 0 || exit 1
#------------------------------------------------------------------------------

View File

@ -3,7 +3,7 @@
# ========= | # ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox # \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration | Website: https://openfoam.org # \\ / O peration | Website: https://openfoam.org
# \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation # \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation
# \\/ M anipulation | # \\/ M anipulation |
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# License # License
@ -26,100 +26,46 @@
# pre-commit-hook # pre-commit-hook
# #
# Description # Description
# pre-commit hook for git. # pre-commit hook for git. Copy or link this file to
# Copy or link this file as ".git/hooks/pre-commit" # ".git/hooks/pre-commit"; e.g.,
#
# Eg,
# ( # (
# cd $WM_PROJECT_DIR/.git/hooks && # cd $WM_PROJECT_DIR/.git/hooks &&
# ln -sf ../../bin/tools/pre-commit-hook pre-commit # ln -sf ../../bin/tools/pre-commit-hook pre-commit
# ) # )
# #
# Hook receives: empty # Hook receives: (nothing)
# #
# Checks for # Checks for:
# - tabs
# - trailing whitespace and non-standard line endings # - trailing whitespace and non-standard line endings
# - illegal code, e.g. <TAB> # - lines longer that than 80 characters
# - columns greater than 80 for *.[CH] files # - non-standard code patterns, > > and NULL
# - non-standard code patterns
# - mismatched header #ifndef/#define names # - mismatched header #ifndef/#define names
# - incorrect copyright statements # - incorrect copyright statements
# #
# Note # Note
# Using "git commit --no-verify" it is possible to override the hook. # Using "git commit --no-verify" it is possible to override the hook.
# #
# By supplying arguments to the hook, it can also be used to manually
# test the specified files/directories for standards conformance.
#
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
. bin/tools/HookFunctions || exit 1 . ./bin/tools/HookFunctions || exit 1
hookName="pre-commit" # Get the commit to test against, or git's "empty" object if there is no head
#-----------------------------------------------------------------------------
# Check content that will be added by this commit
#
# Clear
unset fileList
unset badFiles
# Get the commit to test against
if git rev-parse --verify HEAD > /dev/null 2>&1 if git rev-parse --verify HEAD > /dev/null 2>&1
then then
against=HEAD against=HEAD
else else
# Git's "empty" object
against=$(git hash-object -t tree /dev/null) against=$(git hash-object -t tree /dev/null)
fi fi
# Get the list of files to check # Get the list of files to check
if [ "$#" -gt 0 ] readarray -t files < <(git diff-index --cached --name-only "$against" --)
then
# Called with arguments for the files/directories to be tested
case "$1" in
-h | -help)
die "interactive usage: supply list of files/directories to check"
;;
esac
fileList=$(git ls-files -- $@ 2>/dev/null)
else
# Called with out arguments to test staged changes
fileList=$(git diff-index --cached --name-only $against --)
fi
# If no files have changed then the checks are not needed. This usage can # If no files have changed then the checks are not needed. This usage can
# correspond to a 'git commit --amend' # correspond to a 'git commit --amend'.
[ -n "$fileList" ] || exit 0 [ "${#files[@]}" -gt 0 ] || exit 0
# Do checks
#------------------------------------------------------------------------------ checkAll --cached true "${files[@]}" && exit 0 || exit 1
# Main code. Do all checks.
# Builtin whitespace check to avoid trailing space, including CR-LF endings
bad=$(git diff-index --cached --check $against -- ':(exclude)*.md') || die "$bad"
# Check for illegal code, e.g. <TAB>, etc
checkIllegalCode
# Ensure code conforms to 80 columns max
checkLineLengthNonDirective
# Check for non-standard code patterns
checkNonStandardCodePatterns
# Check if #ifndef/#define bounds are named correctly
checkHeaderIfndefNames
# Check banner
checkBanner
# Check copyright
checkCopyright
exit 0
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------

View File

@ -3,7 +3,7 @@
# ========= | # ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox # \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration | Website: https://openfoam.org # \\ / O peration | Website: https://openfoam.org
# \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation # \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation
# \\/ M anipulation | # \\/ M anipulation |
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# License # License
@ -26,10 +26,8 @@
# pre-receive-hook # pre-receive-hook
# #
# Description # Description
# pre-receive hook for git. # pre-receive hook for git. Copy or link this file to
# Copy or link this file as ".git/hooks/pre-receive" # ".git/hooks/pre-receive"; e.g.,
#
# Eg,
# ( # (
# cd $WM_PROJECT_DIR/.git/hooks && # cd $WM_PROJECT_DIR/.git/hooks &&
# ln -sf ../../bin/tools/pre-receive-hook pre-receive # ln -sf ../../bin/tools/pre-receive-hook pre-receive
@ -37,54 +35,48 @@
# #
# Hook receives: <old-sha1> <new-sha1> <ref-name> # Hook receives: <old-sha1> <new-sha1> <ref-name>
# #
# Checks for # Checks for:
# - illegal code, e.g. <TAB> # - tabs
# - columns greater than 80 for *.[CH] files # - trailing whitespace and non-standard line endings
# - lines longer that than 80 characters
# - non-standard code patterns, > > and NULL
# - mismatched header #ifndef/#define names
# - incorrect copyright statements
# #
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
. bin/tools/HookFunctions || exit 1 . bin/tools/HookFunctions || exit 1
hookName="pre-receive" while read -r oldSHA1 newSHA1 refName
#------------------------------------------------------------------------------
# Main code. Do all checks.
#
while read oldSHA1 newSHA1 refName
do do
unset fileList rawFileList unset rawFiles files
# Get the list of changed files
if [ "$newSHA1" = 0 ] if [ "$newSHA1" = 0 ]
then then
# Ref to be deleted
continue continue
elif [ "$oldSHA1" = 0 ] elif [ "$oldSHA1" = 0 ]
then then
# Ref to be created readarray -t rawFiles < <(git diff-tree --root "$newSHA1")
rawFileList=$(git diff-tree --root $newSHA1)
else else
# Normal changes readarray -t rawFiles < <(git diff --name-only "$oldSHA1".."$newSHA1")
rawFileList=$(git diff --name-only $oldSHA1..$newSHA1)
fi fi
# No files have changed, so the checks are not necessary # If no files have changed then the checks are not necessary
[ -n "$rawFileList" ] || continue [ "${#rawFiles[@]}" -gt 0 ] || continue
fileList=$( # Filter the file list
for f in $rawFileList files=()
for file in "${rawFiles[@]}"
do do
git cat-file -e $newSHA1:$f > /dev/null 2>&1 && echo "$f" if git cat-file -e "$newSHA1":"$file" > /dev/null 2>&1
then
files+=("$file")
fi
done done
)
# check for illegal code, e.g. <TAB>, etc
checkIllegalCode $newSHA1
# ensure code conforms to 80 columns max
checkLineLengthNonDirective $newSHA1
# Do the checks
checkAllNoCopyright "$newSHA1" false "${files[@]}" || exit 1
done done
exit 0 exit 0