forked from clan/clan-core
53 lines
1.3 KiB
Bash
Executable File
53 lines
1.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Run treefmt on every commit and abort if some files have changed.
|
|
#
|
|
# To install, copy this file to .git/hooks/pre-commit and make sure it's
|
|
# executable.
|
|
#
|
|
set -euo pipefail
|
|
|
|
# Redirect stdout to stderr
|
|
exec 1>&2
|
|
|
|
# Get list of files that will be committed
|
|
mapfile -t commit_files < <(git diff --name-only --cached)
|
|
|
|
log() {
|
|
echo "treefmt pre-commit: $*"
|
|
}
|
|
|
|
# If the commit has no files, skip everything as there is nothing to format
|
|
if [[ -z ${commit_files+x} ]] || [[ ${#commit_files} = 0 ]]; then
|
|
log "no files to format"
|
|
exit 0
|
|
fi
|
|
|
|
# Will be called at the end
|
|
restore_stash() {
|
|
# Store exit status
|
|
local ret=$?
|
|
# Don't fail on error from now on
|
|
set +e
|
|
# Put bash the staged files
|
|
git stash pop -q
|
|
|
|
if [[ $ret -gt 0 ]]; then
|
|
log "aborting commit, detected unformatted files"
|
|
fi
|
|
exit "$ret"
|
|
}
|
|
|
|
# Stash index and work dir, keeping only the to-be-committed changes in
|
|
# the working directory.
|
|
git stash push --quiet --keep-index --message "treefmt pre-commit"
|
|
|
|
# Install the callback to restore the stash on script exit
|
|
trap restore_stash EXIT
|
|
|
|
# Run treefmt on the files in the index and record the result.
|
|
nix fmt -- --no-cache "${commit_files[@]}"
|
|
|
|
# Check if there is a diff
|
|
git diff --name-only --exit-code
|