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
Changes from 1 commit
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor(load): rewrite resolve logic
  • Loading branch information
marcalexiei authored and JounQin committed Feb 15, 2024
commit 306b0ec65ba81c11ce241ab16dc4cb408ceceffa
94 changes: 38 additions & 56 deletions @commitlint/load/src/load.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import path from 'path';
import {fileURLToPath, pathToFileURL} from 'url';
import {pathToFileURL} from 'url';

import {validateConfig} from '@commitlint/config-validator';
import executeRule from '@commitlint/execute-rule';
Expand All @@ -11,7 +11,7 @@ import {
QualifiedRules,
UserConfig,
} from '@commitlint/types';
import {resolve} from 'import-meta-resolve';
import {moduleResolve} from 'import-meta-resolve';
import isPlainObject from 'lodash.isplainobject';
import merge from 'lodash.merge';
import uniq from 'lodash.uniq';
Expand All @@ -20,82 +20,61 @@ import {loadConfig} from './utils/load-config.js';
import {loadParserOpts} from './utils/load-parser-opts.js';
import loadPlugin from './utils/load-plugin.js';

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 resolveFrom = (parent: string, id: string) => {
let resolved: string | undefined;
let error: Error | undefined;
const resolveFrom = (specifier: string, parent?: string): string => {
let resolved: URL;
let resolveError: Error | undefined;
// console.info('resolveFrom parent', { specifier, parent })

for (const suffix of ['', '.js', '.json', '/index.js', '/index.json']) {
try {
resolved = resolve(
id + suffix,
pathToFileURL(path.resolve(parent, '__test__.js')).toString()
resolved = moduleResolve(
specifier + suffix,
pathToFileURL(parent ?? import.meta.url)
);
if (/^file:/.test(resolved)) {
resolved = fileURLToPath(resolved);
}
break;
return resolved.pathname;
} catch (err) {
if (!error) {
error = err as Error;
}
resolveError = err as Error;
}
}

if (resolved) {
return resolved;
}

throw (
error ||
Object.assign(new Error(`Cannot find module "${id}" from "${parent}"`), {
code: 'MODULE_NOT_FOUND',
})
);
throw resolveError;
};

const resolveParserPreset = async (resolvedParserPreset: string) => {
let finalParserPreset = resolvedParserPreset;
let finalParserOpts: unknown;
let finalError: Error | undefined;
// console.info('resolveParserPreset', resolvedParserPreset)

for (const suffix of ['', '.js', '.json', '/index.js', '/index.json']) {
try {
finalParserOpts = await dynamicImport(resolvedParserPreset + suffix);
finalParserPreset = resolvedParserPreset + suffix;
break;
} catch (err) {
if (!finalError) {
finalError = err as Error;
}
}
}
const finalParserOpts = await import(resolvedParserPreset);

if (finalError) {
throw finalError;
}
// console.info('resolveParserPreset finalParserOpts', finalParserOpts)

return {
path: `./${path.relative(process.cwd(), finalParserPreset)}`
path: `./${path.relative(process.cwd(), resolvedParserPreset)}`
.split(path.sep)
.join('/'),
parserOpts: finalParserOpts,
parserOpts: finalParserOpts.default,
};
};

/**
* formatter should be kept as is when unable to resolve it from config directory
*/
const resolveFormatter = (formatter: string, parent?: string): string => {
try {
return resolveFrom(formatter, parent);
} catch (error) {
return formatter;
}
};

export default async function load(
seed: UserConfig = {},
options: LoadOptions = {}
): Promise<QualifiedConfig> {
const cwd = typeof options.cwd === 'undefined' ? process.cwd() : options.cwd;
const loaded = await loadConfig(cwd, options.file);
const base = loaded && loaded.filepath ? path.dirname(loaded.filepath) : cwd;
const baseDirectory =
loaded && loaded.filepath ? path.dirname(loaded.filepath) : cwd;
const configFilePath = loaded?.filepath;
let config: UserConfig = {};
if (loaded) {
validateConfig(loaded.filepath || '', loaded.config);
Expand All @@ -115,18 +94,21 @@ export default async function load(

// Resolve parserPreset key
if (typeof config.parserPreset === 'string') {
const resolvedParserPreset = resolveFrom(base, config.parserPreset);
const resolvedParserPreset = resolveFrom(
config.parserPreset,
configFilePath
);

config.parserPreset = {
name: config.parserPreset,
...resolveParserPreset(resolvedParserPreset),
...(await resolveParserPreset(resolvedParserPreset)),
};
}

// Resolve extends key
const extended = await resolveExtends(config, {
prefix: 'commitlint-config',
cwd: base,
cwd: baseDirectory,
parserPreset: await config.parserPreset,
});

Expand Down Expand Up @@ -177,7 +159,7 @@ export default async function load(
? [extended.extends]
: [],
// Resolve config-relative formatter module
formatter: resolveFrom(base, extended.formatter) || extended.formatter,
formatter: resolveFormatter(extended.formatter, configFilePath),
// Resolve parser-opts from preset
parserPreset: await loadParserOpts(extended.parserPreset),
ignores: extended.ignores,
Expand Down