Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: migrate to pure ESM #3850

Merged
merged 22 commits into from Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9f152a2
feat: migrate to pure ESM
JounQin Jan 12, 2024
4ffd49f
chore: update snapshot
JounQin Jan 15, 2024
24d3570
fix: load `parserPreset` with another `await`
JounQin Jan 15, 2024
b8b8361
test: migrate to vitest
JounQin Jan 27, 2024
4784029
test: remove no replacement `--runInBand` test-ci script
JounQin Jan 29, 2024
e189602
chore: fix code reviews
JounQin Jan 29, 2024
306b0ec
refactor(load): rewrite resolve logic
marcalexiei Jan 31, 2024
70ee03a
fix(config-nx-scopes): fix syntax error
marcalexiei Jan 31, 2024
c01c6f2
feat(resolve-extends): add resolveFrom and loadParserPreset
marcalexiei Jan 31, 2024
ce618e1
feat(load): use resolveFrom and loadParserPreset from resolve-extends
marcalexiei Jan 31, 2024
237b803
test: include only @commitlint/* packages src in coverage
marcalexiei Jan 31, 2024
79e8c8c
test: explicit import vitest utilities
marcalexiei Feb 1, 2024
25a1279
test: remove @jest/globals from dependencies
marcalexiei Feb 1, 2024
e2326a7
fix(resolve-extends): `resolveFrom` output should be platform aware
marcalexiei Feb 1, 2024
429669e
test: restore NO_COLOR to test script
marcalexiei Feb 1, 2024
6aaa6c1
chore: fix linting issues
JounQin Feb 1, 2024
7da4a8c
fix: should use fileURLToPath instead of pathname for Windows compati…
JounQin Feb 3, 2024
c945012
Apply suggestions from code review
JounQin Feb 4, 2024
af4999f
fix: should reuse `cli` instead call `yargs()`
JounQin Feb 4, 2024
0cad810
feat(cli): set terminalWidth as wrap to avoid work break on help
marcalexiei Feb 5, 2024
f214899
Update .eslintrc.cjs
JounQin Feb 5, 2024
85b095b
feat: migrate @commitlint/config-conventional to pure ESM
JounQin Feb 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 3 additions & 4 deletions .eslintrc.js → .eslintrc.cjs
Expand Up @@ -31,7 +31,7 @@ module.exports = {
'import/no-extraneous-dependencies': [
'error',
{
devDependencies: ['**/*.test.js', '**/*.test.ts'],
devDependencies: ['**/*.test.js', '**/*.test.ts', 'vitest'],
},
],
},
Expand Down Expand Up @@ -61,15 +61,14 @@ module.exports = {
},
{
files: ['*.test.ts', '*.test.js'],
env: {
jest: true,
},
extends: ['plugin:jest/recommended'],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-var-requires': 'off',
// disallow non-import statements appearing before import statements
'import/first': 'off',
'import/no-extraneous-dependencies': 'off',
'jest/no-deprecated-functions': 'off'
},
},
],
Expand Down
7 changes: 3 additions & 4 deletions .github/workflows/CI.yml
Expand Up @@ -29,13 +29,13 @@ jobs:
run: yarn build

- name: Test
run: yarn test-ci
run: yarn test
JounQin marked this conversation as resolved.
Show resolved Hide resolved

nodeJsBaselineAptCompatibility:
name: NodeJS installed from stock Ubuntu-LTS packages (not external sources)
runs-on: ubuntu-22.04
container:
image: "ubuntu:24.04"
image: 'ubuntu:24.04'
steps:
- uses: actions/checkout@v4

Expand All @@ -55,5 +55,4 @@ jobs:
run: yarn build

- name: Run Tests
run: yarn test-ci

run: yarn test
2 changes: 1 addition & 1 deletion @alias/commitlint-config-angular/index.js
@@ -1 +1 @@
module.exports = require('@commitlint/config-angular');
export {default} from '@commitlint/config-angular';
1 change: 1 addition & 0 deletions @alias/commitlint-config-angular/package.json
@@ -1,5 +1,6 @@
{
"name": "commitlint-config-angular",
"type": "module",
"version": "18.6.1",
"description": "Shareable commitlint config enforcing the angular commit convention",
"files": [
Expand Down
2 changes: 1 addition & 1 deletion @alias/commitlint-config-lerna-scopes/index.js
@@ -1 +1 @@
module.exports = require('@commitlint/config-lerna-scopes');
export {default} from '@commitlint/config-lerna-scopes';
1 change: 1 addition & 0 deletions @alias/commitlint-config-lerna-scopes/package.json
@@ -1,5 +1,6 @@
{
"name": "commitlint-config-lerna-scopes",
"type": "module",
"version": "18.6.1",
"description": "Shareable commitlint config enforcing lerna package names as scopes",
"files": [
Expand Down
2 changes: 1 addition & 1 deletion @alias/commitlint-config-nx-scopes/index.js
@@ -1 +1 @@
module.exports = require('@commitlint/config-nx-scopes');
export {default} from '@commitlint/config-nx-scopes';
1 change: 1 addition & 0 deletions @alias/commitlint-config-nx-scopes/package.json
@@ -1,5 +1,6 @@
{
"name": "commitlint-config-nx-scopes",
"type": "module",
"version": "18.6.1",
"description": "Shareable commitlint config enforcing nx project names as scopes",
"files": [
Expand Down
2 changes: 1 addition & 1 deletion @alias/commitlint-config-patternplate/index.js
@@ -1 +1 @@
module.exports = require('@commitlint/config-patternplate');
export {default} from '@commitlint/config-patternplate';
1 change: 1 addition & 0 deletions @alias/commitlint-config-patternplate/package.json
@@ -1,5 +1,6 @@
{
"name": "commitlint-config-patternplate",
"type": "module",
"version": "18.6.1",
"description": "Lint your commits, patternplate-style",
"files": [
Expand Down
3 changes: 1 addition & 2 deletions @alias/commitlint/cli.js
@@ -1,3 +1,2 @@
#!/usr/bin/env node
const pkgDir = require('@commitlint/cli');
require(pkgDir);
import '@commitlint/cli/cli.js';
9 changes: 9 additions & 0 deletions @alias/commitlint/cli.test.js
@@ -1,6 +1,15 @@
import {test, expect} from 'vitest';
import {createRequire} from 'module';
import path from 'path';
import {fileURLToPath} from 'url';

import execa from 'execa';
import {fix} from '@commitlint/test';

const require = createRequire(import.meta.url);

const __dirname = path.resolve(fileURLToPath(import.meta.url), '..');

const bin = require.resolve('./cli.js');

function cli(args, options, input) {
Expand Down
1 change: 1 addition & 0 deletions @alias/commitlint/package.json
@@ -1,5 +1,6 @@
{
"name": "commitlint",
"type": "module",
"version": "18.6.1",
"description": "Lint your commit messages",
"files": [
Expand Down
2 changes: 1 addition & 1 deletion @commitlint/cli/cli.js
@@ -1,2 +1,2 @@
#!/usr/bin/env node
require('./lib/cli.js');
import './lib/cli.js';
3 changes: 3 additions & 0 deletions @commitlint/cli/fixtures/package.json
@@ -0,0 +1,3 @@
{
"type": "commonjs"
}
File renamed without changes.
6 changes: 3 additions & 3 deletions @commitlint/cli/package.json
@@ -1,12 +1,14 @@
{
"name": "@commitlint/cli",
"type": "module",
"version": "18.6.1",
"description": "Lint your commit messages",
"files": [
"index.js",
"index.cjs",
"cli.js",
"lib"
],
"main": "index.cjs",
"bin": {
"commitlint": "./cli.js"
},
Expand Down Expand Up @@ -39,7 +41,6 @@
"devDependencies": {
"@commitlint/test": "^18.0.0",
"@commitlint/utils": "^18.6.1",
"@types/lodash.isfunction": "^3.0.8",
"@types/lodash.merge": "^4.6.8",
"@types/node": "^18.11.9",
"@types/yargs": "^17.0.29",
Expand All @@ -53,7 +54,6 @@
"@commitlint/read": "^18.6.1",
"@commitlint/types": "^18.6.1",
"execa": "^5.0.0",
"lodash.isfunction": "^3.0.9",
"resolve-from": "5.0.0",
"resolve-global": "1.0.0",
"yargs": "^17.0.0"
Expand Down
58 changes: 28 additions & 30 deletions @commitlint/cli/src/cli.test.ts
@@ -1,8 +1,16 @@
import {describe, test, expect} from 'vitest';
import {createRequire} from 'module';
import path from 'path';
import {fileURLToPath} from 'url';

import {fix, git} from '@commitlint/test';
import execa from 'execa';
import fs from 'fs-extra';
import merge from 'lodash.merge';
import path from 'path';

const require = createRequire(import.meta.url);

const __dirname = path.resolve(fileURLToPath(import.meta.url), '..');

const bin = require.resolve('../cli.js');

Expand Down Expand Up @@ -511,34 +519,24 @@ test('should print help', async () => {
[input] reads from stdin if --edit, --env, --from and --to are omitted

Options:
-c, --color toggle colored output [boolean] [default: true]
-g, --config path to the config file [string]
--print-config print resolved config
[string] [choices: "", "text", "json"]
-d, --cwd directory to execute in
[string] [default: (Working Directory)]
-e, --edit read last commit message from the specified file or
fallbacks to ./.git/COMMIT_EDITMSG [string]
-E, --env check message in the file at path given by environment
variable value [string]
-x, --extends array of shareable configurations to extend [array]
-H, --help-url help url in error message [string]
-f, --from lower end of the commit range to lint; applies if
edit=false [string]
--git-log-args additional git log arguments as space separated string,
example '--first-parent --cherry-pick' [string]
-o, --format output format of the results [string]
-p, --parser-preset configuration preset to use for
conventional-commits-parser [string]
-q, --quiet toggle console output [boolean] [default: false]
-t, --to upper end of the commit range to lint; applies if
edit=false [string]
-V, --verbose enable verbose output for reports without problems
[boolean]
-s, --strict enable strict mode; result code 2 for warnings, 3 for
errors [boolean]
-v, --version display version information [boolean]
-h, --help Show help [boolean]"
-c, --color toggle colored output [boolean] [default: true]
JounQin marked this conversation as resolved.
Show resolved Hide resolved
-g, --config path to the config file [string]
--print-config print resolved config [string] [choices: "", "text", "json"]
-d, --cwd directory to execute in [string] [default: (Working Directory)]
-e, --edit read last commit message from the specified file or fallbacks to ./.git/COMMIT_EDITMSG [string]
-E, --env check message in the file at path given by environment variable value [string]
-x, --extends array of shareable configurations to extend [array]
-H, --help-url help url in error message [string]
-f, --from lower end of the commit range to lint; applies if edit=false [string]
--git-log-args additional git log arguments as space separated string, example '--first-parent --cherry-pick' [string]
-o, --format output format of the results [string]
-p, --parser-preset configuration preset to use for conventional-commits-parser [string]
-q, --quiet toggle console output [boolean] [default: false]
-t, --to upper end of the commit range to lint; applies if edit=false [string]
-V, --verbose enable verbose output for reports without problems [boolean]
-s, --strict enable strict mode; result code 2 for warnings, 3 for errors [boolean]
-v, --version display version information [boolean]
-h, --help Show help [boolean]"
`);
});

Expand Down Expand Up @@ -600,7 +598,7 @@ describe('should print config', () => {
const actual = await cli(['--print-config=json', '--no-color'], {cwd})();

expect(actual.stdout).toMatchInlineSnapshot(
`"{"extends":[],"formatter":"@commitlint/format","plugins":{},"rules":{"type-enum":[2,"never",["foo"]]},"helpUrl":"https://github.com/conventional-changelog/commitlint/#what-is-commitlint\","prompt":{}}"`
`"{"extends":[],"formatter":"@commitlint/format","plugins":{},"rules":{"type-enum":[2,"never",["foo"]]},"helpUrl":"https://github.com/conventional-changelog/commitlint/#what-is-commitlint","prompt":{}}"`
);
});
});
Expand Down
70 changes: 44 additions & 26 deletions @commitlint/cli/src/cli.ts
@@ -1,30 +1,45 @@
import execa, {ExecaError} from 'execa';
import load from '@commitlint/load';
import lint from '@commitlint/lint';
import read from '@commitlint/read';
import isFunction from 'lodash.isfunction';
import resolveFrom from 'resolve-from';
import resolveGlobal from 'resolve-global';
import yargs, {Arguments} from 'yargs';
import {createRequire} from 'module';
import path from 'path';
import {fileURLToPath, pathToFileURL} from 'url';
import util from 'util';

import {CliFlags} from './types';
import {
import lint from '@commitlint/lint';
import load from '@commitlint/load';
import read from '@commitlint/read';
import type {
Formatter,
LintOptions,
LintOutcome,
ParserOptions,
ParserPreset,
QualifiedConfig,
Formatter,
UserConfig,
} from '@commitlint/types';
import {CliError} from './cli-error';
import type {Options} from 'conventional-commits-parser';
import execa, {ExecaError} from 'execa';
import resolveFrom from 'resolve-from';
import resolveGlobal from 'resolve-global';
import yargs, {type Arguments} from 'yargs';

import {CliFlags} from './types.js';

import {CliError} from './cli-error.js';

const require = createRequire(import.meta.url);

const __dirname = path.resolve(fileURLToPath(import.meta.url), '..');

const dynamicImport = async <T>(id: string): Promise<T> => {
const imported = await import(
path.isAbsolute(id) ? pathToFileURL(id).toString() : id
);
return ('default' in imported && imported.default) || imported;
};

const pkg = require('../package');
const pkg: typeof import('../package.json') = require('../package.json');

const gitDefaultCommentChar = '#';

const cli = yargs
const cli = yargs(process.argv.slice(2))
.options({
color: {
alias: 'c',
Expand Down Expand Up @@ -131,6 +146,12 @@ const cli = yargs
)
.strict();

/**
* avoid description words to be divided in new lines when there is enough space
* @see https://github.com/conventional-changelog/commitlint/pull/3850#discussion_r1472251234
*/
cli.wrap(cli.terminalWidth());

main(cli.argv).catch((err) => {
setTimeout(() => {
if (err.type === pkg.name) {
Expand Down Expand Up @@ -215,7 +236,7 @@ async function main(args: MainArgs): Promise<void> {
'[input] is required: supply via stdin, or --env or --edit or --from and --to',
pkg.name
);
yargs.showHelp('log');
cli.showHelp('log');
console.log(err.message);
throw err;
}
Expand All @@ -225,7 +246,7 @@ async function main(args: MainArgs): Promise<void> {
file: flags.config,
});
const parserOpts = selectParserOpts(loaded.parserPreset);
const opts: LintOptions & {parserOpts: ParserOptions} = {
const opts: LintOptions & {parserOpts: Options} = {
parserOpts: {},
plugins: {},
ignores: [],
Expand All @@ -243,7 +264,7 @@ async function main(args: MainArgs): Promise<void> {
if (loaded.defaultIgnores === false) {
opts.defaultIgnores = false;
}
const format = loadFormatter(loaded, flags);
const format = await loadFormatter(loaded, flags);

// If reading from `.git/COMMIT_EDIT_MSG`, strip comments using
// core.commentChar from git configuration, falling back to '#'.
Expand Down Expand Up @@ -431,21 +452,18 @@ function selectParserOpts(parserPreset: ParserPreset | undefined) {
return parserPreset.parserOpts;
}

function loadFormatter(config: QualifiedConfig, flags: CliFlags): Formatter {
function loadFormatter(
config: QualifiedConfig,
flags: CliFlags
): Promise<Formatter> {
const moduleName = flags.format || config.formatter || '@commitlint/format';
const modulePath =
resolveFrom.silent(__dirname, moduleName) ||
resolveFrom.silent(flags.cwd, moduleName) ||
resolveGlobal.silent(moduleName);

if (modulePath) {
const moduleInstance = require(modulePath);

if (isFunction(moduleInstance.default)) {
return moduleInstance.default;
}

return moduleInstance;
return dynamicImport<Formatter>(modulePath);
}

throw new Error(`Using format ${moduleName}, but cannot find the module.`);
Expand Down
9 changes: 5 additions & 4 deletions @commitlint/config-angular-type-enum/index.js
Expand Up @@ -11,8 +11,9 @@ const types = [
'test',
];

module.exports.rules = {
'type-enum': [2, 'always', types],
export default {
rules: {
'type-enum': [2, 'always', types],
},
value: () => types,
};

module.exports.value = () => types;
1 change: 1 addition & 0 deletions @commitlint/config-angular-type-enum/package.json
@@ -1,5 +1,6 @@
{
"name": "@commitlint/config-angular-type-enum",
"type": "module",
"version": "18.6.1",
"description": "Shareable commitlint config enforcing the angular commit convention types",
"files": [
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/config-angular/index.js
@@ -1,6 +1,6 @@
const typeEnum = require('@commitlint/config-angular-type-enum');
import typeEnum from '@commitlint/config-angular-type-enum';

module.exports = {
export default {
parserPreset: {parserOpts: {headerPattern: /^(\w*)(?:\((.*)\))?!?: (.*)$/}},
rules: {
'subject-exclamation-mark': [2, 'never'],
Expand Down