git pre-commit hook for puppet, erb and yaml files

 · Systeemkabouter

A pre-commit hook is a great way to run custom actions before handing over your work to GIT (and thus your CI tool chain). For puppet related GIT repositories I’ve assembled a pre-commit hook that checks the puppet code, changed ERB templates and any changed YAML files for formatting errors.

All not rocket science when put together, but a great time saver nonetheless. I never fly without it these days. Just paste the code block below in your [GITREPO]/.git/hooks/pre-commit and make sure the result is executable for your own account. The code is just bits that I pieced together.

There are a few dependencies that you might have to install depending on your platform.

#!/bin/bash
# Requires bash, as it uses the [[ ]] syntax.
#
# https://puppetlabs.com/blog/using-puppet-lint-to-save-yourself-from-style-faux-pas
# https://docs.puppetlabs.com/guides/templating.html#syntax-checking
#
# If it's puppet code, lint it up.

# If we don't have puppet-lint, so just exit and leave them be.
which puppet-lint >/dev/null 2>&1 || exit

# 20150915 syncaddict
# - Added support for erb syntax checking
#
# 20151020 syncaddict
# - Added support for YAML syntax checking
# - more verbose operation
#
# Variables goes hither

declare -a FILES
IFS="
"
FILES=$(git diff --cached --name-only --diff-filter=ACM )


for file in ${FILES[@]}
do
case $file in
*\.pp*)
echo "Checking puppet file $file"
puppet-lint --no-puppet_url_without_modules-check --no-80chars-check --fix --with-filename "$file"
RC=$?
if [ $RC -ne 0 ]; then exit $RC;fi

      puppet parser validate "$file"
      RC=$?
      if [ $RC -ne 0 ]; then exit $RC;fi
    ;;
    *\.erb*)
      echo "Checking erb template $file"
      erb -P -x -T '-' $file | ruby -c
      RC=$?
      if [ $RC -ne 0 ]; then exit $RC;fi
    ;;
    *\.yaml*)
      echo "Checking yaml file $file"
      ruby -e "require 'yaml'; YAML.load_file('$file')"
      RC=$?
      if [ $RC -ne 0 ]; then exit $RC;fi
    ;;
    *)
      echo "Not checking file $file"
    ;;
esac
done

exit 0