Skip to content

Commit 4018e00

Browse files
committed
fix(cli): use core.commentChar from git config with --edit flag (conventional-changelog#3190)
When parsing `.git/COMMIT_EDITMSG` use the `core.commentChar` git setting if present, falling back to the default comment char `#` otherwise. Use the `parserOpts.commentChar` setting only when parsing other messages (e.g. from stdin.)
1 parent 5ca9cfd commit 4018e00

File tree

5 files changed

+57
-11
lines changed

5 files changed

+57
-11
lines changed

@commitlint/cli/fixtures/comment-char/commitlint.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module.exports = {
22
rules: {
3-
'subject-empty': [2, 'never']
3+
'body-empty': [2, 'never']
44
},
55
parserPreset: {
66
parserOpts: {

@commitlint/cli/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
"@commitlint/utils": "^17.0.0",
4242
"@types/node": "12.20.52",
4343
"@types/yargs": "^17.0.0",
44-
"execa": "^5.0.0",
4544
"fs-extra": "^10.0.0"
4645
},
4746
"dependencies": {
@@ -50,6 +49,7 @@
5049
"@commitlint/load": "^17.0.0",
5150
"@commitlint/read": "^17.0.0",
5251
"@commitlint/types": "^17.0.0",
52+
"execa": "^5.0.0",
5353
"lodash": "^4.17.19",
5454
"resolve-from": "5.0.0",
5555
"resolve-global": "1.0.0",

@commitlint/cli/src/cli.test.ts

+41-4
Original file line numberDiff line numberDiff line change
@@ -329,13 +329,50 @@ test('should handle --amend with signoff', async () => {
329329
expect(commit).toBeTruthy();
330330
}, 10000);
331331

332-
test('should fail with an empty message and a commentChar is set', async () => {
332+
test('it uses parserOpts.commentChar when not using edit mode', async () => {
333333
const cwd = await gitBootstrap('fixtures/comment-char');
334-
await execa('git', ['config', '--local', 'core.commentChar', '$'], {cwd});
335-
await fs.writeFile(path.join(cwd, '.git', 'COMMIT_EDITMSG'), '#1234');
334+
const input = 'header: foo\n$body\n';
335+
336+
const actual = await cli([], {cwd})(input);
337+
expect(actual.stdout).toContain('[body-empty]');
338+
expect(actual.exitCode).toBe(1);
339+
});
340+
341+
test("it doesn't use parserOpts.commentChar when using edit mode", async () => {
342+
const cwd = await gitBootstrap('fixtures/comment-char');
343+
await fs.writeFile(
344+
path.join(cwd, '.git', 'COMMIT_EDITMSG'),
345+
'header: foo\n\n$body\n'
346+
);
347+
348+
const actual = await cli(['--edit', '.git/COMMIT_EDITMSG'], {cwd})();
349+
expect(actual.stdout).not.toContain('[body-empty]');
350+
expect(actual.exitCode).toBe(0);
351+
});
352+
353+
test('it uses core.commentChar git config when using edit mode', async () => {
354+
const cwd = await gitBootstrap('fixtures/comment-char');
355+
await execa('git', ['config', 'core.commentChar', '$'], {cwd});
356+
await fs.writeFile(
357+
path.join(cwd, '.git', 'COMMIT_EDITMSG'),
358+
'header: foo\n\n$body\n'
359+
);
360+
361+
const actual = await cli(['--edit', '.git/COMMIT_EDITMSG'], {cwd})();
362+
expect(actual.stdout).toContain('[body-empty]');
363+
expect(actual.exitCode).toBe(1);
364+
});
365+
366+
test('it falls back to # for core.commentChar when using edit mode', async () => {
367+
const cwd = await gitBootstrap('fixtures/comment-char');
368+
await execa('git', ['config', 'core.commentChar', ''], {cwd});
369+
await fs.writeFile(
370+
path.join(cwd, '.git', 'COMMIT_EDITMSG'),
371+
'header: foo\n\n#body\n'
372+
);
336373

337374
const actual = await cli(['--edit', '.git/COMMIT_EDITMSG'], {cwd})();
338-
expect(actual.stdout).toContain('[subject-empty]');
375+
expect(actual.stdout).toContain('[body-empty]');
339376
expect(actual.exitCode).toBe(1);
340377
});
341378

@commitlint/cli/src/cli.ts

+13-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import execa from 'execa';
12
import load from '@commitlint/load';
23
import lint from '@commitlint/lint';
34
import read from '@commitlint/read';
@@ -21,6 +22,8 @@ import {CliError} from './cli-error';
2122

2223
const pkg = require('../package');
2324

25+
const gitDefaultCommentChar = '#';
26+
2427
const cli = yargs
2528
.options({
2629
color: {
@@ -221,11 +224,16 @@ async function main(args: MainArgs) {
221224
}
222225
const format = loadFormatter(loaded, flags);
223226

224-
// Strip comments if reading from `.git/COMMIT_EDIT_MSG` using the
225-
// commentChar from the parser preset falling back to a `#` if that is not
226-
// set
227-
if (flags.edit && typeof opts.parserOpts.commentChar !== 'string') {
228-
opts.parserOpts.commentChar = '#';
227+
// If reading from `.git/COMMIT_EDIT_MSG`, strip comments using
228+
// core.commentChar from git configuration, falling back to '#'.
229+
if (flags.edit) {
230+
try {
231+
const {stdout} = await execa('git', ['config', 'core.commentChar']);
232+
opts.parserOpts.commentChar = stdout.trim() || gitDefaultCommentChar;
233+
} catch (e) {
234+
console.warn('Could not determine core.commentChar git configuration', e);
235+
opts.parserOpts.commentChar = gitDefaultCommentChar;
236+
}
229237
}
230238

231239
const results = await Promise.all(

@packages/test/src/git.ts

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ async function setup(cwd: string, gitCommand = 'git') {
3535
cwd,
3636
});
3737
await execa(gitCommand, ['config', 'commit.gpgsign', 'false'], {cwd});
38+
await execa(gitCommand, ['config', 'core.commentChar', '#'], {cwd});
3839
} catch (err: any) {
3940
if (typeof err === 'object' && typeof err.message === 'object') {
4041
console.warn(`git config in ${cwd} failed`, err.message);

0 commit comments

Comments
 (0)