Skip to content

Instantly share code, notes, and snippets.

@mariuswilms
Last active May 19, 2022 09:36
Show Gist options
  • Save mariuswilms/2765716 to your computer and use it in GitHub Desktop.
Save mariuswilms/2765716 to your computer and use it in GitHub Desktop.
Git pre-commit Hook
#!/bin/bash
#
# Language agnostic GIT pre commit hook.
#
# Copyright (c) 2013 Marius Wilms.
# All rights reserved.
#
# Distributed under the terms of the BSD 3-clause license. Redistributions
# of this file must retain the above copyright notice. For the full license
# text see: http://opensource.org/licenses/BSD-3-Clause.
#
# Detection for non-ASCII characters based upon
# https://gist.github.com/2587900 by Brent Sowers.
#
EXIT=0
JS_LINTER=""
which jshint > /dev/null
if [[ $? != 0 ]]; then
JS_LINTER="jshint"
fi
which eslint > /dev/null
if [[ $? != 0 ]]; then
JS_LINTER="eslint"
fi
if [[ $JS_LIKNTER == "" ]]; then
ENABLE_LINT_JS="n"
else
ENABLE_LINT_JS="y"
fi
which msgfmt > /dev/null
if [[ $? != 0 ]]; then
ENABLE_LINT_PO="n"
else
ENABLE_LINT_PO="y"
fi
echo "Pre-commit hook started."
echo
# Determine current revision
if git-rev-parse --verify HEAD >/dev/null 2>&1; then
AGAINST=HEAD
else
# Initial commit; diff against an empty tree object
AGAINST=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
FILES=$(git diff-index --cached --name-only --diff-filter=AM ${AGAINST})
NUMFILES=$(echo $FILES | grep -o ' ' | wc -l | awk '{print $1}')
if [[ $NUMFILES -gt 30 ]]; then
echo "Too many files ($NUMFILES) to check. Try --no-verify"
exit 1
fi
echo "Checking $NUMFILES files..."
for FILE in $FILES; do
if [ ! -f $FILE ]; then
# Do not check directories.
continue
fi
echo "------------------------------------------------------------"
echo "Checking: ${FILE}"
# Non-ASCII characters
# OUT=$(cat $FILE | tr -d "\000-\011\013-\177" | tr -d '\n')
# if [ -n "$OUT" ]; then
# for ((I=0; I < ${#OUT}; I++)); do
# CHAR=${OUT:$I:1}
# echo "Non-ASCII characters \`$CHAR\` found:"
# git diff HEAD -S$CHAR -- $FILE
# done
# EXIT=1
# fi
grep -E '^#!.*bash' $FILE > /dev/null
ISNT_BASH=$?
# Syntax check
if [ $(echo $FILE | grep -E '\.(php|ctp)$') ]; then
DEBUG=$(grep --line-number -E '(var_dump\|die\(|die;)' $FILE)
if [[ $? == 0 ]]; then
echo "Found debug code!"
echo $DEBUG
EXIT=1
fi
# PHP, CakePHP Templates
php -l $FILE 2>/dev/null
elif [ $(echo $FILE | grep -E '\.(js)$') ]; then
DEBUG=$(grep --line-number -E 'console\.(debug|log)\(' $FILE)
if [[ $? == 0 ]]; then
echo "Found debug code!"
echo $DEBUG
EXIT=1
fi
# JavaScript
if [[ $ENABLE_LINT_JS == "y" ]]; then
$JS_LINTER $FILE 2>&1
fi
elif [ $ISNT_BASH = 0 ]; then
# BASH
bash -n $FILE
elif [ $(echo $FILE | grep -E '\.po$') ]; then
# GNU Gettext
# POT files wont pass validation as they often contain
# fuzzy headers. So we only check PO files here.
if [[ $ENABLE_LINT_PO == "y" ]]; then
msgfmt -c $FILE
fi
fi
if [ $? != 0 ]; then
EXIT=1
fi
done
echo
echo "============================================================"
if [ $EXIT != 0 ]; then
echo "Pre-commit hook failed."
echo
echo "Fix the issues detected above then try to commit your"
echo "changes again. You can prevent the hook from running"
echo "by using the \`--no-verify\` option with \`git commit\`."
else
echo "Pre-commit hook succeeded."
fi
echo
exit $EXIT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment