Skip to content

Commit

Permalink
fix(cli): use core.commentChar from git config with --edit flag (#…
Browse files Browse the repository at this point in the history
…3191)

* fix(cli): use core.commentChar from git config with --edit flag (#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.)

* fix(cli): tweaks for core.commentChar handling (#3190)

- Remove useless change to test git repository setup
- Add comment on git config error handling

* fix(cli): make tests independent of global git config (#3190)

- Don't apply global changes
- Set $HOME to ensure default global settings aren't picked up

* ci: try fixing HOME setting on Windows

* test: use cross-env for setting $HOME
  • Loading branch information
jscheid committed May 24, 2022
1 parent afbb11f commit e5fee05
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 14 deletions.
2 changes: 1 addition & 1 deletion @commitlint/cli/fixtures/comment-char/commitlint.config.js
@@ -1,6 +1,6 @@
module.exports = {
rules: {
'subject-empty': [2, 'never']
'body-empty': [2, 'never']
},
parserPreset: {
parserOpts: {
Expand Down
2 changes: 1 addition & 1 deletion @commitlint/cli/package.json
Expand Up @@ -41,7 +41,6 @@
"@commitlint/utils": "^17.0.0",
"@types/node": "12.20.52",
"@types/yargs": "^17.0.0",
"execa": "^5.0.0",
"fs-extra": "^10.0.0"
},
"dependencies": {
Expand All @@ -50,6 +49,7 @@
"@commitlint/load": "^17.0.0",
"@commitlint/read": "^17.0.0",
"@commitlint/types": "^17.0.0",
"execa": "^5.0.0",
"lodash": "^4.17.19",
"resolve-from": "5.0.0",
"resolve-global": "1.0.0",
Expand Down
43 changes: 40 additions & 3 deletions @commitlint/cli/src/cli.test.ts
Expand Up @@ -329,13 +329,50 @@ test('should handle --amend with signoff', async () => {
expect(commit).toBeTruthy();
}, 10000);

test('should fail with an empty message and a commentChar is set', async () => {
test('it uses parserOpts.commentChar when not using edit mode', async () => {
const cwd = await gitBootstrap('fixtures/comment-char');
const input = 'header: foo\n$body\n';

const actual = await cli([], {cwd})(input);
expect(actual.stdout).toContain('[body-empty]');
expect(actual.exitCode).toBe(1);
});

test("it doesn't use parserOpts.commentChar when using edit mode", async () => {
const cwd = await gitBootstrap('fixtures/comment-char');
await fs.writeFile(
path.join(cwd, '.git', 'COMMIT_EDITMSG'),
'header: foo\n\n$body\n'
);

const actual = await cli(['--edit', '.git/COMMIT_EDITMSG'], {cwd})();
expect(actual.stdout).not.toContain('[body-empty]');
expect(actual.exitCode).toBe(0);
});

test('it uses core.commentChar git config when using edit mode', async () => {
const cwd = await gitBootstrap('fixtures/comment-char');
await execa('git', ['config', '--local', 'core.commentChar', '$'], {cwd});
await fs.writeFile(path.join(cwd, '.git', 'COMMIT_EDITMSG'), '#1234');
await fs.writeFile(
path.join(cwd, '.git', 'COMMIT_EDITMSG'),
'header: foo\n\n$body\n'
);

const actual = await cli(['--edit', '.git/COMMIT_EDITMSG'], {cwd})();
expect(actual.stdout).toContain('[body-empty]');
expect(actual.exitCode).toBe(1);
});

test('it falls back to # for core.commentChar when using edit mode', async () => {
const cwd = await gitBootstrap('fixtures/comment-char');
await fs.writeFile(
path.join(cwd, '.git', 'COMMIT_EDITMSG'),
'header: foo\n\n#body\n'
);

const actual = await cli(['--edit', '.git/COMMIT_EDITMSG'], {cwd})();
expect(actual.stdout).toContain('[subject-empty]');
expect(actual.stdout).toContain('[body-empty]');
expect(actual.stderr).toEqual('');
expect(actual.exitCode).toBe(1);
});

Expand Down
26 changes: 21 additions & 5 deletions @commitlint/cli/src/cli.ts
@@ -1,3 +1,4 @@
import execa, {ExecaError} from 'execa';
import load from '@commitlint/load';
import lint from '@commitlint/lint';
import read from '@commitlint/read';
Expand All @@ -21,6 +22,8 @@ import {CliError} from './cli-error';

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

const gitDefaultCommentChar = '#';

const cli = yargs
.options({
color: {
Expand Down Expand Up @@ -221,11 +224,24 @@ async function main(args: MainArgs) {
}
const format = loadFormatter(loaded, flags);

// Strip comments if reading from `.git/COMMIT_EDIT_MSG` using the
// commentChar from the parser preset falling back to a `#` if that is not
// set
if (flags.edit && typeof opts.parserOpts.commentChar !== 'string') {
opts.parserOpts.commentChar = '#';
// If reading from `.git/COMMIT_EDIT_MSG`, strip comments using
// core.commentChar from git configuration, falling back to '#'.
if (flags.edit) {
try {
const {stdout} = await execa('git', ['config', 'core.commentChar']);
opts.parserOpts.commentChar = stdout.trim() || gitDefaultCommentChar;
} catch (e) {
const execaError = e as ExecaError;
// git config returns exit code 1 when the setting is unset,
// don't warn in this case.
if (!execaError.failed || execaError.exitCode !== 1) {
console.warn(
'Could not determine core.commentChar git configuration',
e
);
}
opts.parserOpts.commentChar = gitDefaultCommentChar;
}
}

const results = await Promise.all(
Expand Down
7 changes: 4 additions & 3 deletions package.json
Expand Up @@ -19,8 +19,8 @@
"publish": "lerna publish --conventional-commits",
"reinstall": "yarn clean && yarn install",
"start": "yarn watch",
"test": "jest",
"test-ci": "jest --runInBand",
"test": "cross-env HOME=$PWD jest",
"test-ci": "cross-env HOME=$PWD jest --runInBand",
"postinstall": "yarn husky install"
},
"commitlint": {
Expand Down Expand Up @@ -90,6 +90,7 @@
"@types/node": "^12.20.27",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"cross-env": "^7.0.3",
"docsify-cli": "^4.4.3",
"eslint": "^8.0.0",
"eslint-config-prettier": "^8.0.0",
Expand All @@ -106,4 +107,4 @@
"resolutions": {
"**/lodash": "^4.17.19"
}
}
}
9 changes: 8 additions & 1 deletion yarn.lock
Expand Up @@ -3915,7 +3915,14 @@ create-require@^1.1.0:
resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==

cross-spawn@^7.0.2, cross-spawn@^7.0.3:
cross-env@^7.0.3:
version "7.0.3"
resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==
dependencies:
cross-spawn "^7.0.1"

cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
Expand Down

0 comments on commit e5fee05

Please sign in to comment.