#!/bin/bash if [ "x$SKIP_LINT" != "x" ]; then echo "SKIP_LINT set in environment, skipping Puppet syntax checks" exit fi TERM=${TERM:-unknown}; export TERM git_root=$(git rev-parse --show-toplevel) failures=0 RC=0 hook_dir="$(dirname "$0")" hook_symlink="$(readlink "$0")" # Manage arguments passed to script while getopts ":a" o; do case "${o}" in a) CHECK_ALL=true;; s) export ERRORS_ONLY=true;; esac done # Figure out where commit hooks are if [[ ! -z "$hook_symlink" ]] && ! [[ "$hook_symlink" == ../* ]]; then #pre-commit is setup as a symlink subhook_root="$(dirname "$hook_symlink")/commit_hooks" else #commit_hooks should be with pre-commit subhook_root="${hook_dir}/commit_hooks" fi # If using submodules, we need to read proper subhook root if [[ -f "${git_root}/.git" ]]; then IFS=": " while read -r name value do if [[ "$name" == "gitdir" ]]; then submodule_hookdir="$value" fi done < "${git_root}/.git" if [[ ! -z "$submodule_hookdir" ]]; then subhook_root="${git_root}/${submodule_hookdir}/hooks/commit_hooks" fi fi # Decide if we want puppet-lint CHECK_PUPPET_LINT=${CHECK_PUPPET_LINT:-"enabled"} if [[ -e ${subhook_root}/config.cfg ]] ; then source "${subhook_root}/config.cfg" fi # Only puppet 3.2.1 - 3.8 support "--parser future" option. if [[ "$USE_PUPPET_FUTURE_PARSER" == "enabled" ]]; then case $(puppet --version) in 3.2.[1-9]) ;; 3.[3-8]*) ;; *) USE_PUPPET_FUTURE_PARSER="disabled" ;; esac fi SAVEIFS=$IFS IFS=$(echo -en "\n\b") if [ $CHECK_ALL ]; then files_to_check=$(find "$git_root" -path "${git_root}/.git" -prune -o -print) else files_to_check=$(git diff --cached --name-only --diff-filter=ACM) fi # On cygwin/windows, puppet is a symlink to native puppet install, which needs windows paths. if [[ "$OSTYPE" == "cygwin" ]] && file -L $(which puppet) 2>/dev/null | grep -q 'DOS batch file' && type cygpath >/dev/null 2>&1; then USE_NATIVE="YES" fi for changedfile in $files_to_check; do [[ -f "$changedfile" ]] || continue if [ "$USE_NATIVE" == "YES" ]; then changedfile_native="`cygpath -w "$changedfile"`" else changedfile_native="$changedfile" fi #check puppet manifest syntax if type puppet >/dev/null 2>&1; then if echo "$changedfile" | grep -iq '\.epp$'; then ${subhook_root}/puppet_epp_syntax_check.sh "$changedfile" RC=$? if [[ "$RC" -ne 0 ]]; then failures=$((failures + 1)) fi elif echo "$changedfile" | grep -iq '\.pp$'; then ${subhook_root}/puppet_manifest_syntax_check.sh "$changedfile_native" "$USE_PUPPET_FUTURE_PARSER" RC=$? if [[ "$RC" -ne 0 ]]; then failures=$((failures + 1)) fi fi else echo "puppet not installed. Skipping puppet syntax checks..." fi if type ruby >/dev/null 2>&1; then #check erb (template file) syntax if type erb >/dev/null 2>&1; then if echo "$changedfile" | grep -iq '\.erb$'; then ${subhook_root}/erb_template_syntax_check.sh "$changedfile" RC=$? if [[ "$RC" -ne 0 ]]; then failures=$((failures + 1)) fi fi else echo "erb not installed. Skipping erb template checks..." fi #check json (i.e. metadata.json) syntax if echo "$changedfile" | grep -iq '\.json$'; then ${subhook_root}/json_syntax_check.sh "$changedfile" RC=$? if [[ "$RC" -ne 0 ]]; then failures=$((failures + 1)) fi fi else echo "ruby not installed. Skipping erb/json checks..." fi if type yamllint >/dev/null 2>&1 || type ruby >/dev/null 2>&1; then #check hiera data (yaml/yml/eyaml/eyml) syntax if echo "$changedfile" | grep -iq '\.e\?ya\?ml$'; then ${subhook_root}/yaml_syntax_check.sh "$changedfile" RC=$? if [[ "$RC" -ne 0 ]]; then failures=$((failures + 1)) fi fi else echo "yamllint nor ruby not installed. Skipping yaml checks..." fi #puppet manifest styleguide compliance if [[ "$CHECK_PUPPET_LINT" != "disabled" ]] ; then if type puppet-lint >/dev/null 2>&1; then if echo "$changedfile" | grep -iq '\.pp$'; then if [[ "$failures" -eq 0 ]]; then ${subhook_root}/puppet_lint_checks.sh "$CHECK_PUPPET_LINT" "$changedfile" RC=$? if [[ "$RC" -ne 0 ]]; then failures=$((failures + 1)) fi else echo "Skipping puppet-lint check due to prior errors." fi fi else echo "puppet-lint not installed. Skipping puppet-lint tests..." fi fi #puppet manifest documentation checks if [[ "$CHECK_PUPPET_DOCS" != "disabled" ]] ; then if puppet strings >/dev/null 2>&1; then if echo "$changedfile" | grep -iq '\.pp$'; then ${subhook_root}/puppet_manifest_documentation_check.sh "$CHECK_PUPPET_DOCS" "$changedfile" RC=$? if [[ "$RC" -ne 0 ]]; then failures=$((failures + 1)) fi fi else echo "puppet strings not installed. Skipping puppet documentation checks..." fi fi done IFS=$SAVEIFS #rspec test validation if [[ "$CHECK_RSPEC" != "disabled" ]] ; then if hash rspec >/dev/null 2>&1; then ${subhook_root}/rspec_puppet_checks.sh RC=$? if [[ "$RC" -ne 0 ]]; then failures=$((failures + 1)) fi else echo "rspec not installed. Skipping rspec-puppet tests..." fi fi #r10k puppetfile syntax check if [[ "$CHECK_R10K" != "disabled" ]] ; then if hash r10k >/dev/null 2>&1; then if [[ "$changedfile" = "Puppetfile" ]]; then "${subhook_root}/r10k_syntax_check.sh" RC=$? if [[ "$RC" -ne 0 ]]; then failures=$((failures + 1)) fi fi else echo "r10k not installed. Skipping r10k Puppetfile test..." fi fi #summary if [[ "$failures" -ne 0 ]]; then echo -e "$(tput setaf 1)Error: ${failures} subhooks failed. Please fix above errors.$(tput sgr0)" exit 1 fi exit 0