hastebin/scripts/install-git-hooks.sh

268 lines
6.9 KiB
Bash
Executable File

#!/bin/bash
# Installation script for Git hooks in Hastebin
# This script sets up pre-commit hooks (tests + security scan) and pre-push hooks (unused code + security scan)
#
# Usage:
# ./install-git-hooks.sh [--force]
#
# Options:
# --force Overwrite existing hooks without prompting (backs up existing hooks)
# Without this flag, fails if hooks already exist
set -e
# Parse arguments
FORCE_MODE=false
while [[ $# -gt 0 ]]; do
case $1 in
--force)
FORCE_MODE=true
shift
;;
*)
echo "Unknown option: $1"
echo "Usage: $0 [--force]"
exit 1
;;
esac
done
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Get the repository root
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)")
HOOKS_DIR="$REPO_ROOT/.git/hooks"
PRE_COMMIT_HOOK="$HOOKS_DIR/pre-commit"
PRE_PUSH_HOOK="$HOOKS_DIR/pre-push"
SCRIPT_DIR="$REPO_ROOT/scripts"
echo -e "${BLUE}Installing Git hooks for Hastebin${NC}"
echo ""
# Check if we're in a git repository
if [ ! -d "$REPO_ROOT/.git" ]; then
echo -e "${RED}Error: Not a git repository${NC}"
exit 1
fi
# Create hooks directory if it doesn't exist
mkdir -p "$HOOKS_DIR"
# Function to handle existing hook
handle_existing_hook() {
local hook_path="$1"
local hook_name="$2"
if [ -f "$hook_path" ]; then
if [ "$FORCE_MODE" = true ]; then
# Backup existing hook with timestamp
mv "$hook_path" "$hook_path.backup.$(date +%Y%m%d_%H%M%S)"
echo -e "${YELLOW}Backed up existing $hook_name hook${NC}"
else
echo -e "${RED}Error: $hook_name hook already exists at $hook_path${NC}"
echo -e "${YELLOW}Use --force to overwrite (will backup existing hook)${NC}"
exit 1
fi
fi
}
# Check for existing hooks
handle_existing_hook "$PRE_COMMIT_HOOK" "pre-commit"
handle_existing_hook "$PRE_PUSH_HOOK" "pre-push"
# --- Create the pre-commit hook ---
cat > "$PRE_COMMIT_HOOK" << 'HOOK_EOF'
#!/bin/bash
# Git pre-commit hook for Hastebin
# Runs tests and security scans before allowing commits
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
echo -e "${YELLOW}Running pre-commit checks...${NC}"
echo ""
# Get the repository root
REPO_ROOT=$(git rev-parse --show-toplevel)
cd "$REPO_ROOT"
# Check required dependencies
MISSING_DEPS=0
if ! command -v docker &> /dev/null; then
echo -e "${RED}Docker not found - required for security scanning${NC}"
MISSING_DEPS=1
fi
if ! command -v trivy &> /dev/null; then
echo -e "${RED}Trivy not found - required for security scanning${NC}"
echo " Install: brew install trivy"
MISSING_DEPS=1
fi
if [ $MISSING_DEPS -ne 0 ]; then
echo -e "${RED}Missing required dependencies. Commit aborted.${NC}"
exit 1
fi
# Check if node_modules exists, if not, install dependencies
if [ ! -d "node_modules" ]; then
echo -e "${YELLOW}Installing dependencies...${NC}"
npm ci
fi
# Run the core tests (faster than full test suite)
echo -e "${YELLOW}[1/2] Running core tests...${NC}"
if npm run test:core; then
echo -e "${GREEN}Core tests passed${NC}"
else
echo -e "${RED}Core tests failed. Commit aborted.${NC}"
echo -e "${YELLOW}To skip this check, use: git commit --no-verify${NC}"
exit 1
fi
# Clean up test artifacts
if [ -d "test-data" ]; then
rm -rf test-data
fi
# Run Trivy security scan
echo ""
echo -e "${YELLOW}[2/2] Running security scan (Trivy image scan)...${NC}"
if "$REPO_ROOT/scripts/scan-trivy-image.sh"; then
echo -e "${GREEN}Security scan passed${NC}"
else
echo -e "${RED}Security scan found vulnerabilities. Commit aborted.${NC}"
echo -e "${YELLOW}To skip this check, use: git commit --no-verify${NC}"
exit 1
fi
echo ""
echo -e "${GREEN}Pre-commit checks passed${NC}"
exit 0
HOOK_EOF
chmod +x "$PRE_COMMIT_HOOK"
echo -e "${GREEN}Pre-commit hook installed${NC}"
# --- Create the pre-push hook ---
cat > "$PRE_PUSH_HOOK" << 'HOOK_EOF'
#!/bin/bash
# Git pre-push hook for Hastebin
# Scans for unused code/dependencies and runs security scan before pushing
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
echo -e "${YELLOW}Running pre-push checks...${NC}"
echo ""
# Get the repository root
REPO_ROOT=$(git rev-parse --show-toplevel)
cd "$REPO_ROOT"
# Check required dependencies
MISSING_DEPS=0
if ! command -v docker &> /dev/null; then
echo -e "${RED}Docker not found - required for security scanning${NC}"
MISSING_DEPS=1
fi
if ! command -v trivy &> /dev/null; then
echo -e "${RED}Trivy not found - required for security scanning${NC}"
echo " Install: brew install trivy"
MISSING_DEPS=1
fi
if [ $MISSING_DEPS -ne 0 ]; then
echo -e "${RED}Missing required dependencies. Push aborted.${NC}"
exit 1
fi
# Check if node_modules exists, if not, install dependencies
if [ ! -d "node_modules" ]; then
echo -e "${YELLOW}Installing dependencies...${NC}"
npm ci
fi
# Scan for unused code/dependencies
SCAN_FAILED=0
echo -e "${YELLOW}[1/3] Scanning for unused files/exports/dependencies (knip)...${NC}"
if npx --yes knip 2>/dev/null; then
echo -e "${GREEN}knip passed${NC}"
else
echo -e "${RED}knip found unused code${NC}"
SCAN_FAILED=1
fi
echo ""
echo -e "${YELLOW}[2/3] Scanning for unused npm dependencies (depcheck)...${NC}"
if npx --yes depcheck 2>/dev/null; then
echo -e "${GREEN}depcheck passed${NC}"
else
echo -e "${RED}depcheck found issues${NC}"
SCAN_FAILED=1
fi
if [ $SCAN_FAILED -ne 0 ]; then
echo -e "${RED}Unused code/dependencies detected. Push aborted.${NC}"
echo -e "${YELLOW}To skip this check, use: git push --no-verify${NC}"
exit 1
fi
# Run Trivy security scan
echo ""
echo -e "${YELLOW}[3/3] Running security scan (Trivy image scan)...${NC}"
if "$REPO_ROOT/scripts/scan-trivy-image.sh"; then
echo -e "${GREEN}Security scan passed${NC}"
else
echo -e "${RED}Security scan found vulnerabilities. Push aborted.${NC}"
echo -e "${YELLOW}To skip this check, use: git push --no-verify${NC}"
exit 1
fi
echo ""
echo -e "${GREEN}Pre-push checks passed${NC}"
exit 0
HOOK_EOF
chmod +x "$PRE_PUSH_HOOK"
echo -e "${GREEN}Pre-push hook installed${NC}"
echo ""
echo -e "${BLUE}Hooks installed:${NC}"
echo -e "${BLUE} - pre-commit: core tests + Trivy security scan${NC}"
echo -e "${BLUE} - pre-push: knip + depcheck + Trivy security scan${NC}"
echo -e "${YELLOW}To skip hooks, use: git commit --no-verify / git push --no-verify${NC}"
echo ""
# Check if dependencies are installed
if [ ! -d "$REPO_ROOT/node_modules" ]; then
echo -e "${YELLOW}Dependencies not found. Installing...${NC}"
cd "$REPO_ROOT"
npm ci
echo -e "${GREEN}Dependencies installed${NC}"
fi
echo -e "${GREEN}Git hooks installation complete!${NC}"