Git pre-commit 훅

커밋 전 린트, 포맷, 타입 체크를 자동 실행하는 Git pre-commit 훅 스크립트.

Gist
#!/usr/bin/env bash
set -euo pipefail

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
PASS="${GREEN}✓${NC}"; FAIL="${RED}✗${NC}"; SKIP="${YELLOW}–${NC}"

echo "Running pre-commit checks..."

STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR)
TS_FILES=$(echo "$STAGED_FILES" | grep -E '\.(ts|tsx)$' || true)
JS_FILES=$(echo "$STAGED_FILES" | grep -E '\.(js|jsx|mjs|cjs)$' || true)
ALL_JS=$(printf '%s\n%s' "$TS_FILES" "$JS_FILES" | grep -v '^$' || true)

run_check() {
  local name="$1"; shift
  if "$@" &>/dev/null; then
    echo -e "  $PASS $name"
  else
    echo -e "  $FAIL $name (run manually to see errors)"
    exit 1
  fi
}

if [[ -n "$ALL_JS" ]]; then
  if command -v eslint &>/dev/null; then
    run_check "ESLint" npx eslint --fix $ALL_JS
    git add $ALL_JS
  else
    echo -e "  $SKIP ESLint (not installed)"
  fi
fi

if command -v prettier &>/dev/null && [[ -n "$STAGED_FILES" ]]; then
  FORMATTED_FILES=$(echo "$STAGED_FILES" | grep -E '\.(ts|tsx|js|jsx|json|css|md)$' || true)
  if [[ -n "$FORMATTED_FILES" ]]; then
    run_check "Prettier" npx prettier --write $FORMATTED_FILES
    git add $FORMATTED_FILES
  fi
else
  echo -e "  $SKIP Prettier (not installed)"
fi

if [[ -n "$TS_FILES" ]] && command -v tsc &>/dev/null; then
  run_check "TypeScript" npx tsc --noEmit
else
  echo -e "  $SKIP TypeScript check (no .ts files changed or tsc not found)"
fi

if [[ -f "package.json" ]] && grep -q '"test:staged"' package.json; then
  run_check "Tests (staged)" npm run test:staged
fi

echo -e "\n${GREEN}All checks passed.${NC} Proceeding with commit.\n"