-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy pathpre-commit-githook
executable file
·194 lines (178 loc) · 6.99 KB
/
pre-commit-githook
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#!/usr/bin/env bash
#**************************************************************************
#* *
#* OCaml *
#* *
#* David Allsopp, MetaStack Solutions Ltd. *
#* *
#* Copyright 2017 MetaStack Solutions Ltd. *
#* *
#* All rights reserved. This file is distributed under the terms of *
#* the GNU Lesser General Public License version 2.1, with the *
#* special exception on linking described in the file LICENSE. *
#* *
#**************************************************************************
# Bump this on any changes. It's vital that HOOK_VERSION followed by equals
# appears nowhere else in these sources!
HOOK_VERSION=6
# For what it's worth, allow for empty trees!
if git rev-parse --verify HEAD >/dev/null 2>&1
then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
# Redirect output to stderr.
exec 1>&2
# Check to see if the script's been updated
if git ls-files --error-unmatch tools/pre-commit-githook >/dev/null 2>&1 ; then
THEIR_VERSION=$(git cat-file --textconv HEAD:tools/pre-commit-githook \
| sed -ne 's/^HOOK_VERSION=//p')
if [[ -n $THEIR_VERSION && $THEIR_VERSION -gt $HOOK_VERSION ]] ; then
echo "Note: tools/pre-commit-githook is newer than .git/hooks/pre-commit"
echo " You may wish to update your local githook"
fi
fi
# Git's built-in mechanism for whitespace is neater than ours, so do it first.
# The strange construction below creates a list of files which have either
# white-at-eol or white-at-eof included in ocaml-typo in .gitattributes and by
# prefixing the names with :! causes git diff-index to skip over them.
if [[ -n $(git diff-index --cached --name-only $against) ]] ; then
FILES=$(git diff-index --cached --name-only $against \
| xargs git check-attr --cached ocaml-typo \
| sed -ne 's/\(.*\): ocaml-typo:.*[ ,]white-at-eo[fl]\(,\|$\)/:!\1/p')
if ! git diff-index --check --cached $against -- $FILES ; then
exit 1
fi
else
exit 0
fi
# Test to see if any part of the directory name has been marked prune
not_pruned () {
DIR=$(dirname "$1")
if [ "$DIR" = "." ] ; then
return 0
else
case ",$(git check-attr typo.prune "$DIR" | sed -e 's/.*: //')," in
,set,)
return 1
;;
*)
not_pruned "$DIR"
return $?
esac
fi
}
# Now run check-typo over all the files in the index
STATUS=0
export OCAML_CT_PREFIX=:
export OCAML_CT_CAT="git cat-file --textconv"
export OCAML_CT_CA_FLAG=--cached
while IFS= read -r path
do
if not_pruned "$path" && ! tools/check-typo "./$path" ; then
STATUS=1
fi
done < <(git diff --diff-filter=d --staged --name-only)
# If any files affecting the generation of configure have been updated, test
# whether the index includes an up-to-date configure script.
# See also tools/ci/actions/check-configure.sh
AUTOCONF_FILES=\
'configure configure.ac aclocal.m4 build-aux/* '\
'tools/autogen tools/git-dev-options.sh'
# Convert $AUTOCONF_FILES to a BRE
PATHS="${AUTOCONF_FILES//./\\.}"
PATHS="${PATHS//\*/.*}"
PATHS="${PATHS// /\\|}"
OVERRIDE_MESSAGE='(you can override githooks with git-commit --no-verify)'
WRONG_AUTOCONF=0
if git diff --diff-filter=d --staged --name-only | grep -qx "$PATHS" ; then
# Get the AC_PREREQ line in configure.ac for the required autoconf version
PREREQ="$(git cat-file --textconv :configure.ac \
| sed -ne 's/^AC_PREREQ(\[\(.*\)\])/\1/p')"
if [[ -z $PREREQ ]]; then
echo 'Unable to find/parse the AC_PREREQ macro in configure.ac'
echo 'This line should be of the form AC_PREREQ([2.69])'
echo '(with no whitespace or comment)'
STATUS=1
else
# Check for autoconf and its version
AUTOCONF_TOOL='autoconf'
# Check version of autoconf
set -o pipefail
AUTOCONF_VERSION="$($AUTOCONF_TOOL --version 2>/dev/null | head -n 1)"
if [[ $? -ne 0 ]]; then
echo 'Files affecting configure updated, but autoconf not found'
echo 'Unable to verify that configure is up-to-date'
echo "$OVERRIDE_MESSAGE"
STATUS=1
else
AUTOCONF_VERSION="${AUTOCONF_VERSION##* }"
if [[ $AUTOCONF_VERSION != $PREREQ ]]; then
# Found autoconf, but it's the wrong version. If it's older,
# tools/autogen will fail. If it's newer, it may succeed, but CI may
# fail. autoconf is frequently available at an exact version, so try
# the two known names for it.
for tool in $AUTOCONF_TOOL-$PREREQ $AUTOCONF_TOOL$PREREQ; do
VERSION="$($tool --version 2>/dev/null | head -n 1)"
if [[ $? -eq 0 ]]; then
VERSION="${VERSION##* }"
if [[ $VERSION != $PREREQ ]]; then
continue
fi
else
continue
fi
echo "autoconf has version $AUTOCONF_VERSION; using $tool instead"
AUTOCONF_TOOL="$tool"
AUTOCONF_VERSION="$VERSION"
break
done
fi
if [[ $AUTOCONF_VERSION != $PREREQ ]]; then
# We're using the wrong version of autoconf: if all other tests succeed,
# display a warning that CI may complain (CI uses the version specified
# by AC_PREREQ).
WRONG_AUTOCONF=1
fi
# Checkout the relevant files from the index to a temporary directory to
# test them.
BUILD_DIR="$(mktemp -d)"
BUILD_DIR="${BUILD_DIR%%/}/"
if [[ -z $BUILD_DIR ]]; then
echo 'Unable to create a temporary directory to test configure.ac'
STATUS=1
else
git checkout-index --prefix "$BUILD_DIR" -- $AUTOCONF_FILES
pushd "$BUILD_DIR" > /dev/null
mkdir -p a b
mv configure a/
echo 'Regenerating configure...'
if tools/autogen "$AUTOCONF_TOOL"; then
mv configure b/
if diff a/configure b/configure > /dev/null; then
if ((WRONG_AUTOCONF)); then
echo '*** Warning! configure.ac generates the configure script'
echo "*** However, this is using autoconf $AUTOCONF_VERSION"
echo "*** configure.ac requires autoconf $PREREQ; the CI check on"
echo '*** GitHub may fail.'
fi
else
echo 'configure.ac does not appear to generate configure'
echo 'Try running make -B configure and stage the changes'
echo "$OVERRIDE_MESSAGE"
git diff --text --no-index a b
STATUS=1
fi
else
echo 'tools/autogen failed'
STATUS=1
fi
popd > /dev/null
rm -rf "$BUILD_DIR"
fi
fi
fi
fi
exit $STATUS