#!/bin/bash warned=0 final_ret=0 # Check for ruby binary which ruby >/dev/null 2>&1 if [[ $? -ne 0 ]]; then echo "Ruby not found" 1>&2 exit 1 fi # Check for Puppet binary which puppet >/dev/null 2>&1 if [[ $? -ne 0 ]]; then echo "Puppet not found" 1>&2 exit 1 fi # Check for puppet-lint which puppet-lint >/dev/null 2>&1 if [[ $? -ne 0 ]]; then echo "puppet-lint not found" 1>&2 exit 1 fi # Check for erb which erb >/dev/null 2>&1 if [[ $? -ne 0 ]]; then echo "erb not found" 1>&2 exit 1 fi if [[ "x${HOME}" == "x" ]]; then id=`whoami` HOME=`eval echo ~${id}` export HOME fi styleguide_url='http://docs.puppetlabs.com/guides/style_guide.html' git cat-file -e $newrev:.puppetstyle.url >/dev/null 2>&1 if [[ $? -eq 0 ]]; then styleguide_url=$(git show $newrev:.puppetstyle.url) fi tmpdir=`mktemp -d` tmpfile="$tmpdir/candidate" while read oldrev newrev refname; do # Grab a copy of .puppet-lint.rc from this ref if it exists, # and use it to disable lint checks # puppet-lint > 1.0 will let us choose a unique location for the config file # for now we're dropping it into git bare .git repo, non-fatal race condition git cat-file -e $newrev:.puppet-lint.rc && git show $newrev:.puppet-lint.rc > .puppet-lint.rc # Retrieve a list of all modified files as part of this push # We'll only check the latest revisionso that things that were broken but then fixed # can be pushed. As such, strip out any duplicates, where the same file was changed # in multiple commits for puppetmodule in `git diff-tree --no-commit-id --diff-filter=ACM --name-only -r "$oldrev" "$newrev" | sort | uniq`; do # Retrieve the latest version of the changed file git show $newrev:$puppetmodule > $tmpfile case $puppetmodule in *.pp ) puppet parser validate $tmpfile rc=$? if [[ $rc != 0 ]]; then echo -e "\e[0;31m'puppet parser validate' failed on $puppetmodule - push denied. Run tests locally and confirm they pass before pushing. \e[0m" final_ret=1 fi puppet-lint $tmpfile rc=$? if [[ $rc != 0 ]]; then if [[ $warned = 0 ]]; then echo -e "\e[0;33m" "Please follow the puppet module styleguide (${styleguide_url})." "\e[0m" echo -e "\e[0;33m" "The above ERROR/WARNING messages are informational only. The commit has not been blocked for this reason. In the future, these may cause your commit to be refused." "\e[0m" warned=1 fi echo -e "\e[0;33m" "Style guide compliance errors in $puppetmodule:" "\e[0m" fi ;; *.erb ) cat $tmpfile | erb -x -T - | ruby -c 2>&1 >/dev/null rc=$? if [[ $rc != 0 ]]; then echo -e "\e[0;31m" "Ruby syntax checker failed on template $puppetmodule:" "\e[0m" final_ret=1 fi ;; *.yml|*.yaml) # syntax YAML files, https://ttboj.wordpress.com/2013/08/25/finding-yaml-errors-in-puppet/ ruby -ryaml -e "YAML.parse(File.open('${tmpfile}'))" if [[ $? -ne 0 ]]; then echo -e "\e[0;31m" "YAML syntax error in ${puppetmodule}" "\e[0m" final_ret=1 fi ;; *.json) ruby -rrubygems -e "require 'json'; JSON.parse(File.open('${tmpfile}').read)" if [[ $? -ne 0 ]]; then echo -e "\e[0;31m" "JSON syntax error in ${puppetmodule}" "\e[0m" final_ret=1 fi ;; esac done done rm -rf $tmpdir exit $final_ret