forked from mirrors/kingfisher
136 lines
3.5 KiB
Bash
Executable file
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 "$@"
|