checks - Replace npm commands with bun/bunx in scripts, docs, and CI - Add enhanced pre-commit checks with parallel execution - Document pre-commit hook behavior in PRE_COMMIT_HOOKS.md - Update .gitignore/.dockerignore for bun-debug.log - Refine ESLint config for bun and Prettier integration - Add scripts/type-check-staged.sh for fast staged type checks - Improve developer workflow and code quality automation
171 lines
5.1 KiB
Bash
Executable File
171 lines
5.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Enhanced pre-commit checks with parallel execution for speed
|
|
# This script runs multiple checks efficiently on staged files only
|
|
|
|
set -e
|
|
|
|
echo "🚀 Running pre-commit checks..."
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Function to print colored output
|
|
print_status() {
|
|
echo -e "${BLUE}[PRE-COMMIT]${NC} $1"
|
|
}
|
|
|
|
print_success() {
|
|
echo -e "${GREEN}✅${NC} $1"
|
|
}
|
|
|
|
print_error() {
|
|
echo -e "${RED}❌${NC} $1"
|
|
}
|
|
|
|
print_warning() {
|
|
echo -e "${YELLOW}⚠️${NC} $1"
|
|
}
|
|
|
|
# Check if there are any staged files
|
|
STAGED_FILES=$(git diff --cached --name-only)
|
|
if [ -z "$STAGED_FILES" ]; then
|
|
print_warning "No staged files found"
|
|
exit 0
|
|
fi
|
|
|
|
print_status "Found $(echo "$STAGED_FILES" | wc -l) staged files"
|
|
|
|
# Create temporary directory for parallel job management
|
|
TEMP_DIR=$(mktemp -d)
|
|
trap "rm -rf $TEMP_DIR" EXIT
|
|
|
|
# Function to run a command and capture its output
|
|
run_check() {
|
|
local name="$1"
|
|
local command="$2"
|
|
local output_file="$TEMP_DIR/$name.out"
|
|
local error_file="$TEMP_DIR/$name.err"
|
|
|
|
{
|
|
echo "Running: $command"
|
|
eval "$command" > "$output_file" 2> "$error_file"
|
|
echo $? > "$TEMP_DIR/$name.exit"
|
|
} &
|
|
|
|
echo $! > "$TEMP_DIR/$name.pid"
|
|
}
|
|
|
|
# Start parallel checks
|
|
print_status "Starting parallel checks..."
|
|
|
|
# 1. Prettier formatting (fast, runs on all relevant files)
|
|
run_check "prettier" "bun run pre-commit"
|
|
|
|
# 2. ESLint on staged JS/TS files only
|
|
STAGED_JS_TS_FILES=$(echo "$STAGED_FILES" | grep -E '\.(js|jsx|ts|tsx)$' || true)
|
|
if [ -n "$STAGED_JS_TS_FILES" ]; then
|
|
run_check "eslint" "bunx eslint --fix --max-warnings 0 $STAGED_JS_TS_FILES"
|
|
else
|
|
echo "0" > "$TEMP_DIR/eslint.exit"
|
|
echo "No JS/TS files to lint" > "$TEMP_DIR/eslint.out"
|
|
fi
|
|
|
|
# 3. TypeScript type checking on staged files
|
|
STAGED_TS_FILES=$(echo "$STAGED_FILES" | grep -E '\.(ts|tsx)$' || true)
|
|
if [ -n "$STAGED_TS_FILES" ]; then
|
|
run_check "typecheck" "./scripts/type-check-staged.sh"
|
|
else
|
|
echo "0" > "$TEMP_DIR/typecheck.exit"
|
|
echo "No TypeScript files to check" > "$TEMP_DIR/typecheck.out"
|
|
fi
|
|
|
|
# 4. Markdown linting on staged markdown files
|
|
STAGED_MD_FILES=$(echo "$STAGED_FILES" | grep -E '\.md$' || true)
|
|
if [ -n "$STAGED_MD_FILES" ]; then
|
|
run_check "markdown" "bunx markdownlint-cli2 --fix $STAGED_MD_FILES || echo 'Markdown linting failed but continuing...'"
|
|
else
|
|
echo "0" > "$TEMP_DIR/markdown.exit"
|
|
echo "No markdown files to lint" > "$TEMP_DIR/markdown.out"
|
|
fi
|
|
|
|
# 5. Secret scanning on staged files (optional check)
|
|
if command -v secretlint > /dev/null; then
|
|
run_check "secrets" "bunx secretlint $STAGED_FILES || echo 'Secret scanning failed but continuing...'"
|
|
else
|
|
echo "0" > "$TEMP_DIR/secrets.exit"
|
|
echo "secretlint not available, skipping secret scanning" > "$TEMP_DIR/secrets.out"
|
|
fi
|
|
|
|
# Wait for all jobs to complete and collect results
|
|
print_status "Waiting for checks to complete..."
|
|
|
|
FAILED_CHECKS=()
|
|
ALL_CHECKS=("prettier" "eslint" "typecheck" "markdown" "secrets")
|
|
|
|
for check in "${ALL_CHECKS[@]}"; do
|
|
if [ -f "$TEMP_DIR/$check.pid" ]; then
|
|
wait $(cat "$TEMP_DIR/$check.pid") 2>/dev/null || true
|
|
fi
|
|
|
|
exit_code=$(cat "$TEMP_DIR/$check.exit" 2>/dev/null || echo "1")
|
|
|
|
if [ "$exit_code" = "0" ]; then
|
|
print_success "$check passed"
|
|
else
|
|
# For some checks, failure is not critical
|
|
if [ "$check" = "secrets" ] || [ "$check" = "markdown" ]; then
|
|
print_warning "$check had issues (non-critical)"
|
|
if [ -f "$TEMP_DIR/$check.out" ] && [ -s "$TEMP_DIR/$check.out" ]; then
|
|
echo -e "${YELLOW}$check output:${NC}"
|
|
cat "$TEMP_DIR/$check.out"
|
|
fi
|
|
else
|
|
print_error "$check failed"
|
|
FAILED_CHECKS+=("$check")
|
|
|
|
# Show error output
|
|
if [ -f "$TEMP_DIR/$check.err" ] && [ -s "$TEMP_DIR/$check.err" ]; then
|
|
echo -e "${RED}$check errors:${NC}"
|
|
cat "$TEMP_DIR/$check.err"
|
|
fi
|
|
if [ -f "$TEMP_DIR/$check.out" ] && [ -s "$TEMP_DIR/$check.out" ]; then
|
|
echo -e "${YELLOW}$check output:${NC}"
|
|
cat "$TEMP_DIR/$check.out"
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Re-stage any files that were modified by formatters
|
|
git add $STAGED_FILES 2>/dev/null || true
|
|
|
|
# Final result
|
|
if [ ${#FAILED_CHECKS[@]} -eq 0 ]; then
|
|
print_success "All critical pre-commit checks passed! 🎉"
|
|
echo ""
|
|
echo "Summary of checks:"
|
|
echo " ✅ Code formatting (Prettier)"
|
|
echo " ✅ Code linting (ESLint)"
|
|
echo " ✅ Type checking (TypeScript)"
|
|
echo " ⚠️ Markdown linting (non-critical)"
|
|
echo " ⚠️ Secret scanning (optional)"
|
|
echo ""
|
|
exit 0
|
|
else
|
|
print_error "The following critical checks failed: ${FAILED_CHECKS[*]}"
|
|
echo ""
|
|
echo "💡 Tips to fix:"
|
|
echo " - Run 'bun run lint:fix' to auto-fix linting issues"
|
|
echo " - Run 'bun run format' to fix formatting issues"
|
|
echo " - Run 'bun run type-check' to see detailed type errors"
|
|
echo ""
|
|
echo "🚨 Critical failures prevent commit. Fix these issues first."
|
|
echo ""
|
|
exit 1
|
|
fi
|