Skip to content

Commit 721b6dc

Browse files
committed
Add mix-format pre-commit hook
1 parent a1ba9e7 commit 721b6dc

1 file changed

Lines changed: 55 additions & 0 deletions

File tree

.githooks/pre-commit

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Unity pre-commit hook.
4+
#
5+
# Runs `mix format` on every staged `.ex` / `.exs` / `.heex` file so
6+
# that CI's `mix format --check-formatted` cannot fail on a freshly-
7+
# committed file. Re-stages each formatted file in-place so the
8+
# commit you wrote is the commit that lands.
9+
#
10+
# Lives under .githooks/ (committed to the repo, not under .git/hooks/
11+
# which is local-only). Activate with:
12+
#
13+
# git config core.hooksPath .githooks
14+
#
15+
16+
set -eu
17+
18+
# Collect staged Elixir files (added, copied, modified — not deleted).
19+
# Avoid `mapfile` so this works on macOS's stock bash 3.2.
20+
staged="$(
21+
git diff --cached --name-only --diff-filter=ACM \
22+
| grep -E '\.(ex|exs|heex)$' || true
23+
)"
24+
25+
if [ -z "$staged" ]; then
26+
exit 0
27+
fi
28+
29+
# Skip files that no longer exist on disk (e.g. renamed away after
30+
# staging) and accumulate the ones we can format.
31+
to_format=""
32+
while IFS= read -r f; do
33+
if [ -f "$f" ]; then
34+
to_format="$to_format $f"
35+
fi
36+
done <<EOF
37+
$staged
38+
EOF
39+
40+
# Trim leading whitespace; bail if nothing's left.
41+
to_format="${to_format# }"
42+
if [ -z "$to_format" ]; then
43+
exit 0
44+
fi
45+
46+
# Format the files in place. Word-splitting on `to_format` is
47+
# intentional — the file list is space-separated.
48+
# shellcheck disable=SC2086
49+
mix format $to_format
50+
51+
# Re-stage anything `mix format` actually changed. `git add` is a
52+
# no-op for files that didn't change, so this is safe to call on
53+
# every file in the list.
54+
# shellcheck disable=SC2086
55+
git add $to_format

0 commit comments

Comments
 (0)