#!/usr/bin/env sh
# Lint and format staged Python files with ruff before committing, mirroring the
# `ruff check` + `ruff format --check` gate in CI (.github/workflows/ci.yml) so
# failures surface locally instead of breaking CI.
# Enable once with: git config core.hooksPath .githooks
set -e

# Bail out early if no Python files are staged. This check uses a plain
# (non-NUL) substitution only to test emptiness — command substitution strips
# NUL bytes, so it must never be used to carry the -z file list.
[ -z "$(git diff --cached --name-only --diff-filter=ACM -- '*.py')" ] && exit 0

# Lint first, auto-fixing what ruff can. Any remaining (unfixable) violation
# makes ruff exit non-zero, and `set -e` aborts the commit so it never reaches
# CI. Then format. Both pipe the NUL-separated staged list straight into
# xargs -0 (never through a shell variable) so paths with spaces/newlines stay
# intact and separators are preserved. Re-stage what ruff rewrote at the end.
git diff --cached --name-only --diff-filter=ACM -z -- '*.py' | xargs -0 uv run ruff check --fix --
git diff --cached --name-only --diff-filter=ACM -z -- '*.py' | xargs -0 uv run ruff format --
git diff --cached --name-only --diff-filter=ACM -z -- '*.py' | xargs -0 git add --
