Files
JuliaFEM.jl/.githooks/commit-msg
T
Jukka Aho e7862ed538 fix(githooks): enforce subject, summary, and bullet layout
The commit-msg hook parses messages in bash only so contributors get the same
shape every time without Python or other helpers in the hook path.

- Enforce eighty-column lines plus subject, blank, summary, blank, then bullets
- Reject bullet-looking lines inside the summary block and blanks among bullets
- Skip all checks while .git/MERGE_HEAD exists for merge commits
2026-05-11 02:46:06 +03:00

131 lines
3.8 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# Enforce commit message layout and line length (pure bash; no helper scripts).
# Enable with: git config core.hooksPath .githooks
#
# Required shape (merge commits skip all checks while .git/MERGE_HEAD exists):
# 1) subject (non-empty, <=80 chars)
# 2) blank line
# 3) one or more summary lines (no "- " bullet prefix), <=80 chars each
# 4) blank line
# 5) one or more body lines, each a "- ..." bullet, <=80 chars each
#
# Merge templates from Git can exceed 80 columns; skip checks then.
set -euo pipefail
msg_file=${1:?commit-msg hook requires path to message file}
if [[ -f .git/MERGE_HEAD ]]; then
exit 0
fi
lines=()
lineno=0
while IFS= read -r line || [[ -n "${line}" ]]; do
lineno=$((lineno + 1))
len=${#line}
if ((len > 80)); then
echo "❌ COMMIT MESSAGE: line ${lineno} is ${len} chars (max 80)"
echo ""
echo "Required layout: subject, blank, summary paragraph, blank, bullets."
echo "See .github/prompts/commit.prompt.md"
echo ""
echo "Offending line (truncated for display):"
printf '%s\n' "${line}" | cut -c1-120
exit 1
fi
lines+=("$line")
done <"${msg_file}"
# Drop trailing empty lines so optional final newline does not confuse counts.
while ((${#lines[@]} > 0)); do
last=$(( ${#lines[@]} - 1 ))
if [[ -z ${lines[last]} ]]; then
unset "lines[last]"
else
break
fi
done
n=${#lines[@]}
if ((n < 5)); then
echo "❌ COMMIT MESSAGE: need subject, blank, summary, blank, then bullets"
echo "(at least five lines). See .github/prompts/commit.prompt.md"
exit 1
fi
if [[ -z "${lines[0]}" ]]; then
echo "❌ COMMIT MESSAGE: first line (subject) must not be empty"
exit 1
fi
if [[ -n "${lines[1]}" ]]; then
echo "❌ COMMIT MESSAGE: line 2 must be blank (separator after subject)"
exit 1
fi
bullet_idx=-1
for ((i = 2; i < n; i++)); do
line=${lines[i]}
if [[ "${line}" =~ ^[[:space:]]*-[[:space:]] ]]; then
bullet_idx=$i
break
fi
done
if ((bullet_idx < 0)); then
echo "❌ COMMIT MESSAGE: no bullet list found (lines starting with \"- \")"
echo "After the summary paragraph and its trailing blank line, add details"
echo "as \"- ...\" bullets. See .github/prompts/commit.prompt.md"
exit 1
fi
if ((bullet_idx < 3)); then
echo "❌ COMMIT MESSAGE: add at least one summary line after the subject blank"
echo "before the separator blank and bullets."
exit 1
fi
if [[ -n "${lines[bullet_idx - 1]}" ]]; then
echo "❌ COMMIT MESSAGE: blank line required between summary and bullet list"
echo "(line $((bullet_idx)) should be empty)."
exit 1
fi
has_summary=0
for ((i = 2; i < bullet_idx - 1; i++)); do
line=${lines[i]}
if [[ -n "${line}" ]] && [[ "${line}" =~ ^[[:space:]]*-[[:space:]] ]]; then
echo "❌ COMMIT MESSAGE: line $((i + 1)) looks like a bullet but is above"
echo "the summary block; write prose summary lines first, then a blank"
echo "line, then \"- ...\" bullets."
exit 1
fi
if [[ -n "${line}" ]]; then
has_summary=1
fi
done
if ((has_summary == 0)); then
echo "❌ COMMIT MESSAGE: summary paragraph is empty (need 13 sentences before"
echo "the blank line that precedes bullets)."
exit 1
fi
for ((i = bullet_idx; i < n; i++)); do
line=${lines[i]}
if [[ -z "${line}" ]]; then
echo "❌ COMMIT MESSAGE: line $((i + 1)) is empty inside the bullet block;"
echo "remove blank lines between bullets or end the message after the last"
echo "bullet."
exit 1
fi
if ! [[ "${line}" =~ ^[[:space:]]*-[[:space:]] ]]; then
echo "❌ COMMIT MESSAGE: line $((i + 1)) must be a \"- ...\" bullet after the"
echo "summary section."
exit 1
fi
done
exit 0