Skip to content

feat(commits): add Conventional Commits message normalizer - #240

Open
iamlasse wants to merge 3 commits into
marcus:mainfrom
iamlasse:chore/commit-normalize-20260905
Open

feat(commits): add Conventional Commits message normalizer#240
iamlasse wants to merge 3 commits into
marcus:mainfrom
iamlasse:chore/commit-normalize-20260905

Conversation

@iamlasse

@iamlasse iamlasse commented Sep 5, 2026

Copy link
Copy Markdown

Summary

Standardize the project's commit message format by enforcing Conventional Commits going forward via tooling (no history rewrite).

  • internal/commits — pure Normalize/Validate functions enforcing the project's rules: known type set (feat, fix, docs, style, refactor, perf, test, chore, build, ci), lowercase type and subject, trimmed whitespace, 72-char subject limit, blank line between subject and body, body wrapped at 72 columns. Table-driven unit tests cover valid messages, type canonicalization, unknown types, over-length subjects, whitespace trimming, multi-paragraph wrapping, and empty/subject-only messages.
  • nightshift commit normalize — cobra subcommand reading the message from a positional argument, --file (e.g. .git/COMMIT_EDITMSG), or stdin. --check validates without rewriting. With --file the normalized message is written back in place; non-zero exit on validation failure so hooks can block bad commits.
  • scripts/commit-msg.sh — installable git commit-msg hook (falls back to go run when the binary is not on PATH); make install-hooks now installs it alongside pre-commit.
  • docs/commit-messages.md — documents the enforced format, examples, CLI usage, and hook installation.

Verified end-to-end: a non-conforming message is blocked by the hook, a fixable one (uppercase type, stray whitespace/punctuation, unwrapped body) is rewritten in place before the commit is created.

Nightshift-Task: commit-normalize
Nightshift-Ref: https://github.com/marcus/nightshift

Add internal/commits with pure Normalize/validate functions enforcing the project's Conventional Commits rules (known type set, lowercase type and subject, 72-char subject limit, whitespace trimming, and 72-column body wrapping). Wire it into the CLI as 'nightshift commit normalize' (positional, --file, and stdin sources; --check to validate only; --file rewrites the message in place), ship a commit-msg git hook under scripts/ with make install-hooks support, and document the format and installation in docs/commit-messages.md.

Nightshift-Task: commit-normalize
Nightshift-Ref: https://github.com/marcus/nightshift
wrapBody used to join every run of consecutive non-blank body lines into
a single paragraph before wrapping, which merged multi-line git trailers
(Signed-off-by, Co-authored-by) onto one line and destroyed intentional
line structure such as lists and indented code blocks. The final
paragraph is now detected as a git trailer block and emitted verbatim,
and structured lines (list items, quotes, indented or fenced code) keep
their own lines while prose around them is still joined and wrapped.

Nightshift-Task: commit-normalize
Nightshift-Ref: https://github.com/marcus/nightshift
@iamlasse

iamlasse commented Sep 5, 2026

Copy link
Copy Markdown
Author

Fixes both review blockers from iteration 1:

1. Trailer handling (wrapBody) — the final paragraph is now detected as a git trailer block (Token: value lines plus indented continuations) and emitted verbatim: trailers are never joined onto one line and never wrapped, even past 72 columns. Structured lines inside paragraphs (list items - * + 1., block quotes, indented or fenced code) also keep their own lines; only runs of prose are joined and wrapped. Documented in docs/commit-messages.md. Six new table-driven cases cover trailers, overlong trailers, continuations, lists, indented code, and prose/list interleaving.

2. Verification methodology — this fix commit (4d407e0) was created through the hook itself, with a fresh build of the binary first on PATH: the message file was drafted with an unwrapped single-line body, commit-msg reported "normalized", and git log -1 --format=%B on the resulting commit shows the body wrapped at 72 columns with both Nightshift-* trailers intact on separate lines — direct evidence the hook rewrote it. (Iteration 1's commit 1723edc was never rewritten because the stale nightshift v0.3.4 on PATH predates the subcommand; re-normalizing 1723edc's message now yields wrapped body + separate trailers.)

go build/go vet/gofmt -l clean, full go test ./... passes.

Bring the PR branch up to date with origin/main (dc3b319, agent
guidance docs refresh). No code changes; keeps the PR current for
review.

Nightshift-Task: commit-normalize
Nightshift-Ref: https://github.com/marcus/nightshift
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant