feat: autodoc for build config
This commit is contained in:
parent
45cf391c7d
commit
fd4050e0e9
2
TODO.md
2
TODO.md
|
@ -17,7 +17,7 @@
|
||||||
- [ ] hints for hook types
|
- [ ] hints for hook types
|
||||||
- [x] localConfig discovered by hook
|
- [x] localConfig discovered by hook
|
||||||
- [x] renamed to 'build/config'?
|
- [x] renamed to 'build/config'?
|
||||||
- [ ] automatically generated list of build config
|
- [x] automatically generated list of build config
|
||||||
- [ ] static documentation site generator
|
- [ ] static documentation site generator
|
||||||
- [ ] autogenerated config dox page
|
- [ ] autogenerated config dox page
|
||||||
- [x] remove `invokeParallel()`
|
- [x] remove `invokeParallel()`
|
||||||
|
|
|
@ -38,10 +38,26 @@ export default {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
'@flecks/core.build.config': () => [
|
'@flecks/core.build.config': () => [
|
||||||
|
/**
|
||||||
|
* Babel configuration. See: https://babeljs.io/docs/en/config-files
|
||||||
|
*/
|
||||||
'babel.config.js',
|
'babel.config.js',
|
||||||
|
/**
|
||||||
|
* ESLint defaults. The default .eslintrc.js just reads from this file so that the build
|
||||||
|
* process can dynamically configure parts of ESLint.
|
||||||
|
*/
|
||||||
['.eslint.defaults.js', {specifier: (specific) => `${specific}.eslint.defaults.js`}],
|
['.eslint.defaults.js', {specifier: (specific) => `${specific}.eslint.defaults.js`}],
|
||||||
|
/**
|
||||||
|
* ESLint configuration. See: https://eslint.org/docs/user-guide/configuring/
|
||||||
|
*/
|
||||||
['.eslintrc.js', {specifier: (specific) => `${specific}.eslintrc.js`}],
|
['.eslintrc.js', {specifier: (specific) => `${specific}.eslintrc.js`}],
|
||||||
|
/**
|
||||||
|
* Neutrino build configuration. See: https://neutrinojs.org/usage/
|
||||||
|
*/
|
||||||
['.neutrinorc.js', {specifier: (specific) => `${specific}.neutrinorc.js`}],
|
['.neutrinorc.js', {specifier: (specific) => `${specific}.neutrinorc.js`}],
|
||||||
|
/**
|
||||||
|
* Webpack (v4) configuration. See: https://v4.webpack.js.org/configuration/
|
||||||
|
*/
|
||||||
'webpack.config.js',
|
'webpack.config.js',
|
||||||
],
|
],
|
||||||
'@flecks/core.commands': commands,
|
'@flecks/core.commands': commands,
|
||||||
|
|
|
@ -3,7 +3,11 @@ import {join} from 'path';
|
||||||
|
|
||||||
import {D} from '@flecks/core';
|
import {D} from '@flecks/core';
|
||||||
|
|
||||||
import {generateHookPage, generateTodoPage} from './generate';
|
import {
|
||||||
|
generateBuildConfigsPage,
|
||||||
|
generateHookPage,
|
||||||
|
generateTodoPage,
|
||||||
|
} from './generate';
|
||||||
import {parseFlecks} from './parser';
|
import {parseFlecks} from './parser';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -26,6 +30,9 @@ export default (program, flecks) => {
|
||||||
debug('Generating TODO page...');
|
debug('Generating TODO page...');
|
||||||
const todoPage = generateTodoPage(state.todos, flecks);
|
const todoPage = generateTodoPage(state.todos, flecks);
|
||||||
debug('generated');
|
debug('generated');
|
||||||
|
debug('Generating build configs page...');
|
||||||
|
const buildConfigsPage = generateBuildConfigsPage(state.buildConfigs);
|
||||||
|
debug('generated');
|
||||||
const output = join(FLECKS_CORE_ROOT, 'dox');
|
const output = join(FLECKS_CORE_ROOT, 'dox');
|
||||||
await mkdir(output, {recursive: true});
|
await mkdir(output, {recursive: true});
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
|
@ -37,6 +44,9 @@ export default (program, flecks) => {
|
||||||
debug('Writing TODO page...');
|
debug('Writing TODO page...');
|
||||||
await writeFile(join(output, 'TODO.md'), todoPage);
|
await writeFile(join(output, 'TODO.md'), todoPage);
|
||||||
console.log('TODO.md');
|
console.log('TODO.md');
|
||||||
|
debug('Writing build configs page...');
|
||||||
|
await writeFile(join(output, 'build-configs.md'), buildConfigsPage);
|
||||||
|
console.log('build-configs.md');
|
||||||
console.groupEnd();
|
console.groupEnd();
|
||||||
console.log('');
|
console.log('');
|
||||||
/* eslint-enable no-console */
|
/* eslint-enable no-console */
|
||||||
|
|
|
@ -6,6 +6,25 @@ const makeFilenameRewriter = (filenameRewriters) => (filename, line, column) =>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const generateBuildConfigsPage = (buildConfigs) => {
|
||||||
|
const source = [];
|
||||||
|
source.push('# Build configuration files');
|
||||||
|
source.push('');
|
||||||
|
source.push('This page documents all the build configuration files in this project.');
|
||||||
|
source.push('');
|
||||||
|
if (buildConfigs.length > 0) {
|
||||||
|
buildConfigs
|
||||||
|
.sort(({config: l}, {config: r}) => (l < r ? -1 : 1))
|
||||||
|
.forEach(({config, comment}) => {
|
||||||
|
source.push(`## \`${config}\``);
|
||||||
|
source.push('');
|
||||||
|
source.push(comment);
|
||||||
|
source.push('');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return source.join('\n');
|
||||||
|
};
|
||||||
|
|
||||||
export const generateHookPage = (hooks, flecks) => {
|
export const generateHookPage = (hooks, flecks) => {
|
||||||
const {filenameRewriters} = flecks.get('@flecks/dox/server');
|
const {filenameRewriters} = flecks.get('@flecks/dox/server');
|
||||||
const rewriteFilename = makeFilenameRewriter(filenameRewriters);
|
const rewriteFilename = makeFilenameRewriter(filenameRewriters);
|
||||||
|
|
|
@ -4,6 +4,8 @@ import {dirname, join} from 'path';
|
||||||
import {transformAsync} from '@babel/core';
|
import {transformAsync} from '@babel/core';
|
||||||
import traverse from '@babel/traverse';
|
import traverse from '@babel/traverse';
|
||||||
import {
|
import {
|
||||||
|
isArrayExpression,
|
||||||
|
isArrowFunctionExpression,
|
||||||
isIdentifier,
|
isIdentifier,
|
||||||
isLiteral,
|
isLiteral,
|
||||||
isMemberExpression,
|
isMemberExpression,
|
||||||
|
@ -20,10 +22,15 @@ const flecksCorePath = dirname(__non_webpack_require__.resolve('@flecks/core/pac
|
||||||
class ParserState {
|
class ParserState {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
this.buildConfigs = [];
|
||||||
this.hooks = {};
|
this.hooks = {};
|
||||||
this.todos = [];
|
this.todos = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addBuildConfig(config, comment) {
|
||||||
|
this.buildConfigs.push({comment, config});
|
||||||
|
}
|
||||||
|
|
||||||
addImplementation(hook, filename, loc) {
|
addImplementation(hook, filename, loc) {
|
||||||
this.hooks[hook] = this.hooks[hook] || {};
|
this.hooks[hook] = this.hooks[hook] || {};
|
||||||
this.hooks[hook].implementations = this.hooks[hook].implementations || [];
|
this.hooks[hook].implementations = this.hooks[hook].implementations || [];
|
||||||
|
@ -70,6 +77,40 @@ const implementationVisitor = (fn) => ({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const FlecksBuildConfigs = (state, filename) => (
|
||||||
|
implementationVisitor((property) => {
|
||||||
|
if ('@flecks/core.build.config' === property.key.value) {
|
||||||
|
if (isArrowFunctionExpression(property.value)) {
|
||||||
|
if (isArrayExpression(property.value.body)) {
|
||||||
|
property.value.body.elements.forEach((element) => {
|
||||||
|
let config;
|
||||||
|
if (isStringLiteral(element)) {
|
||||||
|
config = element.value;
|
||||||
|
}
|
||||||
|
if (isArrayExpression(element)) {
|
||||||
|
if (element.elements.length > 0 && isStringLiteral(element.elements[0])) {
|
||||||
|
config = element.elements[0].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (config && element.leadingComments.length > 0) {
|
||||||
|
state.addBuildConfig(
|
||||||
|
config,
|
||||||
|
element.leadingComments.pop().value.split('\n')
|
||||||
|
.map((line) => line.trim())
|
||||||
|
.map((line) => line.replace(/^\*/, ''))
|
||||||
|
.map((line) => line.trim())
|
||||||
|
.filter((line) => !!line)
|
||||||
|
.join(' ')
|
||||||
|
.trim(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
const FlecksInvocations = (state, filename) => ({
|
const FlecksInvocations = (state, filename) => ({
|
||||||
CallExpression(path) {
|
CallExpression(path) {
|
||||||
if (isMemberExpression(path.node.callee)) {
|
if (isMemberExpression(path.node.callee)) {
|
||||||
|
@ -192,6 +233,7 @@ export const parseCode = async (code) => {
|
||||||
export const parseFile = async (filename, resolved, state) => {
|
export const parseFile = async (filename, resolved, state) => {
|
||||||
const buffer = await readFile(filename);
|
const buffer = await readFile(filename);
|
||||||
const ast = await parseCode(buffer.toString('utf8'));
|
const ast = await parseCode(buffer.toString('utf8'));
|
||||||
|
traverse(ast, FlecksBuildConfigs(state, resolved));
|
||||||
traverse(ast, FlecksInvocations(state, resolved));
|
traverse(ast, FlecksInvocations(state, resolved));
|
||||||
traverse(ast, FlecksImplementations(state, resolved));
|
traverse(ast, FlecksImplementations(state, resolved));
|
||||||
traverse(ast, FlecksTodos(state, resolved));
|
traverse(ast, FlecksTodos(state, resolved));
|
||||||
|
|
|
@ -37,6 +37,11 @@ export default {
|
||||||
delete neutrinoConfigs.http;
|
delete neutrinoConfigs.http;
|
||||||
},
|
},
|
||||||
'@flecks/core.build.config': () => [
|
'@flecks/core.build.config': () => [
|
||||||
|
/**
|
||||||
|
* Template file used to generate the client HTML.
|
||||||
|
*
|
||||||
|
* See: https://github.com/jantimon/html-webpack-plugin/blob/main/docs/template-option.md
|
||||||
|
*/
|
||||||
'template.ejs',
|
'template.ejs',
|
||||||
],
|
],
|
||||||
'@flecks/core.config': () => ({
|
'@flecks/core.config': () => ({
|
||||||
|
|
Loading…
Reference in New Issue
Block a user