#!/usr/bin/env bash # Tom Ryder # Start counting errors declare -i errors # Read records supplied by git diff-index, null-terminated; we only want the # sha1 object name of the staged file while read -r -d '' _ _ _ sha1 _ ; do # git diff-files has a NULL both before and after the filename it prints, # so we need to run read again to get the filename out to move on to the # next record (this is a bit weird, but at least it works) read -r -d '' filename _ # Skip the sha1 if it's empty (which is how diff-index shows deleted files # or moves) if [[ $sha1 != *[^0]* ]] ; then continue fi # Check Bash syntax if [[ $filename == *.bash ]] || \ git cat-file -p "$sha1" | file - | grep -iq 'Bourne-Again' ; then printf 'Checking modified %s ... \n' "$filename" # Check the file with sh -n if ! git cat-file -p "$sha1" | bash -n ; then ((errors++)) continue fi fi # Check shell script syntax if [[ $filename == *.sh ]] || \ git cat-file -p "$sha1" | file - | grep -iq 'POSIX shell' ; then printf 'Checking modified %s ... \n' "$filename" # Check the file with sh -n if ! git cat-file -p "$sha1" | sh -n ; then ((errors++)) continue fi fi # Check HTML syntax if [[ $filename == *.html ]] || \ git cat-file -p "$sha1" | file - | grep -iq html ; then printf 'Checking modified %s ... \n' "$filename" # Check the file with HTML5 tidy(1) if ! git cat-file -p "$sha1" | tidy -eq -utf8 ; then ((errors++)) continue fi fi # Check JS syntax and best practices if [[ $filename == *.js ]] || \ git cat-file -p "$sha1" | file - | grep -iq javascript ; then printf 'Checking modified %s ... \n' "$filename" # Check the file with jslint (which sucks and is bad) if ! jslint <(git cat-file -p "$sha1") ; then ((errors++)) continue fi fi # Check Perl syntax if [[ $filename == *.pl ]] || \ [[ $filename == *.pm ]] || \ git cat-file -p "$sha1" | file - | grep -iq perl ; then printf 'Checking modified %s ... \n' "$filename" # Check the file with perl -c; skip perlcritic if it doesn't pass if ! git cat-file -p "$sha1" | perl -c ; then ((errors++)) continue fi # Check the file with perlcritic --brutal if ! git cat-file -p "$sha1" | perlcritic --brutal ; then ((errors++)) continue fi fi # Check PHP syntax if [[ $filename == *.php ]] || \ git cat-file -p "$sha1" | file - | grep -iq php ; then printf 'Checking modified %s ... \n' "$filename" # Check the file with php -l if ! git cat-file -p "$sha1" | php -l ; then ((errors++)) continue fi fi # Standard input for the while loop is here done < <(git diff-index -z --cached HEAD) # Exit 0 if there were no errors, 1 if there were exit "$((errors > 0))"