From 9d7fbfbbbc34326f0f475ec3a0a2c6b19403ca67 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Thu, 5 Mar 2026 18:36:17 +0800 Subject: [PATCH 1/5] commitlint/tests: better title for 2 tests This way their purpose is more understandable. --- commitlint/tests/plugins.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commitlint/tests/plugins.test.ts b/commitlint/tests/plugins.test.ts index aeb70eb9..e8715bdf 100644 --- a/commitlint/tests/plugins.test.ts +++ b/commitlint/tests/plugins.test.ts @@ -858,7 +858,7 @@ test("prefer-slash-over-backslash2", () => { test("header-max-length-with-suggestions1", () => { const commitMsgWithThatExceedsHeaderMaxLength = - "foo: this is only a title with a configuration in it that exceeds header max length"; + "foo: this is only a title with the term 'configuration' in it that exceeds header max length"; const headerMaxLength1 = runCommitLintOnMsg( commitMsgWithThatExceedsHeaderMaxLength ); @@ -871,7 +871,7 @@ test("header-max-length-with-suggestions1", () => { test("header-max-length-with-suggestions2", () => { const commitMsgWithThatExceedsHeaderMaxLength = - "foo: this is only a title with a 1 second in it that exceeds header max length"; + "foo: this is only a title with the term '1 second' (which includes a space) in it that exceeds header max length"; const headerMaxLength2 = runCommitLintOnMsg( commitMsgWithThatExceedsHeaderMaxLength ); From 536c3c7d0249362403b2849da426e489974e75eb Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Thu, 5 Mar 2026 18:42:19 +0800 Subject: [PATCH 2/5] commitlint/abbreviations: remove weird item It is even more weird when used in plural, which is how it was shown in a plugin test, meh. --- commitlint/abbreviations.ts | 1 - commitlint/tests/plugins.test.ts | 13 ------------- 2 files changed, 14 deletions(-) diff --git a/commitlint/abbreviations.ts b/commitlint/abbreviations.ts index b722af3e..94ef3516 100644 --- a/commitlint/abbreviations.ts +++ b/commitlint/abbreviations.ts @@ -46,7 +46,6 @@ export const abbr = { "command": "cmd", "commands": "cmds", "command line": "cmdline", - "compare": "cmp", "compress": "zip", "compressed": "zipped", "concatenate": "concat", diff --git a/commitlint/tests/plugins.test.ts b/commitlint/tests/plugins.test.ts index e8715bdf..67330f5d 100644 --- a/commitlint/tests/plugins.test.ts +++ b/commitlint/tests/plugins.test.ts @@ -985,19 +985,6 @@ test("header-max-length-with-suggestions11", () => { ); }); -test("header-max-length-with-suggestions12", () => { - const commitMsgThatExceedsHeaderMaxLength = - "Split that compares better because blah blah bla very very very long title"; - const headerMaxLength12 = runCommitLintOnMsg( - commitMsgThatExceedsHeaderMaxLength - ); - const not_expected_message = `"compares" -> "cmps"`; - expect(headerMaxLength12.status).not.toBe(0); - expect( - (headerMaxLength12.stdout + "").includes(not_expected_message) - ).toEqual(false); -}); - test("proper-issue-refs1", () => { const commitMsgWithHashtagRef = `foo: blah blah From 67b9249de318291f4a64c3b17805eaf16b5c5498 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Thu, 5 Mar 2026 19:12:00 +0800 Subject: [PATCH 3/5] commitlint/tests: testcases for Revert exceptions They have failing CI because I haven't implemented them yet. --- commitlint/tests/plugins.test.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/commitlint/tests/plugins.test.ts b/commitlint/tests/plugins.test.ts index 67330f5d..0da0a342 100644 --- a/commitlint/tests/plugins.test.ts +++ b/commitlint/tests/plugins.test.ts @@ -985,6 +985,33 @@ test("header-max-length-with-suggestions11", () => { ); }); +test("header-max-length-with-suggestions12", () => { + const commitMsgThatExceedsHeaderMaxLengthBecauseItIsARevert = + 'Revert "This header is a title with less than 50chars"'; + const headerMaxLength12 = runCommitLintOnMsg( + commitMsgThatExceedsHeaderMaxLengthBecauseItIsARevert + ); + expect(headerMaxLength12.status).toBe(0); +}); + +test("header-max-length-with-suggestions13", () => { + const commitMsgThatExceedsHeaderMaxLengthBecauseItIsARevertOfARevert = + 'Reapply "This header is a title with less than 50chars"'; + const headerMaxLength13 = runCommitLintOnMsg( + commitMsgThatExceedsHeaderMaxLengthBecauseItIsARevertOfARevert + ); + expect(headerMaxLength13.status).toBe(0); +}); + +test("header-max-length-with-suggestions14", () => { + const commitMsgThatExceedsHeaderMaxLengthEvenIfItIsARevert = + 'Revert "This header is a title with moooooooooore than 50chars"'; + const headerMaxLength14 = runCommitLintOnMsg( + commitMsgThatExceedsHeaderMaxLengthEvenIfItIsARevert + ); + expect(headerMaxLength14.status).not.toBe(0); +}); + test("proper-issue-refs1", () => { const commitMsgWithHashtagRef = `foo: blah blah From 01b9310f9031af30e52a69a47de49a16435825cf Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Thu, 5 Mar 2026 19:36:05 +0800 Subject: [PATCH 4/5] commitlint/plugins: make new tests pass This makes maxLineHeader plugin respect the exceptions of titles that are too long because they are reverts or reverts of a revert. --- commitlint/plugins.ts | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/commitlint/plugins.ts b/commitlint/plugins.ts index fbe94ce1..65263a8c 100644 --- a/commitlint/plugins.ts +++ b/commitlint/plugins.ts @@ -135,7 +135,31 @@ export abstract class Plugins { const headerLength = headerStr.length; let message = `Please do not exceed ${maxLineLength} characters in title (found ${headerLength}).`; - if (!headerStr.startsWith("Merge ") && headerLength > maxLineLength) { + let theMaxLineLengthToCompareWith = maxLineLength; + + // note: a revert of a revert, in new versions of git, is written as "Reapply..." which happens + // to have same length as "Revert" + const extraCharsAllowedBecauseOfARevertOrARevertOfARevert = + 'Revert "'.length + + // we add one because revert commits end with '"' + 1; + + const maxLineLengthAfterAccountingForRevertException = + maxLineLength + extraCharsAllowedBecauseOfARevertOrARevertOfARevert; + if ( + headerStr.endsWith('"') && + (headerStr.startsWith('Revert "') || + headerStr.startsWith('Reapply "')) + ) { + theMaxLineLengthToCompareWith = + maxLineLengthAfterAccountingForRevertException; + message = `Please do not exceed ${maxLineLength} (${maxLineLengthAfterAccountingForRevertException} if it's a revert) characters in title (found ${headerLength}).`; + } + + if ( + !headerStr.startsWith("Merge ") && + headerLength > theMaxLineLengthToCompareWith + ) { offence = true; const colonIndex = headerStr.indexOf(":"); From 5c913f61eaf46c699349867dfcb4e52257b480c7 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Thu, 5 Mar 2026 21:09:32 +0800 Subject: [PATCH 5/5] Fixup workaround --- commitlint.config.ts | 9 +++------ commitlint/plugins.ts | 10 +++++++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/commitlint.config.ts b/commitlint.config.ts index 9414d2c6..fb66f9d9 100644 --- a/commitlint.config.ts +++ b/commitlint.config.ts @@ -98,17 +98,14 @@ export default { }, "header-max-length-with-suggestions": ( - { header }: { header: any }, + { raw }: { raw: any }, _: any, maxLineLength: number ) => { - const headerStr = extractStringFromCommitlintParam( - "header", - header - ); + const rawStr = extractStringFromCommitlintParam("rawStr", raw); return Plugins.headerMaxLengthWithSuggestions( - headerStr, + rawStr, maxLineLength ); }, diff --git a/commitlint/plugins.ts b/commitlint/plugins.ts index 65263a8c..4b01451b 100644 --- a/commitlint/plugins.ts +++ b/commitlint/plugins.ts @@ -128,11 +128,19 @@ export abstract class Plugins { } public static headerMaxLengthWithSuggestions( - headerStr: string, + rawStr: string, maxLineLength: number ) { let offence = false; + const lineBreakIndex = rawStr.indexOf("\n"); + let headerStr = rawStr; + if (lineBreakIndex >= 0) { + // Extracting headerStr from rawStr rather than using header directly is a + // workaround for what must be a commitlint or conventional-changelog bug, TODO: report + headerStr = rawStr.substring(0, lineBreakIndex); + } + const headerLength = headerStr.length; let message = `Please do not exceed ${maxLineLength} characters in title (found ${headerLength}).`; let theMaxLineLengthToCompareWith = maxLineLength;