chiark / gitweb /
2bbfe39c3a5b0df483cc03fa349ece3bd5d700b9
[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-all jenkins-setup-build-environment jenkins-test completion/bash-completion buildserver/provision-*"
15     RB_FILES="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         for name in $@; do
76                 for suff in "3" "-3" "-python3" ""; do
77                         cmd=${name}${suff}
78                         if cmd_exists $cmd; then
79                                 echo $cmd
80                                 return 0
81                         fi
82                 done
83         done
84         warn "$1 is not installed, using dummy placeholder!"
85         echo :
86 }
87
88 DASH=$(find_command dash)
89 PYFLAKES=$(find_command pyflakes)
90 PEP8=$(find_command pycodestyle pep8)
91 RUBY=$(find_command ruby)
92
93 if [ "$PY_FILES $PY_TEST_FILES" != " " ]; then
94     if ! $PYFLAKES $PY_FILES $PY_TEST_FILES; then
95         err "pyflakes tests failed!"
96     fi
97 fi
98
99 if [ "$PY_FILES" != "" ]; then
100     if ! $PEP8 --ignore=$PEP8_IGNORE $PY_FILES; then
101         err "pep8 tests failed!"
102     fi
103 fi
104
105 # The tests use a little hack in order to cleanly import the fdroidserver
106 # package locally like a regular package.  pep8 doesn't see that, so this
107 # makes pep8 skip E402 on the test files that need that hack.
108 if [ "$PY_TEST_FILES" != "" ]; then
109     if ! $PEP8 --ignore=$PEP8_IGNORE,E402 $PY_TEST_FILES; then
110         err "pep8 tests failed!"
111     fi
112 fi
113
114 for f in $SH_FILES; do
115         if ! $DASH -n $f; then
116                 err "dash tests failed!"
117         fi
118 done
119
120 for f in $BASH_FILES; do
121         if ! bash -n $f; then
122                 err "bash tests failed!"
123         fi
124 done
125
126 for f in $RB_FILES; do
127         if ! $RUBY -c $f 1>/dev/null; then
128                 err "ruby tests failed!"
129         fi
130 done
131
132 exit 0