From 481478c2320971214b9888f806069c569985d8c5 Mon Sep 17 00:00:00 2001 From: Julian Scheid Date: Mon, 23 May 2022 01:31:56 +1200 Subject: [PATCH 1/5] 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.) --- .../comment-char/commitlint.config.js | 2 +- @commitlint/cli/package.json | 2 +- @commitlint/cli/src/cli.test.ts | 46 +++++++++++++++++-- @commitlint/cli/src/cli.ts | 24 ++++++++-- @packages/test/src/git.ts | 1 + 5 files changed, 64 insertions(+), 11 deletions(-) diff --git a/@commitlint/cli/fixtures/comment-char/commitlint.config.js b/@commitlint/cli/fixtures/comment-char/commitlint.config.js index 2292580640..98ea1686e0 100644 --- a/@commitlint/cli/fixtures/comment-char/commitlint.config.js +++ b/@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: { diff --git a/@commitlint/cli/package.json b/@commitlint/cli/package.json index a7d95c50b6..ddc77537bc 100644 --- a/@commitlint/cli/package.json +++ b/@commitlint/cli/package.json @@ -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": { @@ -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", diff --git a/@commitlint/cli/src/cli.test.ts b/@commitlint/cli/src/cli.test.ts index 324c55e409..b6996957f0 100644 --- a/@commitlint/cli/src/cli.test.ts +++ b/@commitlint/cli/src/cli.test.ts @@ -329,13 +329,51 @@ 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'); - await execa('git', ['config', '--local', 'core.commentChar', '$'], {cwd}); - await fs.writeFile(path.join(cwd, '.git', 'COMMIT_EDITMSG'), '#1234'); + 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', 'core.commentChar', '$'], {cwd}); + 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 execa('git', ['config', '--unset', 'core.commentChar'], {cwd}); + 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); }); diff --git a/@commitlint/cli/src/cli.ts b/@commitlint/cli/src/cli.ts index e95d31536a..a4074fe37d 100644 --- a/@commitlint/cli/src/cli.ts +++ b/@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'; @@ -21,6 +22,8 @@ import {CliError} from './cli-error'; const pkg = require('../package'); +const gitDefaultCommentChar = '#'; + const cli = yargs .options({ color: { @@ -221,11 +224,22 @@ 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; + 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( diff --git a/@packages/test/src/git.ts b/@packages/test/src/git.ts index e0ba9f7dbd..d0acb9d86f 100644 --- a/@packages/test/src/git.ts +++ b/@packages/test/src/git.ts @@ -35,6 +35,7 @@ async function setup(cwd: string, gitCommand = 'git') { cwd, }); await execa(gitCommand, ['config', 'commit.gpgsign', 'false'], {cwd}); + await execa(gitCommand, ['config', 'core.commentChar', '#'], {cwd}); } catch (err: any) { if (typeof err === 'object' && typeof err.message === 'object') { console.warn(`git config in ${cwd} failed`, err.message); From 33be5ab3b2abd1690cb58356dc4400386c30c47f Mon Sep 17 00:00:00 2001 From: Julian Scheid Date: Mon, 23 May 2022 22:09:53 +1200 Subject: [PATCH 2/5] fix(cli): tweaks for core.commentChar handling (#3190) - Remove useless change to test git repository setup - Add comment on git config error handling --- @commitlint/cli/src/cli.ts | 2 ++ @packages/test/src/git.ts | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/@commitlint/cli/src/cli.ts b/@commitlint/cli/src/cli.ts index a4074fe37d..4f9fd5bd21 100644 --- a/@commitlint/cli/src/cli.ts +++ b/@commitlint/cli/src/cli.ts @@ -232,6 +232,8 @@ async function main(args: MainArgs) { 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', diff --git a/@packages/test/src/git.ts b/@packages/test/src/git.ts index d0acb9d86f..e0ba9f7dbd 100644 --- a/@packages/test/src/git.ts +++ b/@packages/test/src/git.ts @@ -35,7 +35,6 @@ async function setup(cwd: string, gitCommand = 'git') { cwd, }); await execa(gitCommand, ['config', 'commit.gpgsign', 'false'], {cwd}); - await execa(gitCommand, ['config', 'core.commentChar', '#'], {cwd}); } catch (err: any) { if (typeof err === 'object' && typeof err.message === 'object') { console.warn(`git config in ${cwd} failed`, err.message); From 093c7ea2eb5b00e4c270c53bf1bf6c14062f7809 Mon Sep 17 00:00:00 2001 From: Julian Scheid Date: Mon, 23 May 2022 22:22:57 +1200 Subject: [PATCH 3/5] 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 --- @commitlint/cli/src/cli.test.ts | 3 +-- package.json | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/@commitlint/cli/src/cli.test.ts b/@commitlint/cli/src/cli.test.ts index b6996957f0..9f628f4d58 100644 --- a/@commitlint/cli/src/cli.test.ts +++ b/@commitlint/cli/src/cli.test.ts @@ -352,7 +352,7 @@ test("it doesn't use parserOpts.commentChar when using edit mode", async () => { test('it uses core.commentChar git config when using edit mode', async () => { const cwd = await gitBootstrap('fixtures/comment-char'); - await execa('git', ['config', 'core.commentChar', '$'], {cwd}); + await execa('git', ['config', '--local', 'core.commentChar', '$'], {cwd}); await fs.writeFile( path.join(cwd, '.git', 'COMMIT_EDITMSG'), 'header: foo\n\n$body\n' @@ -365,7 +365,6 @@ test('it uses core.commentChar git config when using edit mode', async () => { test('it falls back to # for core.commentChar when using edit mode', async () => { const cwd = await gitBootstrap('fixtures/comment-char'); - await execa('git', ['config', '--unset', 'core.commentChar'], {cwd}); await fs.writeFile( path.join(cwd, '.git', 'COMMIT_EDITMSG'), 'header: foo\n\n#body\n' diff --git a/package.json b/package.json index c529210375..d3e4a9f802 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,8 @@ "publish": "lerna publish --conventional-commits", "reinstall": "yarn clean && yarn install", "start": "yarn watch", - "test": "jest", - "test-ci": "jest --runInBand", + "test": "HOME=$PWD jest", + "test-ci": "HOME=$PWD jest --runInBand", "postinstall": "yarn husky install" }, "commitlint": { @@ -106,4 +106,4 @@ "resolutions": { "**/lodash": "^4.17.19" } -} \ No newline at end of file +} From f2a35817be30cec42882d493118e93f528d031d2 Mon Sep 17 00:00:00 2001 From: Julian Scheid Date: Mon, 23 May 2022 22:27:20 +1200 Subject: [PATCH 4/5] ci: try fixing HOME setting on Windows --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index d3e4a9f802..d081530120 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,8 @@ "publish": "lerna publish --conventional-commits", "reinstall": "yarn clean && yarn install", "start": "yarn watch", - "test": "HOME=$PWD jest", - "test-ci": "HOME=$PWD jest --runInBand", + "test": "env HOME=$PWD jest", + "test-ci": "env HOME=$PWD jest --runInBand", "postinstall": "yarn husky install" }, "commitlint": { From e784c4df9b21dc9b14af7f770b6132abb399c8c0 Mon Sep 17 00:00:00 2001 From: Julian Scheid Date: Mon, 23 May 2022 22:39:34 +1200 Subject: [PATCH 5/5] test: use cross-env for setting $HOME --- package.json | 5 +++-- yarn.lock | 9 ++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index d081530120..dc58ad41aa 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,8 @@ "publish": "lerna publish --conventional-commits", "reinstall": "yarn clean && yarn install", "start": "yarn watch", - "test": "env HOME=$PWD jest", - "test-ci": "env HOME=$PWD jest --runInBand", + "test": "cross-env HOME=$PWD jest", + "test-ci": "cross-env HOME=$PWD jest --runInBand", "postinstall": "yarn husky install" }, "commitlint": { @@ -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", diff --git a/yarn.lock b/yarn.lock index 8779cca1a3..c3d9a93637 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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==