Files
cdk/misc/git-hooks/pre-commit
2024-08-29 11:41:12 +01:00

171 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
set +e
git diff-files --quiet
is_unclean=$?
set -e
# Revert `git stash` on exit
function revert_git_stash {
>&2 echo "Unstashing uncommitted changes..."
git stash pop -q
}
# Stash pending changes and revert them when script ends
if [ -z "${NO_STASH:-}" ] && [ $is_unclean -ne 0 ]; then
>&2 echo "Stashing uncommitted changes..."
GIT_LITERAL_PATHSPECS=0 git stash -q --keep-index
trap revert_git_stash EXIT
fi
export FLAKEBOX_GIT_LS
FLAKEBOX_GIT_LS="$(git ls-files)"
export FLAKEBOX_GIT_LS_TEXT
FLAKEBOX_GIT_LS_TEXT="$(echo "$FLAKEBOX_GIT_LS" | grep -v -E "\.(png|ods|jpg|jpeg|woff2|keystore|wasm|ttf|jar|ico|gif)\$")"
function check_nothing() {
true
}
export -f check_nothing
function check_cargo_fmt() {
set -euo pipefail
flakebox-in-each-cargo-workspace cargo fmt --all --check
}
export -f check_cargo_fmt
function check_cargo_lock() {
set -euo pipefail
# https://users.rust-lang.org/t/check-if-the-cargo-lock-is-up-to-date-without-building-anything/91048/5
flakebox-in-each-cargo-workspace cargo update --workspace --locked |& while read -r note ; do echo "$note (cargo)"; done
}
export -f check_cargo_lock
function check_leftover_dbg() {
set -euo pipefail
errors=""
for path in $(echo "$FLAKEBOX_GIT_LS_TEXT" | grep '.*\.rs'); do
if grep 'dbg!(' "$path" > /dev/null; then
>&2 echo "$path contains dbg! macro"
errors="true"
fi
done
if [ -n "$errors" ]; then
>&2 echo "Fix the problems above or use --no-verify" 1>&2
return 1
fi
}
export -f check_leftover_dbg
function check_semgrep() {
set -euo pipefail
# semgrep is not available on MacOS
if ! command -v semgrep > /dev/null ; then
>&2 echo "Skipping semgrep check: not available"
return 0
fi
if [ ! -f .config/semgrep.yaml ] ; then
>&2 echo "Skipping semgrep check: .config/semgrep.yaml doesn't exist"
return 0
fi
if [ ! -s .config/semgrep.yaml ] ; then
>&2 echo "Skipping semgrep check: .config/semgrep.yaml empty"
return 0
fi
env SEMGREP_ENABLE_VERSION_CHECK=0 \
semgrep -q --error --no-rewrite-rule-ids --config .config/semgrep.yaml
}
export -f check_semgrep
function check_shellcheck() {
set -euo pipefail
for path in $(echo "$FLAKEBOX_GIT_LS_TEXT" | grep -E '.*\.sh$'); do
shellcheck --severity=warning "$path"
done
}
export -f check_shellcheck
function check_trailing_newline() {
set -euo pipefail
errors=""
for path in $(echo "$FLAKEBOX_GIT_LS_TEXT"); do
# extra branches for clarity
if [ ! -s "$path" ]; then
# echo "$path is empty"
true
elif [ -z "$(tail -c 1 < "$path")" ]; then
# echo "$path ends with a newline or with a null byte"
true
else
>&2 echo "$path doesn't end with a newline" 1>&2
errors="true"
fi
done
if [ -n "$errors" ]; then
>&2 echo "Fix the problems above or use --no-verify" 1>&2
return 1
fi
}
export -f check_trailing_newline
function check_trailing_whitespace() {
set -euo pipefail
rev="HEAD"
if ! git rev-parse -q 1>/dev/null HEAD 2>/dev/null ; then
>&2 echo "Warning: no commits yet, checking against --root"
rev="--root"
fi
if ! git diff --check $rev ; then
>&2 echo "Trailing whitespace detected. Please remove them before committing."
return 1
fi
}
export -f check_trailing_whitespace
function check_typos() {
set -euo pipefail
if ! echo "$FLAKEBOX_GIT_LS_TEXT" | typos --file-list - --force-exclude ; then
>&2 echo "Typos found: Valid new words can be added to '.typos.toml'"
return 1
fi
}
export -f check_typos
parallel \
--nonotice \
::: \
check_cargo_fmt \
check_cargo_lock \
check_leftover_dbg \
check_semgrep \
check_shellcheck \
check_trailing_newline \
check_trailing_whitespace \
check_typos \
check_nothing