Skip to content

Commit a9dfdb9

Browse files
fix(exe)[cmp]: don't lint generated commit headers
Merge commits, reverts, autosquash markers, and release bumps used to fail the keyword parser and block the commit. Skip them before parsing, controlled by a new `default-ignores` key in [commit] (on unless disabled), mirroring commitlint's defaultIgnores option. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 3a652d5 commit a9dfdb9

3 files changed

Lines changed: 47 additions & 0 deletions

File tree

crates/atypical-commit/src/config.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ pub struct CommitConfig {
1616
pub enclosures: Vec<EnclosureConfig>,
1717
pub separator: char,
1818
pub modifier_sequence: Sequence,
19+
/// Skip machine-generated headers (merges, reverts, version
20+
/// bumps...); not part of the grammar, so absent from `Tokens`.
21+
pub default_ignores: bool,
1922
}
2023

2124
#[derive(Debug, Clone, PartialEq)]
@@ -57,6 +60,7 @@ impl From<&Tokens<'_>> for CommitConfig {
5760
.collect(),
5861
separator: tokens.separator,
5962
modifier_sequence: tokens.modifier_sequence,
63+
default_ignores: true,
6064
}
6165
}
6266
}
@@ -129,6 +133,16 @@ mod tests {
129133
);
130134
}
131135

136+
#[test]
137+
fn test_default_ignores_is_on_unless_disabled() {
138+
assert!(CommitConfig::default().default_ignores);
139+
140+
let config: CommitConfig =
141+
toml::from_str("default-ignores = false").unwrap();
142+
143+
assert!(!config.default_ignores);
144+
}
145+
132146
#[test]
133147
fn test_modifier_sequence_names() {
134148
let config: CommitConfig =

crates/atypical-commit/src/main.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ fn main() -> Result<Exit> {
117117

118118
use chumsky::Parser;
119119
let config = commit_config(args.config)?;
120+
121+
if config.default_ignores && atypical_commit::ignore::is_ignored(header) {
122+
return Ok(Exit::Success);
123+
}
124+
120125
let tokens = atypical_commit::Tokens::from(&config);
121126
let result = header_parser(&tokens).parse(header);
122127

crates/atypical-commit/tests/cli.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,34 @@ fn valid_header_after_blank_lines_and_crlf() {
7575
assert_eq!(output.status.code(), Some(0));
7676
}
7777

78+
#[test]
79+
fn generated_messages_are_ignored() {
80+
for header in [
81+
"Merge pull request #1 from repo/branch\n",
82+
"Merge branch 'main' into fix/default-ignore\n",
83+
"Revert \"add(lib)[int]: something\"\n",
84+
"fixup! add(lib)[int]: something\n",
85+
"chore(release): v1.2.3 [skip ci]\n",
86+
] {
87+
let output = lint(&["-"], Some(header));
88+
89+
assert_eq!(output.status.code(), Some(0), "not ignored: {header}");
90+
}
91+
}
92+
93+
#[test]
94+
fn default_ignores_can_be_disabled() {
95+
let config =
96+
fixture("no-ignores.toml", "[commit]\ndefault-ignores = false\n");
97+
let config = config.to_str().unwrap();
98+
let header = Some("Merge branch 'main'\n");
99+
100+
let output = lint(&["--config", config, "-"], header);
101+
102+
assert_eq!(output.status.code(), Some(1));
103+
assert!(stderr(&output).contains("unknown keyword `Merge`"));
104+
}
105+
78106
#[test]
79107
fn invalid_keyword_reports_and_fails() {
80108
let output = lint(&["-"], Some("feat: wrong style\n"));

0 commit comments

Comments
 (0)