diff options
Diffstat (limited to 'git-tools/hooks')
-rwxr-xr-x | git-tools/hooks/commit-msg | 143 | ||||
-rwxr-xr-x | git-tools/hooks/pre-commit | 65 | ||||
-rwxr-xr-x | git-tools/hooks/prepare-commit-msg | 4 |
3 files changed, 183 insertions, 29 deletions
diff --git a/git-tools/hooks/commit-msg b/git-tools/hooks/commit-msg index a6777ff9c9..b156d276df 100755 --- a/git-tools/hooks/commit-msg +++ b/git-tools/hooks/commit-msg @@ -11,14 +11,30 @@ # # ln -s ../../git-tools/hooks/commit-msg \\ # .git/hooks/commit-msg +# +# You can configure whether invalid commit messages abort commits: +# +# git config phpbb.hooks.commit-msg.fatal true (abort) +# git config phpbb.hooks.commit-msg.fatal false (warn only, do not abort) +# +# The default is to warn only. +# +# Warning/error messages use color by default if the output is a terminal +# ("output" here is normally standard error when you run git commit). +# To force or disable the use of color: +# +# git config phpbb.hooks.commit-msg.color true (force color output) +# git config phpbb.hooks.commit-msg.color false (disable color output) config_ns="phpbb.hooks.commit-msg"; -if [ "$(git config --bool $config_ns.fatal)" = "false" ] +if [ "$(git config --bool $config_ns.fatal)" = "true" ] then - fatal=0; -else fatal=1; + severity=Error; +else + fatal=0; + severity=Warning; fi debug_level=$(git config --int $config_ns.debug || echo 0); @@ -47,20 +63,86 @@ debug() quit() { - if [ $1 -gt 0 ] && [ $1 -ne $ERR_UNKNOWN ] && [ $fatal -eq 0 ] + if [ $1 -eq 0 ] || [ $1 -eq $ERR_UNKNOWN ] then + # success + exit 0; + elif [ $fatal -eq 0 ] + then + # problems found but fatal is false + complain 'Please run `git commit --amend` and fix the problems mentioned.' 1>&2 exit 0; else + complain "Aborting commit." 1>&2 exit $1; fi } -msg=$(grep -nE '.{81,}' "$1"); +use_color() +{ + if [ -z "$use_color_cached" ] + then + case $(git config --bool $config_ns.color) + in + false) + use_color_cached=1 + ;; + true) + use_color_cached=0 + ;; + *) + # tty detection in shell: + # http://hwi.ath.cx/jsh/list/shext/isatty.sh.html + tty 0>/dev/stdout >/dev/null 2>&1 + use_color_cached=$? + ;; + esac + fi + # return value is the flag inverted - + # if return value is 0, this means use color + return $use_color_cached +} + +complain() +{ + if use_color + then + # Careful: our argument may include arguments to echo like -n + # ANSI color codes: + # http://pueblo.sourceforge.net/doc/manual/ansi_color_codes.html + printf "\033[31m\033[1m" + if [ "$1" = "-n" ] + then + echo "$@" + printf "\033[0m" + else + # This will print one trailing space. + # Not sure how to avoid this at the moment. + echo "$@" $(printf "\033[0m") + fi + else + echo "$@" + fi +} + +# Check for empty commit message +if ! grep -qv '^#' "$1" +then + # Commit message is empty (or contains only comments). + # Let git handle this. + # It will abort with a message like so: + # + # Aborting commit due to empty commit message. + exit 0 +fi + +msg=$(grep -v '^#' "$1" |grep -nE '.{81,}') if [ $? -eq 0 ] then - echo "The following lines are greater than 80 characters long:\n" >&2; - echo $msg >&2; + complain "The following lines are greater than 80 characters long:" >&2; + complain >&2 + complain "$msg" >&2; quit $ERR_LENGTH; fi @@ -107,7 +189,19 @@ do case $expect in "header") err=$ERR_HEADER; - echo "$line" | grep -Eq "^\[(ticket/[0-9]+|feature/$branch_regex|task/$branch_regex)\] [A-Z].+$" + echo "$line" | grep -Eq "^\[(ticket/[0-9]+|feature/$branch_regex|task/$branch_regex)\] .+$" + result=$? + if ! echo "$line" | grep -Eq "^\[(ticket/[0-9]+|feature/$branch_regex|task/$branch_regex)\] [A-Z].+$" + then + # Don't be too strict. + # Commits may be temporary, intended to be squashed later. + # Just issue a warning here. + complain "$severity: heading should be a sentence beginning with a capital letter." 1>&2 + complain "You entered:" 1>&2 + complain "$line" 1>&2 + fi + # restore exit code + (exit $result) ;; "empty") err=$ERR_EMPTY; @@ -128,11 +222,15 @@ do # Should not end up here false ;; + "possibly-eof") + # Allow empty and/or comment lines at the end + ! tail -n +"$i" "$1" |grep -qvE '^($|#)' + ;; "comment") echo "$line" | grep -Eq "^#"; ;; *) - echo "Unrecognised token $expect" >&2; + complain "Unrecognised token $expect" >&2; quit $err; ;; esac @@ -188,7 +286,7 @@ do in_description=1; ;; "footer") - expecting="footer eof"; + expecting="footer possibly-eof"; if [ "$tickets" = "" ] then tickets="$line"; @@ -199,8 +297,11 @@ do "comment") # Comments should expect the same thing again ;; + "possibly-eof") + expecting="eof"; + ;; *) - echo "Unrecognised token $expect" >&2; + complain "Unrecognised token $expect" >&2; quit 254; ;; esac @@ -214,11 +315,11 @@ do else # None of the expected line formats matched # Guess we'll call it a day here then - echo "Syntax error on line $i:" >&2; - echo ">> $line" >&2; - echo -n "Expecting: " >&2; - echo "$expecting" | sed 's/ /, /g' >&2; - exit $err; + complain "Syntax error on line $i:" >&2; + complain ">> $line" >&2; + complain -n "Expecting: " >&2; + complain "$expecting" | sed 's/ /, /g' >&2; + quit $err; fi i=$(( $i + 1 )); @@ -227,7 +328,7 @@ done # If EOF is expected exit cleanly echo "$expecting" | grep -q "eof" || ( # Unexpected EOF, error - echo "Unexpected EOF encountered" >&2; + complain "Unexpected EOF encountered" >&2; quit $ERR_EOF; ) && ( # Do post scan checks @@ -238,8 +339,8 @@ echo "$expecting" | grep -q "eof" || ( if [ ! -z "$dupes" ] then - echo "The following tickets are repeated:" >&2; - echo "$dupes" | sed 's/ /\n/g;s/^/* /g' >&2; + complain "The following tickets are repeated:" >&2; + complain "$dupes" | sed 's/ /\n/g;s/^/* /g' >&2; quit $ERR_FOOTER; fi fi @@ -247,8 +348,8 @@ echo "$expecting" | grep -q "eof" || ( if [ $ticket -gt 0 ] then echo "$tickets" | grep -Eq "\bPHPBB3-$ticket\b" || ( - echo "Ticket ID [$ticket] of branch missing from list of tickets:" >&2; - echo "$tickets" | sed 's/ /\n/g;s/^/* /g' >&2; + complain "Ticket ID [$ticket] of branch missing from list of tickets:" >&2; + complain "$tickets" | sed 's/ /\n/g;s/^/* /g' >&2; quit $ERR_FOOTER; ) || exit $?; fi diff --git a/git-tools/hooks/pre-commit b/git-tools/hooks/pre-commit index 4d03359773..03babe47cd 100755 --- a/git-tools/hooks/pre-commit +++ b/git-tools/hooks/pre-commit @@ -12,8 +12,17 @@ # ln -s ../../git-tools/hooks/pre-commit \\ # .git/hooks/pre-commit -# NOTE: this is run through /usr/bin/env -PHP_BIN=php +if [ -z "$PHP_BIN" ] +then + PHP_BIN=php +fi + +if [ "$(echo -e test)" = test ] +then + echo_e="echo -e" +else + echo_e="echo" +fi # necessary check for initial commit if git rev-parse --verify HEAD >/dev/null 2>&1 @@ -27,7 +36,7 @@ fi error=0 errors="" -if ! which $PHP_BIN >/dev/null 2>&1 +if ! which "$PHP_BIN" >/dev/null 2>&1 then echo "PHP Syntax check failed:" echo "PHP binary does not exist or is not in path: $PHP_BIN" @@ -64,7 +73,13 @@ do # check the staged file content for syntax errors # using php -l (lint) - result=$(git cat-file -p $sha | /usr/bin/env $PHP_BIN -l 2>/dev/null) + # note: if display_errors=stderr in php.ini, + # parse errors are printed on stderr; otherwise + # they are printed on stdout. + # we filter everything other than parse errors + # with a grep below, therefore it should be safe + # to combine stdout and stderr in all circumstances + result=$(git cat-file -p $sha | "$PHP_BIN" -l 2>&1) if [ $? -ne 0 ] then error=1 @@ -76,7 +91,45 @@ unset IFS if [ $error -eq 1 ] then - echo -e "PHP Syntax check failed:"; - echo -e "$errors" | grep "^Parse error:" + echo "PHP Syntax check failed:" + # php "display errors" (display_errors php.ini value) + # and "log errors" (log_errors php.ini value). + # these are independent settings - see main/main.c in php source. + # the "log errors" setting produces output which + # starts with "PHP Parse error:"; the "display errors" + # setting produces output starting with "Parse error:". + # if both are turned on php dumps the parse error twice. + # therefore here we try to grep for one version and + # if that yields no results grep for the other version. + # + # other fun php facts: + # + # 1. in cli, display_errors and log_errors have different + # destinations by default. display_errors prints to + # standard output and log_errors prints to standard error. + # whether these destinations make sense is left + # as an exercise for the reader. + # 2. as mentioned above, with all output turned on + # php will print parse errors twice, one time on stdout + # and one time on stderr. + # 3. it is possible to set both display_errors and log_errors + # to off. if this is done php will print the text + # "Errors parsing <file>" but will not say what + # the errors are. useful behavior, this. + # 4. on my system display_errors defaults to on and + # log_errors defaults to off, therefore providing + # by default one copy of messages. your mileage may vary. + # 5. by setting display_errors=stderr and log_errors=on, + # both sets of messages will be printed on stderr. + # 6. php-cgi binary, given display_errors=stderr and + # log_errors=on, still prints both sets of messages + # on stderr, but formats one set as an html fragment. + # 7. your entry here? ;) + $echo_e "$errors" | grep "^Parse error:" + if [ $? -ne 0 ] + then + # match failed + $echo_e "$errors" | grep "^PHP Parse error:" + fi exit 1 fi diff --git a/git-tools/hooks/prepare-commit-msg b/git-tools/hooks/prepare-commit-msg index 2bf25e58a4..11d2b6b2f2 100755 --- a/git-tools/hooks/prepare-commit-msg +++ b/git-tools/hooks/prepare-commit-msg @@ -35,8 +35,8 @@ then # Branch is prefixed with 'ticket/', append ticket ID to message if [ "$branch" != "${branch##ticket/}" ]; then - tail="\n\nPHPBB3-${branch##ticket/}"; + tail="$(printf "\n\nPHPBB3-${branch##ticket/}")"; fi - echo "[$branch]$tail $(cat "$1")" > "$1" + echo "[$branch] $tail$(cat "$1")" > "$1" fi |