Skip to content

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

Open
iamlasse wants to merge 1 commit into
marcus:mainfrom
iamlasse:feat/commit-normalizer-iter2
Open

feat(commits): add Conventional Commits message normalizer#208
iamlasse wants to merge 1 commit into
marcus:mainfrom
iamlasse:feat/commit-normalizer-iter2

Conversation

@iamlasse

@iamlasse iamlasse commented Aug 6, 2026

Copy link
Copy Markdown

Summary

Adds a Conventional Commits message normalizer to the nightshift CLI, addressing all review feedback from PR #207 (iteration 2).

  • internal/commits — pure Normalize/validate package enforcing the project's rules: known lowercase type set (feat fix docs style refactor test chore perf build ci revert), optional (scope), breaking-change ! marker, lowercase non-capitalized subject, rune-based 72-char subject limit, git-comment stripping, whitespace/trailing-period cleanup, and 72-rune body wrapping that preserves paragraph breaks. Idempotent. Errors are wrapped, errors.Is-matchable sentinels.
  • CLInightshift commit normalize accepting a positional message, --file, or stdin, plus --check for validate-only. Registered on the root command.
  • scripts/commit-msg.sh — git commit-msg hook that normalizes the message in place and rejects invalid messages with a friendly diagnostic block.
  • docs/commit-messages.md — format rules, type list, command examples, and hook installation.

Fixes from iteration-1 review

  1. --check is now truly validate-only — it no longer prints the rewritten message; it prints nothing on success and exits non-zero on failure.
  2. Hook diagnostic block is no longer dead codeNORMALIZED="$(...)" || STATUS=$? tolerates the failing command substitution under set -euo pipefail, so the expected-format/types/--no-verify guidance now actually prints.
  3. Single clean error outputSilenceUsage/SilenceErrors on the command; no more Error: + full Usage dump on every validation failure.
  4. No temp-file leak — hook uses mktemp (cleaned via a trap) instead of a fixed /tmp/nightshift-commit-msg.err.
  5. Rune-consistent wrapping — body wrapping now measures width in runes, matching the rune-based subject limit (verified for multibyte text).
  6. Renamed sentinelErrSubjectLowercaseErrSubjectCapitalized (matches its "must not be capitalized" message).
  7. feat! breaking-change supportfeat!: / feat(scope)!: parse and round-trip instead of producing a confusing "unknown type" error; revert added to the allowed type set.

Verification

  • go build ./..., go vet ./..., gofmt -l . — clean
  • go test ./internal/commits/... — pass
  • CLI exercised: --check validate-only, single-line error output, rewrite mode, breaking-change output
  • Hook exercised end-to-end: bad message prints diagnostics + exits 1; good message rewrites in place + exits 0; no temp leak

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 lowercase type set (including
revert), optional scope, breaking-change "!" marker, lowercase non-capitalized
subject, rune-based 72-char subject limit, comment stripping, whitespace and
trailing-period cleanup, and 72-rune body wrapping while preserving paragraph
breaks. Wire it into the CLI as "nightshift commit normalize" (positional,
--file, and stdin sources; --check validate-only), ship a commit-msg git hook
under scripts/, and document the format and installation in
docs/commit-messages.md.

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