kingfisher/scripts/kingfisher-pre-commit-auto.sh

136 lines
3.5 KiB
Bash
Executable file

#!/usr/bin/env bash
# Kingfisher pre-commit hook with automatic binary download
# This script downloads the appropriate kingfisher binary if not already cached,
# then runs the scan against staged changes.
set -euo pipefail
REPO="mongodb/kingfisher"
CACHE_DIR="${KINGFISHER_CACHE_DIR:-${XDG_CACHE_HOME:-$HOME/.cache}/kingfisher}"
KINGFISHER_BIN="$CACHE_DIR/kingfisher"
VERSION_FILE="$CACHE_DIR/.version"
# Determine the expected version from the pre-commit rev (passed as env var or default to latest)
EXPECTED_VERSION="${KINGFISHER_VERSION:-latest}"
get_platform() {
local os arch
os="$(uname -s)"
arch="$(uname -m)"
case "$os" in
Linux) platform="linux" ;;
Darwin) platform="darwin" ;;
MINGW*|MSYS*|CYGWIN*) platform="windows" ;;
*) echo "Error: Unsupported OS '$os'" >&2; exit 1 ;;
esac
case "$arch" in
x86_64|amd64) arch_suffix="x64" ;;
arm64|aarch64) arch_suffix="arm64" ;;
*) echo "Error: Unsupported architecture '$arch'" >&2; exit 1 ;;
esac
echo "${platform}-${arch_suffix}"
}
download_kingfisher() {
local platform="$1"
local version="$2"
local ext="tgz"
if [[ "$platform" == windows-* ]]; then
ext="zip"
fi
local asset_name="kingfisher-${platform}.${ext}"
local download_url
if [[ "$version" == "latest" ]]; then
download_url="https://github.com/${REPO}/releases/latest/download/${asset_name}"
else
# Support both "v1.76.0" and "1.76.0" formats
if [[ "$version" != v* ]]; then
version="v${version}"
fi
download_url="https://github.com/${REPO}/releases/download/${version}/${asset_name}"
fi
mkdir -p "$CACHE_DIR"
local tmpdir
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
echo "Downloading kingfisher ($version) for $platform..." >&2
if ! curl -fLsS "$download_url" -o "$tmpdir/$asset_name"; then
echo "Error: Failed to download $download_url" >&2
exit 1
fi
if [[ "$ext" == "zip" ]]; then
unzip -q "$tmpdir/$asset_name" -d "$tmpdir"
local binary_name="kingfisher.exe"
else
tar -C "$tmpdir" -xzf "$tmpdir/$asset_name"
local binary_name="kingfisher"
fi
if [[ ! -f "$tmpdir/$binary_name" ]]; then
echo "Error: Binary not found in downloaded archive" >&2
exit 1
fi
mv "$tmpdir/$binary_name" "$KINGFISHER_BIN"
chmod +x "$KINGFISHER_BIN"
# Store the version we downloaded
if [[ "$version" == "latest" ]]; then
"$KINGFISHER_BIN" --version 2>/dev/null | head -1 > "$VERSION_FILE" || echo "latest" > "$VERSION_FILE"
else
echo "$version" > "$VERSION_FILE"
fi
echo "Kingfisher installed to $KINGFISHER_BIN" >&2
}
needs_download() {
# Binary doesn't exist
if [[ ! -x "$KINGFISHER_BIN" ]]; then
return 0
fi
# No version tracking - always use existing binary for 'latest'
if [[ "$EXPECTED_VERSION" == "latest" ]]; then
return 1
fi
# Check if version matches
if [[ -f "$VERSION_FILE" ]]; then
local installed_version
installed_version="$(cat "$VERSION_FILE")"
# Normalize version format for comparison
local expected_normalized="$EXPECTED_VERSION"
if [[ "$expected_normalized" != v* ]]; then
expected_normalized="v${expected_normalized}"
fi
if [[ "$installed_version" == *"$expected_normalized"* ]] || [[ "$installed_version" == "$EXPECTED_VERSION" ]]; then
return 1
fi
fi
return 0
}
main() {
local platform
platform="$(get_platform)"
if needs_download; then
download_kingfisher "$platform" "$EXPECTED_VERSION"
fi
# Run kingfisher scan on staged changes
exec "$KINGFISHER_BIN" scan . --staged --quiet --no-update-check "$@"
}
main "$@"