Note that exim contains tracker-specific configuration
[mirror/dsa-puppet.git] / DSA-META / pre-commit
1 #!/bin/bash
2
3 if git rev-parse --verify HEAD &>/dev/null; then
4     against=HEAD
5 else
6     # Initial commit: diff against an empty tree object
7     against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
8 fi
9
10 check_puppet_manifest () {
11     local file=$1
12
13     local pp=${workdir}/${file}
14     mkdir -p $(dirname ${pp})
15     git cat-file blob :0:${file} | sed 's/^import .*/#&/' >${pp}
16     trap "rm -f ${pp}" RETURN
17
18     local output=$(puppet apply --noop ${pp} 2>&1)
19     if [ $? -ne 0 ] || [ -n "${output}" ]; then
20         echo '** Syntax check failed:' >&2
21         echo "${output}" >&2
22         return 1
23     fi
24
25     # Check manifests for exactly one class or define per file.
26     case "${file}" in
27         modules/*/manifests/*)
28             if [[ "$(egrep -c '^(class|define) ' ${file})" != "1" ]]; then
29                 echo "** Multiple class/defines:" >&2
30                 egrep -n '^(class|define) ' ${file} >&2
31                 return 1
32             fi
33             ;;
34     esac
35
36     case "${file}" in
37         manifests/site.pp|modules/*/manifests/*) ;;
38         *) return
39     esac
40
41     if [ -x /usr/bin/pcregrep ]; then
42         local wsfail=$({
43             # grep -nPT would be nice. grep -P seems broken on gudeploy01.
44             # Patterns checked for are (in this order):
45             # - leading SPACE
46             # - SPACE followed by TAB
47             # - TAB followed by SPACE
48             # - non-leading TAB (but allow around '#' comment leader)
49             # - trailing whitespace
50             pcregrep -n -e '^ ' -e ' \t' -e '\t ' -e '[^\t#]\t+(?!#)' -e '\s+$' ${pp}
51         })
52         if [[ $(wc -l <${pp}) > $(cat -s ${pp}|wc -l) ]]; then
53             wsfail+="Excess blank line(s). 'cat -s' is your friend."
54         fi
55         if [[ -n "${wsfail}" ]]; then
56             echo '** Bad whitespace (see Manifest Standards):' >&2
57             echo "${wsfail}" >&2
58             return 1
59         fi
60     else
61         echo "Missing pcregrep: apt-get install pcregrep" >&2
62     fi
63
64     case "${file}" in
65         manifests/site.pp|modules/*/manifests/*)
66             puppet-lint --no-hard_tabs-check --no-80chars-check ${pp} >&2 | uniq
67             ;;
68         *)
69             return
70             ;;
71     esac
72
73     return 0
74 }
75
76 # Check a Puppet template.
77 #
78 check_puppet_template () {
79     local file=$1
80
81     # Beware of 'Syntax OK' message on success.
82     local output=$((git cat-file blob :0:${file}|erb -x -P -T -|ruby -c >/dev/null) 2>&1)
83     if [[ $? -ne 0 || -n "${output}" ]]; then
84         echo '** Syntax check failed:' >&2
85         echo "${output}" >&2
86         return 1
87     fi
88
89     return 0
90 }
91
92 readonly failed=$(mktemp ${TMPDIR:-/tmp}/git.puppet.pre-commit.XXXXXXXXXX)
93 readonly missing=$(mktemp ${TMPDIR:-/tmp}/git.puppet.pre-commit.XXXXXXXXXX)
94 readonly parse=$(mktemp ${TMPDIR:-/tmp}/git.puppet.pre-commit.XXXXXXXXXX)
95 readonly retest=$(mktemp ${TMPDIR:-/tmp}/git.puppet.pre-commit.XXXXXXXXXX)
96 readonly workdir=$(mktemp -d ${TMPDIR:-/tmp}/git.puppet.pre-commit.XXXXXXXXXX)
97 trap "rm -f ${failed} ${missing} ${parse} ${retest}; rm -rf ${workdir}" EXIT
98
99 error=0
100 warning=0
101 for file in $(git diff-index --name-only --diff-filter=AM --cached ${against}); do
102     output=""
103     rc=0
104
105     case "${file}" in
106         manifests/site.pp)
107             output=$(check_puppet_manifest ${file} 2>&1); rc=$?;;
108         modules/*)
109
110             case "${file}" in
111                 modules/*/manifests/*)
112                     case "${file}" in
113                         # FIXME: doing this so the whitespace check happens
114                         *.pp) output=$(check_puppet_manifest ${file} 2>&1); rc=$?;;
115                     esac
116                     ;;
117                 modules/*/templates/*)
118                     output=$(check_puppet_template ${file} 2>&1); rc=$?;;
119             esac
120             ;;
121
122     esac
123
124     if [[ ${rc} -ne 0 || -n "${output}" ]]; then
125         echo "** ${file}" >&2
126         echo "${output}" >&2
127         if [[ ${file} != *.pp ]]; then
128             error=1
129         # puppet-lint warnings are acceptable.
130         elif [[ -n "$(egrep -v '^WARNING: ' <<<${output})" ]]; then
131             error=1
132         else
133             warning=1
134         fi
135     fi
136 done
137
138 if [ "$error" -ne 0 ]; then
139     echo "** Please correct the above errors." >&2
140     exit 1
141 fi
142
143 if [ "$warning" -ne 0 ]; then
144     sleep 5
145 fi
146
147 exit 0