Skip to content

feat!: show input from a new line#4727

Open
knocte wants to merge 6 commits intoconventional-changelog:masterfrom
knocte:finishPr4102
Open

feat!: show input from a new line#4727
knocte wants to merge 6 commits intoconventional-changelog:masterfrom
knocte:finishPr4102

Conversation

@knocte
Copy link
Copy Markdown
Contributor

@knocte knocte commented Apr 22, 2026

Supersedes #4102

This will be less confusing to read, and also easier to test and copy/paste (for example for #4101).

This error log is confusing for people not familiar with commitlint.

⧗   input: fix: ingest - do not double strip /doc/ prefix
It is already stripped here
https://gitlab.com/gitlab-community/modelops/applied-ml/code-suggestions/ai-assist/-/blob/22bb9cf2b996dc2ec347bad761abb12fd11bcf75/scripts/ingest/gitlab-docs/steps/parse.rb#L16
✖   body's lines must not be longer than 100 characters [body-max-line-length]
✖   found 1 warnings

This one should be more clear.

⧗   --- input ---
fix: ingest - do not double strip /doc/ prefix

It is already stripped here
https://gitlab.com/gitlab-community/modelops/applied-ml/code-suggestions/ai-assist/-/blob/22bb9cf2b996dc2ec347bad761abb12fd11bcf75/scripts/ingest/gitlab-docs/steps/parse.rb#L16
✖   body's lines must not be longer than 100 characters [body-max-line-length]
✖   found 1 warnings

Or maybe even this one.

⧗   commit message:
fix: ingest - do not double strip /doc/ prefix

It is already stripped here
https://gitlab.com/gitlab-community/modelops/applied-ml/code-suggestions/ai-assist/-/blob/22bb9cf2b996dc2ec347bad761abb12fd11bcf75/scripts/ingest/gitlab-docs/steps/parse.rb#L16
✖   body's lines must not be longer than 100 characters [body-max-line-length]
✖   found 1 warnings

Motivation and Context

Error output should not mess up original commit message, because it is hard to understand what is wrong.

Usage examples

// commitlint.config.js
module.exports = {};
echo "your commit message here" | commitlint # fails/passes

How Has This Been Tested?

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Add multi-line input display with legacy output flag support

✨ Enhancement 🧪 Tests 📝 Documentation

Grey Divider

Walkthroughs

Description
• Change default input output format to multi-line with --- input --- banner
• Add --legacy-output flag to restore single-line input: ... format
• Add comprehensive test cases for both new and legacy output formats
• Update documentation examples to reflect new default output format
Diagram
flowchart LR
  A["CLI Input"] --> B["Format Module"]
  B --> C{"legacyOutput Flag?"}
  C -->|true| D["Single-line: input: ..."]
  C -->|false| E["Multi-line: --- input ---"]
  D --> F["Output Display"]
  E --> F
Loading

Grey Divider

File Changes

1. @commitlint/cli/src/cli.ts ✨ Enhancement +5/-0

Add legacy-output CLI flag option

@commitlint/cli/src/cli.ts


2. @commitlint/cli/src/types.ts ✨ Enhancement +1/-0

Add legacy-output to CliFlags interface

@commitlint/cli/src/types.ts


3. @commitlint/format/src/format.ts ✨ Enhancement +11/-4

Implement multi-line input format with legacy support

@commitlint/format/src/format.ts


View more (7)
4. @commitlint/format/src/format.test.ts 🧪 Tests +81/-0

Add tests for new and legacy output formats

@commitlint/format/src/format.test.ts


5. @commitlint/types/src/format.ts ✨ Enhancement +1/-0

Add legacyOutput option to FormatOptions interface

@commitlint/types/src/format.ts


6. @commitlint/config-lerna-scopes/readme.md 📝 Documentation +6/-3

Update examples to new multi-line output format

@commitlint/config-lerna-scopes/readme.md


7. @commitlint/config-nx-scopes/readme.md 📝 Documentation +6/-3

Update examples to new multi-line output format

@commitlint/config-nx-scopes/readme.md


8. @commitlint/config-pnpm-scopes/readme.md 📝 Documentation +6/-3

Update examples to new multi-line output format

@commitlint/config-pnpm-scopes/readme.md


9. @commitlint/config-rush-scopes/readme.md 📝 Documentation +6/-3

Update examples to new multi-line output format

@commitlint/config-rush-scopes/readme.md


10. docs/guides/local-setup.md 📝 Documentation +2/-1

Update example output to new multi-line format

docs/guides/local-setup.md


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented Apr 22, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (1)

Grey Divider


Action required

1. URL-in-body regression test missing 📎 Requirement gap ☼ Reliability
Description
The PR adds/updates tests for the new input banner output but does not add the required regression
test ensuring a long URL line in the commit body is parsed as body (not footer) and attributed to
body-max-line-length. Without this, the URL-in-body footer misclassification bug can persist or
regress undetected.
Code

@commitlint/format/src/format.test.ts[R56-140]

+	expect(actual).toStrictEqual(
+		"⧗   --- input ---\nfeat(cli): this is a valid header\n\nThis is a valid body\n\nSigned-off-by: tester\n✔   found 0 problems, 0 warnings",
+	);
+});
+
+test("returns legacy output with full commit message if verbose and legacyOutput", () => {
+	const actual = format(
+		{
+			results: [
+				{
+					errors: [],
+					warnings: [],
+					input:
+						"feat(cli): this is a valid header\n\nThis is a valid body\n\nSigned-off-by: tester",
+				},
+			],
+		},
+		{
+			verbose: true,
+			color: false,
+			legacyOutput: true,
+		},
+	);
+
	expect(actual).toStrictEqual(
		"⧗   input: feat(cli): this is a valid header\n\nThis is a valid body\n\nSigned-off-by: tester\n✔   found 0 problems, 0 warnings",
	);
});

+test('returns input banner with errors and multi-line input', () => {
+	const actual = format(
+		{
+			results: [
+				{
+					errors: [
+						{
+							level: 2,
+							name: 'type-enum',
+							message:
+								'type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test]',
+						},
+					],
+					warnings: [],
+					input: 'foo: this is an invalid header\n\nThis is a body\n\nSigned-off-by: tester',
+				},
+			],
+		},
+		{
+			color: false,
+		}
+	);
+
+	expect(actual).toStrictEqual(
+		'⧗   --- input ---\nfoo: this is an invalid header\n\nThis is a body\n\nSigned-off-by: tester\n✖   type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test] [type-enum]\n\n✖   found 1 problems, 0 warnings'
+	);
+});
+
+test('returns legacy input banner with errors and multi-line input', () => {
+	const actual = format(
+		{
+			results: [
+				{
+					errors: [
+						{
+							level: 2,
+							name: 'type-enum',
+							message:
+								'type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test]',
+						},
+					],
+					warnings: [],
+					input: 'foo: this is an invalid header\n\nThis is a body\n\nSigned-off-by: tester',
+				},
+			],
+		},
+		{
+			color: false,
+			legacyOutput: true,
+		}
+	);
+
+	expect(actual).toStrictEqual(
+		'⧗   input: foo: this is an invalid header\n\nThis is a body\n\nSigned-off-by: tester\n✖   type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test] [type-enum]\n\n✖   found 1 problems, 0 warnings'
+	);
+});
Evidence
PR Compliance ID 2 requires adding an automated regression test for the ticket’s URL-in-body
scenario and asserting body vs footer classification and rule attribution. The changed test
additions in this PR cover formatting output (--- input --- and legacyOutput) but do not include
a URL-in-body parsing/classification regression test.

Add regression test covering URL-in-body parsing to prevent footer misclassification
@commitlint/format/src/format.test.ts[56-140]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The required regression test for the URL-in-body parsing scenario is missing. Add a test that uses the provided example (or equivalent: subject + blank line + body lines including a long standalone URL) and asserts the URL line remains in `body` (not `footer`) and any length violation is attributed to `body-max-line-length` (not `footer-max-line-length` / `footer-leading-blank`).

## Issue Context
This PR changes CLI/format output, but the compliance checklist requires a regression test guarding against footer misclassification when body contains a URL.

## Fix Focus Areas
- @commitlint/parse/src/index.test.ts[159-221]
- @commitlint/lint/src/lint.test.ts[1-120]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Help snapshot now outdated 🐞 Bug ≡ Correctness
Description
Adding the new --legacy-output yargs option changes commitlint --help output, but the existing
inline snapshot for the help text does not include this option, so the test will fail. This will
block CI/merge even though runtime behavior is fine.
Code

@commitlint/cli/src/cli.ts[R138-141]

+		"legacy-output": {
+			description: "use the legacy input output format (single-line 'input: ...')",
+			type: "boolean",
+		},
Evidence
@commitlint/cli/src/cli.ts registers a new yargs option legacy-output, and yargs includes
registered options in the help output. The should print help test uses an inline snapshot that
currently lists options through --verbose and --strict but has no --legacy-output line, so the
snapshot no longer matches the generated help text.

@commitlint/cli/src/cli.ts[133-141]
@commitlint/cli/src/cli.test.ts[618-651]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
A new CLI flag `--legacy-output` was added to yargs options, which changes the `--help` output. The existing inline snapshot for the `should print help` test does not include this option, so the snapshot assertion will fail.

### Issue Context
The CLI help output is snapshot-tested, and yargs prints all registered options. Adding a new option requires updating the expected snapshot string.

### Fix Focus Areas
- @commitlint/cli/src/cli.test.ts[618-651]
- @commitlint/cli/src/cli.ts[133-141]

### What to change
- Update the inline snapshot in `should print help` to include the new `--legacy-output` line (in the correct position/order matching yargs output).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread @commitlint/format/src/format.test.ts
Comment thread @commitlint/cli/src/cli.ts
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates commitlint’s text formatter to display the commit message input starting on a new line (with an --- input --- banner) to make error output clearer and easier to copy/paste, while adding an opt-in legacy mode for the previous single-line input: display.

Changes:

  • Change the default formatted “input” output to a banner + newline style in @commitlint/format.
  • Add legacyOutput / --legacy-output to preserve the previous single-line input: ... output format.
  • Update several docs/examples and extend formatter test coverage for the new/legacy outputs.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
docs/guides/local-setup.md Updates example output to match the new multi-line input banner format.
@commitlint/types/src/format.ts Extends FormatOptions with legacyOutput?: boolean.
@commitlint/format/src/format.ts Implements the new input banner output and legacy toggle.
@commitlint/format/src/format.test.ts Adds tests for new banner output and legacy output.
@commitlint/config-rush-scopes/readme.md Updates shown CLI output to use the new input banner.
@commitlint/config-pnpm-scopes/readme.md Updates shown CLI output to use the new input banner.
@commitlint/config-nx-scopes/readme.md Updates shown CLI output to use the new input banner.
@commitlint/config-lerna-scopes/readme.md Updates shown CLI output to use the new input banner.
@commitlint/cli/src/types.ts Adds legacy-output to CLI flags typing.
@commitlint/cli/src/cli.ts Adds --legacy-output yargs option and passes through to formatter options.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread @commitlint/format/src/format.test.ts Outdated
Comment on lines 30 to 33
❯ echo "build(api): change something in api's build" | commitlint
⧗ input: build(api): change something in api's build
⧗ --- input ---
build(api): change something in api's build
✔ found 0 problems, 0 warnings
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These examples show output for a successful lint ("found 0 problems") but the CLI doesn't print anything on success unless --verbose is used (see docs/guides/local-setup.md). To keep the README accurate, either add --verbose to the example commands or remove the success output blocks.

Copilot uses AI. Check for mistakes.
Comment on lines 30 to 33
❯ echo "build(api): change something in api's build" | commitlint
⧗ input: build(api): change something in api's build
⧗ --- input ---
build(api): change something in api's build
✔ found 0 problems, 0 warnings
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These examples include output for passing commits without showing --verbose, but commitlint suppresses output on success by default. Please update the commands to include --verbose (or adjust the shown output) so the README matches actual CLI behavior.

Copilot uses AI. Check for mistakes.
Comment on lines 99 to 103
❯ echo "build(api): change something in api's build" | commitlint
⧗ input: build(api): change something in api's build
⧗ --- input ---
build(api): change something in api's build
✔ found 0 problems, 0 warnings

Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The success-case examples here show output even though commitlint prints nothing for valid messages unless --verbose is provided. Consider adding --verbose to the example commands (or removing the success output) to avoid confusing users who copy/paste.

Copilot uses AI. Check for mistakes.
Comment on lines 33 to 37
❯ echo "build(api): change something in api's build" | commitlint
⧗ input: build(api): change something in api's build
⧗ --- input ---
build(api): change something in api's build
✔ found 0 problems, 0 warnings

Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like the other config READMEs, this shows output for a passing commit without --verbose, but commitlint is silent on success by default. Please align the example commands/output (e.g., add --verbose) so the documentation reflects real behavior.

Copilot uses AI. Check for mistakes.
Comment thread docs/guides/local-setup.md
@knocte knocte force-pushed the finishPr4102 branch 4 times, most recently from 52731bb to 7f02bb0 Compare April 24, 2026 04:02
@knocte
Copy link
Copy Markdown
Contributor Author

knocte commented Apr 24, 2026

@escapedcat I think this is ready to merge (when we're ready to do the big version bump with breaking changes, not now).

The only feedback I didn't address from Copilot is:

  • wrt "docs/guides/local-setup.md", I don't think there's real need to document this, let's not pollute docs with legacy flags that might disappear eventually? If this change disrupts anyone when they update to new version of commitlint, they will investigate what happened and find this flag easily IMO.
  • wrt the other suggestions for the other .md files: looks like that is an improvement over an issue that was there before, so ideally it should be address in a new PR.

@knocte
Copy link
Copy Markdown
Contributor Author

knocte commented Apr 24, 2026

they will investigate what happened and find this flag easily IMO.

And by this I mean that they'll likely find about this change in the CHANGELOG/ReleaseNotes; they're not going to read the documentation ;)

@escapedcat
Copy link
Copy Markdown
Member

escapedcat commented Apr 24, 2026

I guess we don't lose anything by adding it to the docs and removing it later again. I don't think it's polluting them.

Another small feedback from Claude I think it's worth doing:

Also worth asking the author to add a CHANGELOG/release-notes blurb flagging that --legacy-output is a transition flag slated for removal in the next major after this one — sets expectations up front.

So maybe write a commit body and state this plan?

@abitrolly
Copy link
Copy Markdown
Contributor

@knocte thanks for picking this up! 👍

abitrolly and others added 6 commits April 26, 2026 11:23
This will be less confusing to read, and also easier to test
and copy/paste.
Previous commit adtoped a new output format by default, so
we need to reflect it in the docs like it's done here.
As instructed by GitHub Copilot, we add a new testcase.
To restore old single-line input output.
@knocte
Copy link
Copy Markdown
Contributor Author

knocte commented Apr 26, 2026

I guess we don't lose anything by adding it to the docs and removing it later again. I don't think it's polluting them.

Another small feedback from Claude I think it's worth doing:

Alright, added a commit to address this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

5 participants