-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
git-pre-commit-hook.sh
executable file
·124 lines (112 loc) · 2.91 KB
/
git-pre-commit-hook.sh
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
#!/usr/bin/env bash
#
# SPDX-FileCopyrightText: Copyright © 2020-2023 Serpent OS Developers
#
# SPDX-License-Identifier: Zlib
#
# Git pre-commit hook for serpent-style'd projects.
#
# Inspired by examples from:
#
# https://codeinthehole.com/tips/tips-for-using-a-git-pre-commit-hook/
#
#set -x
# This assumes that directories ending in .d are never added...
D_FILES='\.d$'
function noisyFail ()
{
# set up terminal colours
BOLDRED="\033[1;31m"
BOLD="\033[1m"
RESET="\033[0m"
if [[ -z "$1" ]]; then
echo ""
echo "${BOLDRED}ERROR:${RESET}${BOLD} No message parameter specified for noisyFail?${RESET}"
echo ""
exit 1
fi
ERRMSG="${BOLDRED}ERROR:${RESET}${BOLD} ${1}${RESET}"
echo ""
echo -e "${ERRMSG}"
echo ""
exit 1
}
function checkForTools ()
{
local TOOLS=(
gawk
grep
sed
xargs
)
local MISSING_TOOLS=""
echo -e "\nChecking for tools used by serpent-style git pre-commit hook..."
for tool in "${TOOLS[@]}"; do
command -v "${tool}" > /dev/null 2>&1
if [[ ! $? -eq 0 ]]; then
MISSING_TOOLS+=" ${tool}\n"
else
echo -e "'- found ${tool}"
fi
done
if [[ ! -z "${MISSING_TOOLS}" ]]; then
noisyFail "
Missing tools:
${MISSING_TOOLS}
Git pre-commit hook aborted.
"
else
echo ""
fi
}
# Ignore vendor code, since we only aim to consume it
#
# Else ignore deleted files in 'git diff --cached --name-only' by adding
# '--diff-filter=d'
#
function rejectForbiddenPatterns ()
{
git diff --cached --name-only --diff-filter=d | \
grep -E "${D_FILES}" | \
grep -Ev '^vendor' | \
xargs gawk -- '
# we need this for exit status
BEGIN { matches = 0; }
function error(msg) {
print FILENAME ":" FNR ":";
print ">" $0 "<";
print ">> " msg "\n";
matches += 1;
}
# Illegal patterns
# only match lines that are not commented out (we use 4 space indents)
# each line of Dlang code is matched against all the patterns below in the order listed
#
# Use a "where, what, how-to-fix (why)" format for usability
# disallow writefln run-time format strings
/^[ ]*writefln\(/ {
error("Use writefln! instead of writefln() (compile time format string check)");
}
# disallow logger run-time format strings
/^[ ]*(log|trace|info|warning|error|critical|fatal)f/ {
error("Use e.g. info(format! instead (compile time format string check)");
}
# buildPath has been shown to be slow
/^[ ]*buildPath/ {
error("Use moss.core.util.joinPath instead of buildPath (speedup)");
}
# exit 1 on illegal patterns found
END {
if (matches != 0) {
print "Found " matches " illegal Dlang patterns.";
exit (matches != 0)
}
}
' \
|| noisyFail "
COMMIT REJECTED
-- Found illegal Dlang code patterns.
>> Please remove them before committing!"
}
# list of enabled functions
checkForTools && rejectForbiddenPatterns