A Rust-based commit message linter following the Conventional Commits specification. Similar to Node.js's commitlint, but written entirely in Rust and designed for the Rust ecosystem.
- âś… Validates commit messages against Conventional Commits specification
- âś… Configurable via TOML (similar to
commitlint) - âś… Git hook integration (similar to
cargo-husky) - âś… Supports all standard Conventional Commit types
- âś… Customizable rules for type, scope, subject, body, and footer
- âś… Regex-based commit message parsing
- âś… Ignore patterns for skipping validation
git clone https://github.com/pegasusheavy/cargo-commitlint.git
cd cargo-commitlint
cargo install --path .cargo install cargo-commitlintAfter installation, cargo-commitlint is available as a cargo subcommand. Use it with:
cargo commitlint <command>This project uses cargo-husky to manage git hooks. The hooks are automatically installed when you run cargo test.
- pre-commit: Runs
cargo fmt --checkandcargo clippyto ensure code quality - pre-push: Runs
cargo testto ensure all tests pass before pushing - commit-msg: Validates commit messages using
cargo commitlintand Conventional Commits
Simply run:
cargo testThis will compile the project and install all git hooks configured in .cargo-husky/hooks/.
If you prefer to use cargo commitlint's built-in hook installer instead of cargo-husky:
cargo commitlint installThis will create a .git/hooks/commit-msg hook that validates all commit messages using cargo commitlint.
Remove the git hook:
cargo commitlint uninstallValidate a commit message directly:
# Validate from command line
cargo commitlint check --message "feat: add new feature"
# Validate from stdin
echo "feat: add new feature" | cargo commitlint checkCreate a commitlint.toml or .commitlint.toml file in your project root. You can copy commitlint.example.toml as a starting point:
cp commitlint.example.toml commitlint.toml[rules]
# Type validation
[rules.type]
enum = ["feat", "fix", "docs", "style", "refactor", "test", "chore"]
case = "lowercase"
# Scope validation
[rules.scope]
enum = [] # Empty means all scopes allowed
case = "lowercase"
# Subject validation
subject_case = ["sentence-case"]
subject_empty = false
subject_full_stop = "."
# Header validation
header_max_length = 72
header_min_length = 0
# Body validation
body_leading_blank = true
body_max_line_length = 100
# Footer validation
footer_leading_blank = true
footer_max_line_length = 100
# Parser configuration
[parser]
pattern = "^(?P<type>\\w+)(?:\\((?P<scope>[^)]+)\\))?(?P<breaking>!)?:\\s(?P<subject>.*)$"
# Ignore patterns (regex)
ignores = [
# "Merge.*",
# "Revert.*",
]The tool validates commit messages in the following format:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
feat: A new featurefix: A bug fixdocs: Documentation only changesstyle: Changes that do not affect the meaning of the coderefactor: A code change that neither fixes a bug nor adds a featureperf: A code change that improves performancetest: Adding missing tests or correcting existing testsbuild: Changes that affect the build system or external dependenciesci: Changes to CI configuration files and scriptschore: Other changes that don't modify src or test filesrevert: Reverts a previous commit
Valid commit messages:
feat: add user authentication
feat(api): add new endpoint
fix: resolve memory leak in parser
docs: update README with installation instructions
feat!: breaking change in API
feat: add feature
This is a longer description of the change.
Closes #123
Invalid commit messages:
invalid: bad commit type
feat:Missing colon
feat: subject too long and exceeds the maximum length limit of 72 characters
rules.type.enum: List of allowed commit types (empty = all allowed)rules.type.case: Case requirement (lowercase,uppercase,camel-case,kebab-case,pascal-case,snake-case)rules.scope.enum: List of allowed scopes (empty = all allowed)rules.scope.case: Case requirement for scoperules.subject_case: List of allowed case formats (sentence-case,lowercase,uppercase,start-case)rules.subject_empty: Whether subject can be emptyrules.subject_full_stop: Character that should not appear at end of subjectrules.header_max_length: Maximum header lengthrules.header_min_length: Minimum header lengthrules.body_leading_blank: Require blank line before bodyrules.body_max_line_length: Maximum line length in bodyrules.footer_leading_blank: Require blank line before footerrules.footer_max_line_length: Maximum line length in footer
parser.pattern: Regex pattern for parsing conventional commitsparser.correspondence: Map regex capture groups to commit fields
ignores: List of regex patterns for commits to skip validation
This tool is designed to work seamlessly with Rust projects and integrates with cargo-husky for comprehensive git hook management.
This project includes cargo-husky configuration with pre-commit, pre-push, and commit-msg hooks:
- Pre-commit hook: Ensures code is formatted (
cargo fmt) and passes clippy checks - Pre-push hook: Runs all tests before allowing pushes
- Commit-msg hook: Validates commit messages using
cargo commitlint
To activate the hooks, simply run:
cargo testThe hooks are defined in .cargo-husky/hooks/ and will be automatically installed.
Alternatively, you can use cargo commitlint's built-in installer:
cargo commitlint installThis will install only the commit-msg hook for commit message validation.
Licensed under the MIT License.
Copyright (c) 2025 Pegasus Heavy Industries LLC
See LICENSE or LICENSE-MIT for details.
Contributions are welcome! Please feel free to submit a Pull Request.