Files
JuliaFEM.jl/.githooks/commit-msg
T
Jukka Aho f663fda6f7 fix(githooks): shorten commit-msg hook diagnostics
Long echo strings broke the same eighty-column rule the hook enforces on log
messages. Error output is split so the hook file itself stays readable.

- Wrap rejection messages to eighty columns or fewer
- Keep wording aligned with subject, summary, and bullet layout rules
2026-05-11 02:53:11 +03:00

129 lines
3.7 KiB
Bash
Executable File

#!/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: subject, blank, summary, blank, then \"- ...\" 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, bullets"
echo "(five or more 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 a summary line after the subject blank line"
echo "before the blank that precedes 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: summary line $((i + 1)) starts like a bullet"
echo "Use prose first, one blank line, then hyphen 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 before the bullet list"
echo "Add one to three sentences, then a blank line, then bullets."
exit 1
fi
for ((i = bullet_idx; i < n; i++)); do
line=${lines[i]}
if [[ -z "${line}" ]]; then
echo "❌ COMMIT MESSAGE: empty line $((i + 1)) inside bullet block"
echo "Remove blanks between bullets or end after the last bullet."
exit 1
fi
if ! [[ "${line}" =~ ^[[:space:]]*-[[:space:]] ]]; then
echo "❌ COMMIT MESSAGE: line $((i + 1)) is not a hyphen bullet"
echo "Each bullet line must start with dash then space after summary."
exit 1
fi
done
exit 0