-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathpre-commit-checks
executable file
·138 lines (115 loc) · 3.65 KB
/
pre-commit-checks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#! /bin/bash -u
#
# License: GPLv3 or higher
# XXX: Probably want _some_ output while setting up test environment,
# but easy_install, pip install and setup.py install/test/develop
# are all way to verbose, even with --quiet.
flake8="$(git config hooks.flake8 || which flake8 2>/dev/null)"
virtualenv="$(git config hooks.virtualenv || which virtualenv 2>/dev/null)"
FLAKE8_ERROR="Could not find flake8.
Please see README for details, or run:
pip install flake8
in your development VirtualEnv.
"
VIRTUALENV_ERROR="Could not find virtualenv.
Point hooks.virtualenv to the virtualenv executable, or add it to your
PATH. See README for details.
"
die () {
[ -n "${1-}" ] && echo "Error: $1"
exit ${2:-1}
} >&2
debug () {
echo >&2 "$@"
}
# on_exit / add_on_exit code inspired by:
# http://www.linuxjournal.com/content/use-bash-trap-statement-cleanup-temporary-files
declare -a on_exit_items
quoteargs () {
local i str='' singlequote="'\''"
for i; do
str="$str '${i//\'/$singlequote}'"
done
printf %s "${str# }"
}
function on_exit()
{
for i in "${on_exit_items[@]}"
do
eval "$i"
done
}
function add_on_exit()
{
local n=${#on_exit_items[*]}
on_exit_items[$n]="$(quoteargs "$@")"
if [[ $n -eq 0 ]]; then
trap on_exit EXIT
fi
}
### Flake8 checks
# Flake8 (pep8, rather) has a --diff option, but it seems to be flawed
# (did not detect bad indentation, at least). We'll check both HEAD and
# index, and diff the results of those.
# XXX: renames are at the moment treated as all-new material.
flake8_diff () {
# flake8_diff a b
# a and b assumed to be directories
[ -z "${flake8}" ] && {
# XXX: better way to do this?
(die "${FLAKE8_ERROR}")
return $?
}
local a="${1%%/}" b="${2%%/}"
# use cut to trim the directory names (len+2 to get past the slash).
! fgrep -xv -f <($flake8 "${a}" | cut -c "$((${#a}+2))-") \
<($flake8 "${b}" | cut -c "$((${#b}+2))-")
}
### Python testing
# "python setup.py test" is much to verbose about thing not really
# relevant. asd
unittest_discover () {
### unittest_discover scratch_dir project_dir
# initialize virtualenv, easy_install project,
# run "python -m unittest discover" on project with venv python.
[ -z "$virtualenv" ] && {
# XXX: better way to do this?
(die "${VIRTUALENV_ERROR}")
return $?
}
local scratch="${1%%/}" proj="${2%%/}"
local venv="${scratch}/venv" log="${scratch}/log"
debug "Initialize virtualenv"
$virtualenv "$venv" > /dev/null || {
(die "Failed to create virtualenv.")
return $?
}
debug "Install project (will probably take some time)"
"${venv}/bin/easy_install" -Z "${proj}" &> "$log" || {
cat "$log"
(die "Test installation failed.")
return $?
}
"${venv}/bin/python" -m unittest discover -v "$proj"
}
if git rev-parse --verify HEAD &>/dev/null
then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
exec 1>&2
tmpdir="$(mktemp -d --tmpdir)" || die "Failed to create tempdir?!"
add_on_exit rm -rf "$tmpdir"
mkdir "${tmpdir}/old" "${tmpdir}/new"
git checkout-index -q -a --prefix="${tmpdir}/new/"
git archive $against | tar -C "${tmpdir}/old" -x -f -
flake8_diff "${tmpdir}/old" "${tmpdir}/new"
FLAKE8_STATUS=$?
unittest_discover "$tmpdir" "${tmpdir}/new"
TEST_STATUS=$?
# "git diff --check" is not very clear without color, so force color=auto.
git diff-index --check --cached --color=auto $against
[ $? -eq 0 -a $FLAKE8_STATUS -eq 0 -a $TEST_STATUS -eq 0 ] ||
die "You've got some issues to deal with."