mirror of
https://github.com/documentationjs/documentation.git
synced 2026-01-25 14:26:29 +00:00
refactor: use singleton config for execution
It will be easy to not put config as parameter each time
This commit is contained in:
parent
806defa191
commit
4b711da2b2
@ -1,5 +1,4 @@
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
const exec = require('child_process').exec;
|
||||
const tmp = require('tmp');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
@ -1,42 +1,46 @@
|
||||
const path = require('path');
|
||||
const _ = require('lodash');
|
||||
const config = require('../../src/config');
|
||||
const mergeConfig = require('../../src/merge_config');
|
||||
|
||||
test('bad config', async function() {
|
||||
try {
|
||||
await mergeConfig({ config: 'DOES-NOT-EXIST' });
|
||||
} catch (err) {
|
||||
expect(err).toBeTruthy();
|
||||
}
|
||||
});
|
||||
describe('single config tests', function () {
|
||||
beforeEach(function () {
|
||||
config.reset();
|
||||
});
|
||||
|
||||
test('right merging package configuration', async function() {
|
||||
// Omit configuration from output, for simplicity
|
||||
const nc = _.curryRight(_.omit, 2)([
|
||||
'config',
|
||||
'no-package',
|
||||
'parseExtension',
|
||||
'project-homepage',
|
||||
'project-version',
|
||||
'project-description'
|
||||
]);
|
||||
return mergeConfig({
|
||||
config: path.join(__dirname, '../config_fixture/config.json'),
|
||||
'no-package': true,
|
||||
'project-name': 'cool Documentation'
|
||||
})
|
||||
.then(nc)
|
||||
.then(res => {
|
||||
expect(res).toEqual({
|
||||
'project-name': 'cool Documentation',
|
||||
foo: 'bar'
|
||||
});
|
||||
test('Should be failed on bad config', async function () {
|
||||
try {
|
||||
await mergeConfig({ config: 'DOES-NOT-EXIST' });
|
||||
} catch (err) {
|
||||
expect(err).toBeTruthy();
|
||||
return;
|
||||
}
|
||||
return Promise.reject(new Error('should be failed on bad config'));
|
||||
});
|
||||
|
||||
test('right merging package configuration', async function () {
|
||||
const list = [
|
||||
'config',
|
||||
'no-package',
|
||||
'parseExtension',
|
||||
'project-homepage',
|
||||
'project-version',
|
||||
'project-description'
|
||||
];
|
||||
await mergeConfig({
|
||||
config: path.join(__dirname, '../config_fixture/config.json'),
|
||||
'no-package': true,
|
||||
'project-name': 'cool Documentation'
|
||||
});
|
||||
});
|
||||
|
||||
test('nc(mergeConfig)', async function() {
|
||||
// Omit configuration from output, for simplicity
|
||||
const nc = _.curryRight(_.omit, 2)([
|
||||
const res = config.globalConfig;
|
||||
list.forEach(key => delete res[key]);
|
||||
expect(res).toEqual({
|
||||
'project-name': 'cool Documentation',
|
||||
foo: 'bar'
|
||||
});
|
||||
});
|
||||
|
||||
const list = [
|
||||
'config',
|
||||
'no-package',
|
||||
'parseExtension',
|
||||
@ -44,60 +48,61 @@ test('nc(mergeConfig)', async function() {
|
||||
'project-name',
|
||||
'project-version',
|
||||
'project-description'
|
||||
]);
|
||||
];
|
||||
|
||||
return Promise.all(
|
||||
[
|
||||
[
|
||||
[
|
||||
{ config: path.join(__dirname, '../config_fixture/config.json') },
|
||||
{ foo: 'bar' }
|
||||
],
|
||||
[
|
||||
{
|
||||
passThrough: true,
|
||||
config: path.join(__dirname, '../config_fixture/config.json')
|
||||
},
|
||||
{ foo: 'bar', passThrough: true }
|
||||
],
|
||||
[
|
||||
{
|
||||
config: path.join(__dirname, '../config_fixture/config_comments.json')
|
||||
},
|
||||
{ foo: 'bar' }
|
||||
],
|
||||
[
|
||||
{ config: path.join(__dirname, '../config_fixture/config.yaml') },
|
||||
{ foo: 'bar' }
|
||||
],
|
||||
[
|
||||
{ config: path.join(__dirname, '../config_fixture/config.yml') },
|
||||
{ foo: 'bar' }
|
||||
],
|
||||
[
|
||||
{ config: path.join(__dirname, '../config_fixture/config') },
|
||||
{ foo: 'bar' }
|
||||
],
|
||||
[
|
||||
{ config: path.join(__dirname, '../config_fixture/config_links.yml') },
|
||||
{ foo: 'hello [link](https://github.com/my/link) world' }
|
||||
],
|
||||
[
|
||||
{ config: path.join(__dirname, '../config_fixture/config_file.yml') },
|
||||
{
|
||||
toc: [
|
||||
{
|
||||
name: 'snowflake',
|
||||
file: path.join(__dirname, '../fixture/snowflake.md')
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
].map(pair =>
|
||||
mergeConfig(Object.assign(pair[0], { 'no-package': true }))
|
||||
.then(nc)
|
||||
.then(res => {
|
||||
expect(res).toEqual(pair[1]);
|
||||
})
|
||||
)
|
||||
);
|
||||
{ config: path.join(__dirname, '../config_fixture/config.json') },
|
||||
{ foo: 'bar' }
|
||||
],
|
||||
[
|
||||
{
|
||||
passThrough: true,
|
||||
config: path.join(__dirname, '../config_fixture/config.json')
|
||||
},
|
||||
{ foo: 'bar', passThrough: true }
|
||||
],
|
||||
[
|
||||
{
|
||||
config: path.join(__dirname, '../config_fixture/config_comments.json')
|
||||
},
|
||||
{ foo: 'bar' }
|
||||
],
|
||||
[
|
||||
{ config: path.join(__dirname, '../config_fixture/config.yaml') },
|
||||
{ foo: 'bar' }
|
||||
],
|
||||
[
|
||||
{ config: path.join(__dirname, '../config_fixture/config.yml') },
|
||||
{ foo: 'bar' }
|
||||
],
|
||||
[
|
||||
{ config: path.join(__dirname, '../config_fixture/config') },
|
||||
{ foo: 'bar' }
|
||||
],
|
||||
[
|
||||
{
|
||||
config: path.join(__dirname, '../config_fixture/config_links.yml')
|
||||
},
|
||||
{ foo: 'hello [link](https://github.com/my/link) world' }
|
||||
],
|
||||
[
|
||||
{ config: path.join(__dirname, '../config_fixture/config_file.yml') },
|
||||
{
|
||||
toc: [
|
||||
{
|
||||
name: 'snowflake',
|
||||
file: path.join(__dirname, '../fixture/snowflake.md')
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
].forEach((pair, index) => {
|
||||
test(`nc(mergeConfig) ${index}`, async function () {
|
||||
await mergeConfig(Object.assign(pair[0], { 'no-package': true }));
|
||||
const res = config.globalConfig;
|
||||
list.forEach(key => delete res[key]);
|
||||
expect(res).toEqual(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -11,6 +11,7 @@ const path = require('path');
|
||||
const fs = require('fs');
|
||||
const _ = require('lodash');
|
||||
const chdir = require('chdir');
|
||||
const config = require('../src/config');
|
||||
|
||||
const UPDATE = !!process.env.UPDATE;
|
||||
|
||||
@ -30,6 +31,10 @@ function readOptionsFromFile(file) {
|
||||
return {};
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
config.reset();
|
||||
});
|
||||
|
||||
if (fs.existsSync(path.join(__dirname, '../.git'))) {
|
||||
test('git option', async function () {
|
||||
jest.setTimeout(10000); // 10 second timeout. After update flow.js on 0.56 version the test is executed more time.
|
||||
@ -95,10 +100,8 @@ describe('html', function () {
|
||||
.sync(path.join(__dirname, 'fixture/html', '*.input.js'))
|
||||
.forEach(function (file) {
|
||||
test(path.basename(file), async function () {
|
||||
const result = await documentation.build(
|
||||
[file],
|
||||
readOptionsFromFile(file)
|
||||
);
|
||||
const options = readOptionsFromFile(file);
|
||||
const result = await documentation.build([file], options);
|
||||
const html = await outputHtml(result, {});
|
||||
const clean = html
|
||||
.sort((a, b) => a.path > b.path)
|
||||
|
||||
29
src/config.js
Normal file
29
src/config.js
Normal file
@ -0,0 +1,29 @@
|
||||
const defaultConfig = {
|
||||
// package.json ignored and don't get project infromation
|
||||
'no-package': false,
|
||||
// Extenstions which by dafault are parse
|
||||
parseExtension: ['mjs', 'js', 'jsx', 'es5', 'es6', 'vue']
|
||||
};
|
||||
|
||||
function normalaze(config, global) {
|
||||
if (config.parseExtension) {
|
||||
config.parseExtension = Array.from(
|
||||
new Set([...config.parseExtension, ...global.parseExtension])
|
||||
);
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
globalConfig: {
|
||||
...defaultConfig
|
||||
},
|
||||
reset() {
|
||||
this.globalConfig = { ...defaultConfig };
|
||||
this.globalConfig.parseExtension = [...defaultConfig.parseExtension];
|
||||
},
|
||||
add(parameters) {
|
||||
Object.assign(this.globalConfig, normalaze(parameters, this.globalConfig));
|
||||
}
|
||||
};
|
||||
@ -1,3 +1,4 @@
|
||||
const conf = require('./config');
|
||||
const yaml = require('js-yaml');
|
||||
const fs = require('fs');
|
||||
const pify = require('pify');
|
||||
@ -5,16 +6,15 @@ const readPkgUp = require('read-pkg-up');
|
||||
const path = require('path');
|
||||
const stripComments = require('strip-json-comments');
|
||||
|
||||
function processToc(config, absFilePath) {
|
||||
function normalizeToc(config, basePath) {
|
||||
if (!config || !config.toc) {
|
||||
return config;
|
||||
}
|
||||
|
||||
config.toc = config.toc.map(entry => {
|
||||
if (entry && entry.file) {
|
||||
entry.file = path.join(path.dirname(absFilePath), entry.file);
|
||||
entry.file = path.join(basePath, entry.file);
|
||||
}
|
||||
|
||||
return entry;
|
||||
});
|
||||
|
||||
@ -25,72 +25,60 @@ function processToc(config, absFilePath) {
|
||||
* Use the nearest package.json file for the default
|
||||
* values of `name` and `version` config.
|
||||
*
|
||||
* @param {Object} config the user-provided config, usually via argv
|
||||
* @param {boolean} noPackage options which prevent ge info about project from package.json
|
||||
* @returns {Promise<Object>} configuration with inferred parameters
|
||||
* @throws {Error} if the file cannot be read.
|
||||
*/
|
||||
function mergePackage(config) {
|
||||
if (config.noPackage) {
|
||||
return Promise.resolve(config);
|
||||
async function readPackage(noPackage) {
|
||||
const global = conf.globalConfig;
|
||||
if (noPackage) {
|
||||
return {};
|
||||
}
|
||||
const param = ['name', 'homepage', 'version', 'description'];
|
||||
try {
|
||||
const { pkg } = await readPkgUp();
|
||||
return param.reduce((res, key) => {
|
||||
res[`project-${key}`] = global[key] || pkg[key];
|
||||
return res;
|
||||
}, {});
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
return (
|
||||
readPkgUp()
|
||||
.then(pkg => {
|
||||
['name', 'homepage', 'version', 'description'].forEach(key => {
|
||||
config[`project-${key}`] = config[`project-${key}`] || pkg.pkg[key];
|
||||
});
|
||||
return config;
|
||||
})
|
||||
// Allow this to fail: this inference is not required.
|
||||
.catch(() => config)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge a configuration file into program config, assuming that the location
|
||||
* of the configuration file is given as one of those config.
|
||||
*
|
||||
* @param {Object} config the user-provided config, usually via argv
|
||||
* @returns {Promise<Object>} configuration, if it can be parsed
|
||||
* @param {String} config the user-provided config path, usually via argv
|
||||
* @returns {Promise<Object>} configuration, which are parsed
|
||||
* @throws {Error} if the file cannot be read.
|
||||
*/
|
||||
function mergeConfigFile(config) {
|
||||
if (config && typeof config.config === 'string') {
|
||||
const filePath = config.config;
|
||||
const ext = path.extname(filePath);
|
||||
const absFilePath = path.resolve(process.cwd(), filePath);
|
||||
return pify(fs)
|
||||
.readFile(absFilePath, 'utf8')
|
||||
.then(rawFile => {
|
||||
if (ext === '.json') {
|
||||
return Object.assign(
|
||||
{},
|
||||
config,
|
||||
processToc(JSON.parse(stripComments(rawFile)), absFilePath)
|
||||
);
|
||||
}
|
||||
return Object.assign(
|
||||
{},
|
||||
config,
|
||||
processToc(yaml.safeLoad(rawFile), absFilePath)
|
||||
);
|
||||
});
|
||||
async function readConfigFile(config) {
|
||||
if (typeof config !== 'string') {
|
||||
return {};
|
||||
}
|
||||
const filePath = config;
|
||||
const absFilePath = path.resolve(process.cwd(), filePath);
|
||||
const rawFile = await pify(fs).readFile(absFilePath, 'utf8');
|
||||
const basePath = path.dirname(absFilePath);
|
||||
|
||||
return Promise.resolve(config || {});
|
||||
let obj = null;
|
||||
if (path.extname(filePath) === '.json') {
|
||||
obj = JSON.parse(stripComments(rawFile));
|
||||
} else {
|
||||
obj = yaml.safeLoad(rawFile);
|
||||
}
|
||||
if ('noPackage' in obj) {
|
||||
obj['no-package'] = obj.noPackage;
|
||||
delete obj.noPackage;
|
||||
}
|
||||
return normalizeToc(obj, basePath);
|
||||
}
|
||||
|
||||
function mergeConfig(config) {
|
||||
config.parseExtension = (config.parseExtension || []).concat([
|
||||
'mjs',
|
||||
'js',
|
||||
'jsx',
|
||||
'es5',
|
||||
'es6',
|
||||
'vue'
|
||||
]);
|
||||
module.exports = async function mergeConfig(config = {}) {
|
||||
conf.add(config);
|
||||
conf.add(await readConfigFile(conf.globalConfig.config));
|
||||
conf.add(await readPackage(conf.globalConfig['no-package']));
|
||||
|
||||
return mergeConfigFile(config).then(mergePackage);
|
||||
}
|
||||
|
||||
module.exports = mergeConfig;
|
||||
return conf.globalConfig;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user