just: Introduce pre-commit and pre-push installer
Copies the template script into the git hooks DIR to prevent a potential attacker overwriting its contents. Also introduces a check before running the hook against sensitive files from `master`, if there are changes between the branch and `master`, asks user to confirm continuation of hook execution.
This commit is contained in:
parent
576bc6d6af
commit
bdb2a1fc7f
14
justfile
14
justfile
|
|
@ -1,6 +1,20 @@
|
|||
default:
|
||||
@just --list
|
||||
|
||||
# SECURITY: We COPY the hook template instead of symlinking it. This ensures that
|
||||
# checking out an untrusted patch won't overwrite your local git hooks. The copied
|
||||
# script also checks if sensitive files (like build.rs or justfile) were modified
|
||||
# in the patch and prompts for confirmation, preventing arbitrary code execution.
|
||||
#
|
||||
# Install git hooks
|
||||
[group('hooks')]
|
||||
install-hooks:
|
||||
@cp scripts/git-hook-template.sh .git/hooks/pre-commit
|
||||
@chmod +x .git/hooks/pre-commit
|
||||
@cp scripts/git-hook-template.sh .git/hooks/pre-push
|
||||
@chmod +x .git/hooks/pre-push
|
||||
@echo "✅ pre-commit and pre-push hooks installed."
|
||||
|
||||
# Run pre-commit checks
|
||||
[group('hooks')]
|
||||
pre-commit: format-rust check-rust check-docs check-typos check-spelling check-scripts check-keywords format-nix
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
#! /usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
readonly HOOK_NAME="$(basename "$0")"
|
||||
|
||||
if ! [[ "$HOOK_NAME" =~ ^(pre-(commit|push)|post-checkout)$ ]]
|
||||
then
|
||||
echo "Unknown hook '${HOOK_NAME}'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
readonly SENSITIVE_FILES=("justfile" "build.rs" "rust-toolchain.toml")
|
||||
readonly BASE_BRANCH="master"
|
||||
|
||||
# Check which files were modified compared to the base branch.
|
||||
mapfile -t CHANGED_FILES < <(comm -12 \
|
||||
<(git diff --name-only "${BASE_BRANCH}" | sort) \
|
||||
<(IFS=$'\n'; echo "${SENSITIVE_FILES[*]}" | sort) \
|
||||
)
|
||||
|
||||
if [ ${#CHANGED_FILES[@]} -gt 0 ]; then
|
||||
echo "⚠️ WARNING: Sensitive files have been modified relative to $BASE_BRANCH."
|
||||
echo "Executing this hook may run arbitrary code from the modified files."
|
||||
echo ""
|
||||
|
||||
git --no-pager diff "$BASE_BRANCH" -- "${SENSITIVE_FILES[@]}"
|
||||
|
||||
# Read from /dev/tty because stdin is not attached to the terminal in Git hooks.
|
||||
exec < /dev/tty
|
||||
|
||||
read -r -p "Do you want to continue executing the ${HOOK_NAME} hooks? [y/N] " response
|
||||
case "$response" in
|
||||
[yY][eE][sS]|[yY])
|
||||
echo "Continuing with '${HOOK_NAME}' hook..."
|
||||
;;
|
||||
*)
|
||||
echo "Skipping '${HOOK_NAME}' hook."
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Execute the appropriate just recipe based on the hook name
|
||||
if [ "$HOOK_NAME" = "pre-commit" ]; then
|
||||
echo "Running pre-commit checks..."
|
||||
just pre-commit
|
||||
elif [ "$HOOK_NAME" = "pre-push" ]; then
|
||||
echo "Running pre-push checks..."
|
||||
just pre-push
|
||||
else
|
||||
echo "Unknown hook: $HOOK_NAME"
|
||||
exit 1
|
||||
fi
|
||||
Loading…
Reference in New Issue