chiark / gitweb /
662e5787f1f8ccf913915609dee4a69133654359
[fdroidserver.git] / hooks / pre-commit
1 #!/bin/bash
2 #
3 # Simple pre-commit hook to check that there are no errors in the fdroidserver
4 # source files.
5
6 # Redirect output to stderr.
7 exec 1>&2
8
9 files=`git diff-index --cached HEAD 2>&1 | sed 's/^:.*     //' | uniq | cut -b100-500`
10 if [ -z "$files" ]; then
11     PY_FILES="fdroid makebuildserver setup.py examples/*.py buildserver/*.py fdroidserver/*.py"
12     PY_TEST_FILES="tests/*.TestCase"
13     SH_FILES="hooks/pre-commit"
14     BASH_FILES="fd-commit jenkins-build docs/update.sh completion/bash-completion buildserver/provision-*"
15     RB_FILES="buildserver/cookbooks/*/recipes/*.rb buildserver/Vagrantfile"
16 else
17     # if actually committing right now, then only run on the files
18     # that are going to be committed at this moment
19     PY_FILES=
20     PY_TEST_FILES=
21     SH_FILES=
22     BASH_FILES=
23     RB_FILES=
24
25     for f in $files; do
26         test -e $f || continue
27         case $f in
28             *.py)
29                 PY_FILES+=" $f"
30                 ;;
31             *.TestCase)
32                 PY_TEST_FILES+=" $f"
33                 ;;
34             *.rb)
35                 RB_FILES+=" $f"
36                 ;;
37             *)
38                 if head -1 $f | grep '^#!/bin/sh' > /dev/null 2>&1; then
39                     SH_FILES+=" $f"
40                 elif head -1 $f | grep '^#!/bin/bash' > /dev/null 2>&1; then
41                     BASH_FILES+=" $f"
42                 elif head -1 $f | grep '^#!.*python' > /dev/null 2>&1; then
43                     PY_FILES+=" $f"
44                 fi
45                 ;;
46         esac
47     done
48 fi
49
50 # We ignore the following PEP8 warnings
51 # * E123: closing bracket does not match indentation of opening bracket's line
52 #   - Broken if multiple indentation levels start on a single line
53 # * E501: line too long (82 > 79 characters)
54 #   - Recommended for readability but not enforced
55 #   - Some lines are awkward to wrap around a char limit
56 # * W503: line break before binary operator
57 #   - Quite pedantic
58
59 PEP8_IGNORE="E123,E501,W503"
60
61 err() {
62         echo >&2 ERROR: "$@"
63         exit 1
64 }
65
66 warn() {
67         echo >&2 WARNING: "$@"
68 }
69
70 cmd_exists() {
71         command -v $1 1>/dev/null
72 }
73
74 find_command() {
75         local name=$1
76         for suff in "3" "-python3" ""; do
77                 cmd=${1}${suff}
78                 if cmd_exists $cmd; then
79                         echo $cmd
80                         return 0
81                 fi
82         done
83         warn "$1 is not installed, using dummy placeholder!"
84         echo -n :
85 }
86
87 PYFLAKES=$(find_command pyflakes)
88 PEP8=$(find_command pep8)
89
90 if [ "$PY_FILES $PY_TEST_FILES" != " " ]; then
91     if ! $PYFLAKES $PY_FILES $PY_TEST_FILES; then
92         err "pyflakes tests failed!"
93     fi
94 fi
95
96 if [ "$PY_FILES" != "" ]; then
97     if ! $PEP8 --ignore=$PEP8_IGNORE $PY_FILES; then
98         err "pep8 tests failed!"
99     fi
100 fi
101
102 # The tests use a little hack in order to cleanly import the fdroidserver
103 # package locally like a regular package.  pep8 doesn't see that, so this
104 # makes pep8 skip E402 on the test files that need that hack.
105 if [ "$PY_TEST_FILES" != "" ]; then
106     if ! $PEP8 --ignore=$PEP8_IGNORE,E402 $PY_TEST_FILES; then
107         err "pep8 tests failed!"
108     fi
109 fi
110
111 for f in $SH_FILES; do
112         if ! dash -n $f; then
113                 err "dash tests failed!"
114         fi
115 done
116
117 for f in $BASH_FILES; do
118         if ! bash -n $f; then
119                 err "bash tests failed!"
120         fi
121 done
122
123 for f in $RB_FILES; do
124         if ! ruby -c $f 1>/dev/null; then
125                 err "ruby tests failed!"
126         fi
127 done
128
129 exit 0