mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
refactor: make config loading asynchronous
Workaround for https://github.com/tschaub/mock-fs/issues/377, which causes `fs.readFileSync()` to fail on Node.js >=20.5.0. Fixes #2097.
This commit is contained in:
parent
3e4f5fc557
commit
a82263f925
@ -18,7 +18,7 @@
|
|||||||
*
|
*
|
||||||
* @alias module:@jsdoc/core.config
|
* @alias module:@jsdoc/core.config
|
||||||
*/
|
*/
|
||||||
import { cosmiconfigSync, defaultLoaders } from 'cosmiconfig';
|
import { cosmiconfig, defaultLoaders } from 'cosmiconfig';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import stripBom from 'strip-bom';
|
import stripBom from 'strip-bom';
|
||||||
import stripJsonComments from 'strip-json-comments';
|
import stripJsonComments from 'strip-json-comments';
|
||||||
@ -94,7 +94,7 @@ function loadYaml(filepath, content) {
|
|||||||
return defaultLoaders['.yaml'](filepath, stripBom(content));
|
return defaultLoaders['.yaml'](filepath, stripBom(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
const explorerSync = cosmiconfigSync(MODULE_NAME, {
|
const explorer = cosmiconfig(MODULE_NAME, {
|
||||||
cache: false,
|
cache: false,
|
||||||
loaders: {
|
loaders: {
|
||||||
'.json': loadJson,
|
'.json': loadJson,
|
||||||
@ -113,13 +113,13 @@ const explorerSync = cosmiconfigSync(MODULE_NAME, {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
export function loadSync(filepath) {
|
export async function load(filepath) {
|
||||||
let loaded;
|
let loaded;
|
||||||
|
|
||||||
if (filepath) {
|
if (filepath) {
|
||||||
loaded = explorerSync.load(filepath);
|
loaded = await explorer.load(filepath);
|
||||||
} else {
|
} else {
|
||||||
loaded = explorerSync.search() || {};
|
loaded = (await explorer.search()) ?? {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Config(loaded.filepath, _.defaultsDeep({}, loaded.config, defaults));
|
return new Config(loaded.filepath, _.defaultsDeep({}, loaded.config, defaults));
|
||||||
|
|||||||
@ -31,94 +31,94 @@ describe('@jsdoc/core/lib/config', () => {
|
|||||||
expect(config).toBeObject();
|
expect(config).toBeObject();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('loadSync', () => {
|
describe('load', () => {
|
||||||
it('is a function', () => {
|
it('is a function', () => {
|
||||||
expect(config.loadSync).toBeFunction();
|
expect(config.load).toBeFunction();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns an object with `config` and `filepath` properties', () => {
|
it('returns an object with `config` and `filepath` properties', async () => {
|
||||||
mockFs({
|
mockFs({
|
||||||
'conf.json': '{}',
|
'conf.json': '{}',
|
||||||
});
|
});
|
||||||
|
|
||||||
const conf = config.loadSync('conf.json');
|
const conf = await config.load('conf.json');
|
||||||
|
|
||||||
expect(conf.config).toBeObject();
|
expect(conf.config).toBeObject();
|
||||||
expect(conf.filepath).toEndWith('conf.json');
|
expect(conf.filepath).toEndWith('conf.json');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('loads settings from the specified filepath if there is one', () => {
|
it('loads settings from the specified filepath if there is one', async () => {
|
||||||
mockFs({
|
mockFs({
|
||||||
'conf.json': '{"foo":"bar"}',
|
'conf.json': '{"foo":"bar"}',
|
||||||
});
|
});
|
||||||
|
|
||||||
const conf = config.loadSync('conf.json');
|
const conf = await config.load('conf.json');
|
||||||
|
|
||||||
expect(conf.config.foo).toBe('bar');
|
expect(conf.config.foo).toBe('bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('finds the config file when no filepath is specified', () => {
|
it('finds the config file when no filepath is specified', async () => {
|
||||||
mockFs({
|
mockFs({
|
||||||
'package.json': '{"jsdoc":{"foo":"bar"}}',
|
'package.json': '{"jsdoc":{"foo":"bar"}}',
|
||||||
});
|
});
|
||||||
|
|
||||||
const conf = config.loadSync();
|
const conf = await config.load();
|
||||||
|
|
||||||
expect(conf.config.foo).toBe('bar');
|
expect(conf.config.foo).toBe('bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parses JSON config files that have an extension and contain comments', () => {
|
it('parses JSON config files that have an extension and contain comments', async () => {
|
||||||
mockFs({
|
mockFs({
|
||||||
'.jsdocrc.json': '// comment\n{"foo":"bar"}',
|
'.jsdocrc.json': '// comment\n{"foo":"bar"}',
|
||||||
});
|
});
|
||||||
|
|
||||||
const conf = config.loadSync();
|
const conf = await config.load();
|
||||||
|
|
||||||
expect(conf.config.foo).toBe('bar');
|
expect(conf.config.foo).toBe('bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parses JSON files that start with a BOM', () => {
|
it('parses JSON files that start with a BOM', async () => {
|
||||||
mockFs({
|
mockFs({
|
||||||
'.jsdocrc.json': '\uFEFF{"foo":"bar"}',
|
'.jsdocrc.json': '\uFEFF{"foo":"bar"}',
|
||||||
});
|
});
|
||||||
|
|
||||||
const conf = config.loadSync();
|
const conf = await config.load();
|
||||||
|
|
||||||
expect(conf.config.foo).toBe('bar');
|
expect(conf.config.foo).toBe('bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parses YAML files that start with a BOM', () => {
|
it('parses YAML files that start with a BOM', async () => {
|
||||||
mockFs({
|
mockFs({
|
||||||
'.jsdocrc.yaml': '\uFEFF{"foo":"bar"}',
|
'.jsdocrc.yaml': '\uFEFF{"foo":"bar"}',
|
||||||
});
|
});
|
||||||
|
|
||||||
const conf = config.loadSync();
|
const conf = await config.load();
|
||||||
|
|
||||||
expect(conf.config.foo).toBe('bar');
|
expect(conf.config.foo).toBe('bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('provides the default config if the user config is an empty object', () => {
|
it('provides the default config if the user config is an empty object', async () => {
|
||||||
mockFs({
|
mockFs({
|
||||||
'.jsdocrc.json': '{}',
|
'.jsdocrc.json': '{}',
|
||||||
});
|
});
|
||||||
|
|
||||||
const conf = config.loadSync();
|
const conf = await config.load();
|
||||||
|
|
||||||
expect(conf.config).toEqual(config.defaults);
|
expect(conf.config).toEqual(config.defaults);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('provides the default config if there is no user config', () => {
|
it('provides the default config if there is no user config', async () => {
|
||||||
const conf = config.loadSync();
|
const conf = await config.load();
|
||||||
|
|
||||||
expect(conf.config).toEqual(config.defaults);
|
expect(conf.config).toEqual(config.defaults);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('merges nested defaults with nested user settings as expected', () => {
|
it('merges nested defaults with nested user settings as expected', async () => {
|
||||||
mockFs({
|
mockFs({
|
||||||
'.jsdocrc.json': '{"tags":{"foo":"bar"}}',
|
'.jsdocrc.json': '{"tags":{"foo":"bar"}}',
|
||||||
});
|
});
|
||||||
|
|
||||||
const conf = config.loadSync();
|
const conf = await config.load();
|
||||||
|
|
||||||
expect(conf.config.tags.allowUnknownTags).toBe(config.defaults.tags.allowUnknownTags);
|
expect(conf.config.tags.allowUnknownTags).toBe(config.defaults.tags.allowUnknownTags);
|
||||||
expect(conf.config.tags.foo).toBe('bar');
|
expect(conf.config.tags.foo).toBe('bar');
|
||||||
|
|||||||
@ -85,7 +85,7 @@ export default (() => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// TODO: docs
|
// TODO: docs
|
||||||
cli.loadConfig = () => {
|
cli.loadConfig = async () => {
|
||||||
const env = dependencies.get('env');
|
const env = dependencies.get('env');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -98,7 +98,7 @@ export default (() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
env.conf = config.loadSync(env.opts.configure).config;
|
env.conf = (await config.load(env.opts.configure)).config;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
cli.exit(1, `Cannot parse the config file: ${e}\n${FATAL_ERROR_MESSAGE}`);
|
cli.exit(1, `Cannot parse the config file: ${e}\n${FATAL_ERROR_MESSAGE}`);
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,9 @@ import cli from './cli.js';
|
|||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
env.args = process.argv.slice(2);
|
env.args = process.argv.slice(2);
|
||||||
cli.setEnv(env).setVersionInfo().loadConfig().configureLogger().logStart();
|
cli.setEnv(env).setVersionInfo();
|
||||||
|
await cli.loadConfig();
|
||||||
|
cli.configureLogger().logStart();
|
||||||
|
|
||||||
await cli.runCommand();
|
await cli.runCommand();
|
||||||
})();
|
})();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user