-
Notifications
You must be signed in to change notification settings - Fork 1
/
pre-commit.sh
77 lines (67 loc) · 2.27 KB
/
pre-commit.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
#!/usr/bin/env sh
#
# Executes on git commits. Unrelated to the other Bash scripts.
# https://codeinthehole.com/tips/tips-for-using-a-git-pre-commit-hook/
# https://gist.github.com/glfmn/0c5e9e2b41b48007ed3497d11e3dbbfa
#
# Requirements: prettier, shellcheck. Note shfmt is also run in the editor on
# saves.
# Colors
RED='\033[1;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
BOLD='\033[1m'
# Git metadata
BRANCH_NAME=$(git branch | grep '.*' | sed 's/* //')
STASH_NAME="pre-commit-$(date +%s) on ${BRANCH_NAME}"
FILES=$(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g')
[ -z "$FILES" ] && exit 0
echo "* ${BOLD}Checking for unstashed changes:${NC}"
stash=0
# Check to make sure commit isn't empty.
if git diff-index --cached --quiet HEAD --; then
# It was empty, exit with status 0 to let git handle it.
exit 0
else
# Stash changes that aren't added to the staging index so we test only the
# changes to be committed.
old_stash=$(git rev-parse -q --verify refs/stash)
git stash push -q --keep-index -m "$STASH_NAME"
new_stash=$(git rev-parse -q --verify refs/stash)
echo " - Stashed changes as: ${BOLD}${STASH_NAME}${NC}"
if [ "$old_stash" = "$new_stash" ]; then
echo " - no changes, ${YELLOW}skipping tests${NC}"
exit 0
else
stash=1
fi
fi
echo "* ${BOLD}Testing and formatting:${NC}"
# If using mulitple commands, append && to all but the last so if any one fails
# it's accurately represented in the exit code.
echo "$FILES" | xargs prettier --ignore-unknown --write &&
echo "$FILES" | xargs git add &&
shellcheck --check-sourced ./*.sh
# Capture exit code from tests
status=$?
# Inform user of failure.
echo "* ${BOLD}Build status:${NC}"
if [ "$status" -ne "0" ]; then
echo " - ${RED}failed:${NC} if you still want to commit use ${BOLD}'--no-verify'${NC}"
else
echo " - ${GREEN}passed${NC}"
fi
# Revert stash if changes were stashed to restore working directory files.
if [ "$stash" -eq 1 ]; then
echo "* ${BOLD}Restoring working tree${NC}"
if git reset --hard -q &&
git stash apply --index -q &&
git stash drop -q; then
echo " - ${GREEN}restored${NC} ${STASH_NAME}"
else
echo " - ${RED}unable to revert stash command${NC}"
fi
fi
# Exit with exit code from tests, so if they fail, prevent commit.
exit $status