feat(hooks): install missing tools instead of warning

setup-hooks.sh now installs shellcheck, jq, and yq if absent rather
than warning and continuing. Follows the same install pattern as
setup-gitleaks.sh (curl + install to TOOL_INSTALL_DIR=/usr/local/bin,
OS/arch detection, pinned versions).

Pinned versions: shellcheck 0.10.0, jq 1.7.1, yq 4.44.3.

The deployed pre-commit hook retains its runtime fallbacks as a safety
net for environments where tools are removed after setup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TP4EGbBg3XMcyF28Lx78XJ
This commit is contained in:
2026-06-20 22:08:39 +00:00
parent e5a08ebb45
commit 7323aec740
2 changed files with 90 additions and 15 deletions

View File

@@ -6,6 +6,11 @@ set -euo pipefail
# TARGET_REPO — path to the git repo to configure (default: current directory)
# Idempotent: safe to re-run; always replaces each managed block with the current version.
SHELLCHECK_VERSION="0.10.0"
JQ_VERSION="1.7.1"
YQ_VERSION="4.44.3"
TOOL_INSTALL_DIR="${TOOL_INSTALL_DIR:-/usr/local/bin}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TARGET="${1:-$(pwd)}"
MARKER="# managed by setup-hooks.sh"
@@ -16,18 +21,78 @@ if [[ ! -d "$TARGET/.git" ]]; then
exit 1
fi
# --- Tool checks (optional — warn, don't fail) ---
# --- Tool installation ---
warn_if_missing() {
_os() {
case "$(uname -s)" in
Linux) echo "linux" ;;
Darwin) echo "darwin" ;;
*) echo "Error: unsupported OS '$(uname -s)'" >&2; exit 1 ;;
esac
}
_arch() {
case "$(uname -m)" in
x86_64) echo "x86_64" ;;
aarch64 | arm64) echo "aarch64" ;;
*) echo "Error: unsupported architecture '$(uname -m)'" >&2; exit 1 ;;
esac
}
install_shellcheck() {
local os arch tarball url tmp_dir
os="$(_os)"
arch="$(_arch)"
tarball="shellcheck-v${SHELLCHECK_VERSION}.${os}.${arch}.tar.xz"
url="https://github.com/koalaman/shellcheck/releases/download/v${SHELLCHECK_VERSION}/${tarball}"
tmp_dir="$(mktemp -d)"
trap 'rm -rf "$tmp_dir"' RETURN
echo "Installing shellcheck v${SHELLCHECK_VERSION}..."
curl -fsSL "$url" -o "$tmp_dir/$tarball"
tar -xJf "$tmp_dir/$tarball" -C "$tmp_dir" --strip-components=1
install -m 755 "$tmp_dir/shellcheck" "$TOOL_INSTALL_DIR/shellcheck"
echo "Installed: $TOOL_INSTALL_DIR/shellcheck"
}
install_jq() {
local os arch binary url tmp_dir
os="$(_os)"
arch="$(_arch | sed 's/x86_64/amd64/; s/aarch64/arm64/')"
[[ "$(_os)" == "darwin" ]] && os="macos"
binary="jq-${os}-${arch}"
url="https://github.com/jqlang/jq/releases/download/jq-${JQ_VERSION}/${binary}"
tmp_dir="$(mktemp -d)"
trap 'rm -rf "$tmp_dir"' RETURN
echo "Installing jq v${JQ_VERSION}..."
curl -fsSL "$url" -o "$tmp_dir/jq"
install -m 755 "$tmp_dir/jq" "$TOOL_INSTALL_DIR/jq"
echo "Installed: $TOOL_INSTALL_DIR/jq"
}
install_yq() {
local os arch binary url tmp_dir
os="$(_os)"
arch="$(_arch | sed 's/x86_64/amd64/; s/aarch64/arm64/')"
binary="yq_${os}_${arch}"
url="https://github.com/mikefarah/yq/releases/download/v${YQ_VERSION}/${binary}"
tmp_dir="$(mktemp -d)"
trap 'rm -rf "$tmp_dir"' RETURN
echo "Installing yq v${YQ_VERSION}..."
curl -fsSL "$url" -o "$tmp_dir/yq"
install -m 755 "$tmp_dir/yq" "$TOOL_INSTALL_DIR/yq"
echo "Installed: $TOOL_INSTALL_DIR/yq"
}
ensure_tool() {
local tool="$1"
if ! command -v "$tool" &>/dev/null; then
echo "Warning: $tool not installed — ${tool} checks in pre-commit will be skipped (install $tool to enable)" >&2
"install_${tool}"
fi
}
warn_if_missing shellcheck
warn_if_missing jq
warn_if_missing yq
ensure_tool shellcheck
ensure_tool jq
ensure_tool yq
# --- Marker-block helpers ---