#!/usr/bin/bash # Pre-commit hook: run clang-format via kt-kernel's CMake 'format' target and Black for Python # before allowing commit. If formatting makes changes, stage them and abort so user can review. set -euo pipefail REPO_ROOT="$(git rev-parse --show-toplevel)" # kt-kernel project directory within the monorepo KERNEL_DIR="$REPO_ROOT/kt-kernel" # Relative path for matching staged files under repo root REL_KERNEL_DIR="kt-kernel" BUILD_DIR="$KERNEL_DIR/build" FORMAT_TARGET="format" CLANG_FORMAT_BIN="${CLANG_FORMAT_BIN:-clang-format}" BLACK_BIN="${BLACK_BIN:-black}" # Simple check clang-format present (optional) # clang-format optional: if missing, skip C/C++ formatting if ! command -v "$CLANG_FORMAT_BIN" >/dev/null 2>&1; then echo "[pre-commit] clang-format not found (looked for $CLANG_FORMAT_BIN). Skipping C/C++ format." >&2 fi # black optional: if missing, skip Python formatting if ! command -v "$BLACK_BIN" >/dev/null 2>&1; then echo "[pre-commit] black not found (looked for $BLACK_BIN). Skipping Python format." >&2 fi ## Format only staged changes within kt-kernel # Collect staged files (Added/Modified/Copied/Renamed) mapfile -d '' STAGED < <(git diff --cached --name-only -z --diff-filter=AMCR) PY_CHANGED=() CPP_CHANGED=() for f in "${STAGED[@]}"; do case "$f" in "$REL_KERNEL_DIR"/*) ext="${f##*.}" case "$ext" in py) PY_CHANGED+=("$f") ;; c|cc|cpp|cxx|h|hh|hpp|hxx|cu|cuh) CPP_CHANGED+=("$f") ;; esac ;; esac done # Run clang-format only on staged C/C++ files if command -v "$CLANG_FORMAT_BIN" >/dev/null 2>&1 && [ ${#CPP_CHANGED[@]} -gt 0 ]; then echo "[pre-commit] clang-format on ${#CPP_CHANGED[@]} files" >&2 for f in "${CPP_CHANGED[@]}"; do "$CLANG_FORMAT_BIN" -i "$f" done fi ## Run black only on staged Python files if command -v "$BLACK_BIN" >/dev/null 2>&1 && [ ${#PY_CHANGED[@]} -gt 0 ]; then echo "[pre-commit] black on ${#PY_CHANGED[@]} files" >&2 "$BLACK_BIN" "${PY_CHANGED[@]}" fi # Stage any formatting changes for tracked, formatted files only FMT_FILES=("${PY_CHANGED[@]}" "${CPP_CHANGED[@]}") if [ ${#FMT_FILES[@]} -gt 0 ] && ! git diff --quiet --exit-code -- "${FMT_FILES[@]}"; then echo "[pre-commit] Formatting applied; updating index." >&2 git add "${FMT_FILES[@]}" echo "[pre-commit] Re-run git commit to proceed after reviewing changes." >&2 exit 1 fi echo "[pre-commit] format OK." >&2 exit 0