chiark / gitweb /
import: fix bitbucket import
[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 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" "-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 PYFLAKES=$(find_command pyflakes)
89 PEP8=$(find_command pycodestyle pep8)
90
91 if [ "$PY_FILES $PY_TEST_FILES" != " " ]; then
92     if ! $PYFLAKES $PY_FILES $PY_TEST_FILES; then
93         err "pyflakes tests failed!"
94     fi
95 fi
96
97 if [ "$PY_FILES" != "" ]; then
98     if ! $PEP8 --ignore=$PEP8_IGNORE $PY_FILES; then
99         err "pep8 tests failed!"
100     fi
101 fi
102
103 # The tests use a little hack in order to cleanly import the fdroidserver
104 # package locally like a regular package.  pep8 doesn't see that, so this
105 # makes pep8 skip E402 on the test files that need that hack.
106 if [ "$PY_TEST_FILES" != "" ]; then
107     if ! $PEP8 --ignore=$PEP8_IGNORE,E402 $PY_TEST_FILES; then
108         err "pep8 tests failed!"
109     fi
110 fi
111
112 for f in $SH_FILES; do
113         if ! dash -n $f; then
114                 err "dash tests failed!"
115         fi
116 done
117
118 for f in $BASH_FILES; do
119         if ! bash -n $f; then
120                 err "bash tests failed!"
121         fi
122 done
123
124 for f in $RB_FILES; do
125         if ! ruby -c $f 1>/dev/null; then
126                 err "ruby tests failed!"
127         fi
128 done
129
130 exit 0