aboutsummaryrefslogblamecommitdiff
path: root/pre-commit
blob: 31fb374984bf49fbb9def1e7c1dfd5526abc738d (plain) (tree)









































































































                                                                              
#!/usr/bin/env bash
# Tom Ryder <tom@sanctum.geek.nz>

# 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))"