#!/usr/bin/env bash
#
# pre-commit: refuse a commit whose Swift files are not formatted.
#
# `swift format lint --strict` is the only CI step this repository has ever
# failed on. Build and test have never gone red; every failed run has been
# formatting, and always on a push to main, where the cost is a red badge on a
# release commit plus a second commit to fix it. Catching it here costs a second.
#
# Enable it in a clone with:
#   git config core.hooksPath .githooks
#
# Lints the working-tree copy of each staged Swift file. A partially staged file
# is therefore judged by what is on disk, which is the right answer for
# formatting: the whole file has to be clean before CI sees it.
set -euo pipefail

files=()
while IFS= read -r path; do
  if [[ -n "$path" && -f "$path" ]]; then
    files+=("$path")
  fi
done < <(git diff --cached --name-only --diff-filter=ACMR -- '*.swift')

if [[ ${#files[@]} -eq 0 ]]; then
  exit 0
fi

if ! command -v swift >/dev/null 2>&1; then
  echo "pre-commit: swift not found, skipping the format check." >&2
  exit 0
fi

# --strict matches CI, where warnings are failures.
if ! swift format lint --strict "${files[@]}"; then
  cat >&2 <<'MESSAGE'

pre-commit: those Swift files are not formatted, and CI will reject them.

  Fix:   swift format --in-place --recursive Sources Tests Package.swift
  Stage: git add -u
  Then:  git commit

  To commit anyway: git commit --no-verify
MESSAGE
  exit 1
fi
