mirror of
https://github.com/Sea-Haven-Industries/security-review.git
synced 2026-09-30 08:03:17 +00:00
84 lines
3.6 KiB
Bash
84 lines
3.6 KiB
Bash
|
|
#!/usr/bin/env bash
|
||
|
|
# install-hooks.sh — install the Sea Haven security-review git hooks + skill assets.
|
||
|
|
#
|
||
|
|
# Two modes:
|
||
|
|
# install-hooks.sh --global Lay the hooks down once for EVERY repo on this machine:
|
||
|
|
# writes ~/.config/git/hooks/{pre-commit,pre-push}, sets
|
||
|
|
# git config --global core.hooksPath, and links the skill
|
||
|
|
# prompt + finding.schema.json into ~/.claude (Path A).
|
||
|
|
# install-hooks.sh /path/to/repo Per-repo install: copy the hooks into <repo>/.git/hooks
|
||
|
|
# (use when a repo sets its own local core.hooksPath, e.g.
|
||
|
|
# husky, which would otherwise shadow the global hook).
|
||
|
|
# install-hooks.sh --help
|
||
|
|
#
|
||
|
|
# The hooks run review.sh --scanners-only (fast, deterministic). The full agentic review is the
|
||
|
|
# on-demand /sh-security-review skill; the nightly VM sweep is the backstop. Idempotent + re-runnable.
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
SRC="$(cd "$(dirname "$0")" && pwd)"
|
||
|
|
GLOBAL_HOOKS="$HOME/.config/git/hooks"
|
||
|
|
CLAUDE_DIR="$HOME/.claude"
|
||
|
|
|
||
|
|
usage() { grep '^#' "$0" | sed 's/^# \{0,1\}//'; }
|
||
|
|
|
||
|
|
install_one() { # install_one <src-hook> <dest-hook>
|
||
|
|
local src="$1" dest="$2"
|
||
|
|
cp "$src" "$dest"
|
||
|
|
chmod +x "$dest"
|
||
|
|
}
|
||
|
|
|
||
|
|
link_asset() { # link_asset <src-file> <dest-path> (symlink so the repo stays source of truth)
|
||
|
|
local src="$1" dest="$2"
|
||
|
|
mkdir -p "$(dirname "$dest")"
|
||
|
|
ln -sfn "$src" "$dest"
|
||
|
|
echo " linked $dest -> $src"
|
||
|
|
}
|
||
|
|
|
||
|
|
case "${1:-}" in
|
||
|
|
-h|--help|"") usage; exit 0;;
|
||
|
|
|
||
|
|
--global)
|
||
|
|
echo "== Installing Sea Haven security-review hooks globally =="
|
||
|
|
mkdir -p "$GLOBAL_HOOKS"
|
||
|
|
|
||
|
|
# Warn (don't clobber silently) if a different global hooksPath is already set.
|
||
|
|
CURRENT="$(git config --global --get core.hooksPath || true)"
|
||
|
|
if [ -n "$CURRENT" ] && [ "$CURRENT" != "$GLOBAL_HOOKS" ]; then
|
||
|
|
echo " WARNING: git config --global core.hooksPath is already '$CURRENT'." >&2
|
||
|
|
echo " Overwriting it with '$GLOBAL_HOOKS'. Re-point manually if that was intentional." >&2
|
||
|
|
fi
|
||
|
|
|
||
|
|
install_one "$SRC/hooks/pre-commit" "$GLOBAL_HOOKS/pre-commit"
|
||
|
|
install_one "$SRC/hooks/pre-push" "$GLOBAL_HOOKS/pre-push"
|
||
|
|
git config --global core.hooksPath "$GLOBAL_HOOKS"
|
||
|
|
echo " installed pre-commit + pre-push -> $GLOBAL_HOOKS"
|
||
|
|
echo " set git config --global core.hooksPath = $GLOBAL_HOOKS"
|
||
|
|
|
||
|
|
# Path A assets: link the on-demand skill prompt + finding schema into ~/.claude.
|
||
|
|
link_asset "$SRC/skill/sh-security-review.md" "$CLAUDE_DIR/commands/sh-security-review.md"
|
||
|
|
link_asset "$SRC/finding.schema.json" "$CLAUDE_DIR/security-review/finding.schema.json"
|
||
|
|
|
||
|
|
echo
|
||
|
|
echo "Done. Every repo on this machine is now gated by review.sh --scanners-only before push."
|
||
|
|
echo "Caveats: a repo that sets its OWN local core.hooksPath (e.g. husky) overrides this global hook"
|
||
|
|
echo " — run 'install-hooks.sh <that-repo>' to gate it per-repo. Skip a repo with a"
|
||
|
|
echo " .security-review-skip file at its root; bypass once with 'git push --no-verify'."
|
||
|
|
;;
|
||
|
|
|
||
|
|
--*)
|
||
|
|
echo "unknown option: $1" >&2; usage; exit 2;;
|
||
|
|
|
||
|
|
*)
|
||
|
|
REPO="$1"
|
||
|
|
[ -d "$REPO/.git" ] || { echo "not a git repo: $REPO" >&2; exit 1; }
|
||
|
|
echo "== Installing security-review hooks into $REPO/.git/hooks =="
|
||
|
|
for h in pre-commit pre-push; do
|
||
|
|
DEST="$REPO/.git/hooks/$h"
|
||
|
|
[ -f "$DEST" ] && echo " warning: existing $h hook at $DEST will be overwritten" >&2
|
||
|
|
install_one "$SRC/hooks/$h" "$DEST"
|
||
|
|
echo " installed $h -> $DEST"
|
||
|
|
done
|
||
|
|
echo "note: hooks run deterministic scanners only; full review is /sh-security-review (on demand)."
|
||
|
|
;;
|
||
|
|
esac
|