Skip to content

Commit

Permalink
feat: dox++
Browse files Browse the repository at this point in the history
  • Loading branch information
cha0s committed Dec 31, 2023
1 parent c68bb3b commit 95e18b9
Show file tree
Hide file tree
Showing 16 changed files with 386 additions and 123 deletions.
36 changes: 20 additions & 16 deletions packages/core/build/dox/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,24 +49,28 @@ export const hooks = {

/**
* Define CLI commands.
* @param {[Command](https://github.com/tj/commander.js/tree/master#declaring-program-variable)} program The [Commander.js](https://github.com/tj/commander.js) program.
*/
'@flecks/core.commands': (program) => ({
// So this could be invoked like:
// npx flecks something -t --blow-up blah
something: {
action: (...args) => {
// Run the command...
'@flecks/core.commands': (program, flecks) => {
const {Argument} = flecks.fleck('@flecks/core/server');
return {
// So this could be invoked like:
// npx flecks something -t --blow-up blah
something: {
action: (...args) => {
// Run the command...
},
args: [
new Argument('<somearg>', 'some argument'),
],
description: 'This command does tests and also blows up',
options: [
'-t, --test', 'Do a test',
'-b, --blow-up', 'Blow up instead of running the command',
],
},
args: [
'<somearg>',
],
description: 'This command does tests and also blows up',
options: [
'-t, --test', 'Do a test',
'-b, --blow-up', 'Blow up instead of running the command',
],
},
}),
};
},

/**
* Define configuration.
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/server/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const debug = D('@flecks/core/commands');
const debugSilly = debug.extend('silly');
const flecksRoot = normalize(FLECKS_CORE_ROOT);

export {Argument};

export const processCode = (child) => new Promise((resolve, reject) => {
child.on('error', reject);
child.on('exit', (code) => {
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ defaultOptions.sorted = true;
export {dump as dumpYml, load as loadYml} from 'js-yaml';

export {
Argument,
default as commands,
processCode,
spawnWith,
Expand Down
16 changes: 14 additions & 2 deletions packages/dox/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,27 @@
"build",
"server.js",
"server.js.map",
"src"
"src",
"website"
],
"dependencies": {
"@babel/core": "^7.17.2",
"@babel/traverse": "^7.17.0",
"@babel/types": "^7.17.0",
"@docusaurus/core": "3.0.1",
"@docusaurus/module-type-aliases": "3.0.1",
"@docusaurus/preset-classic": "3.0.1",
"@docusaurus/types": "3.0.1",
"@flecks/core": "^2.0.3",
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"comment-parser": "^1.3.0",
"glob": "^7.2.0"
"glob": "^7.2.0",
"prism-react-renderer": "^2.3.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"remark-html": "^16.0.1",
"rimraf": "^5.0.5"
},
"devDependencies": {
"@flecks/fleck": "^2.0.3"
Expand Down
63 changes: 0 additions & 63 deletions packages/dox/src/commands.js

This file was deleted.

86 changes: 86 additions & 0 deletions packages/dox/src/server/commands.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import {
access,
cp,
mkdir,
rename,
rmdir,
} from 'fs/promises';
import {dirname, join} from 'path';

import {
generate,
resolveSiteDir,
spawn,
} from './docusaurus';

const {
FLECKS_CORE_ROOT = process.cwd(),
} = process.env;

export default (program, flecks) => {
const {Argument} = flecks.fleck('@flecks/core/server');
const commands = {};
const siteDirArgument = new Argument('[siteDir]', 'Docusaurus directory', 'website');
siteDirArgument.defaultValue = 'website';
commands.docusaurus = {
description: 'create a documentation website for this project',
action: async (subcommand, siteDir) => {
const resolvedSiteDir = resolveSiteDir(siteDir);
let siteDirExisted = false;
try {
const result = await mkdir(resolvedSiteDir);
if (undefined === result) {
await rmdir(resolvedSiteDir);
}
}
catch (error) {
siteDirExisted = true;
}
switch (subcommand) {
case 'build':
if (!siteDirExisted) {
throw new Error(`There's no website directory at ${resolvedSiteDir} to build!`);
}
await generate(flecks, resolvedSiteDir);
spawn('build', resolvedSiteDir);
break;
case 'create': {
if (siteDirExisted) {
throw new Error(`A website directory at ${resolvedSiteDir} already exists!`);
}
const templateDirectory = dirname(
__non_webpack_require__.resolve('@flecks/dox/website/sidebars.js'),
);
await cp(templateDirectory, resolvedSiteDir, {recursive: true});
// Copy the docusaurus config if it doesn't already exist.
try {
await access(join(FLECKS_CORE_ROOT, 'build', 'docusaurus.config.js'));
}
catch (error) {
await rename(
join(resolvedSiteDir, 'docusaurus.config.js'),
join(FLECKS_CORE_ROOT, 'build', 'docusaurus.config.js'),
);
}
// eslint-disable-next-line no-console
console.error(`website directory created at ${resolvedSiteDir}!`);
break;
}
case 'start':
if (!siteDirExisted) {
throw new Error(`There's no website directory at ${resolvedSiteDir} to start!`);
}
await generate(flecks, resolvedSiteDir);
spawn('start', resolvedSiteDir);
break;
default:
break;
}
},
args: [
new Argument('subcommand', 'Docusaurus command to run').choices(['build', 'create', 'start']),
siteDirArgument,
],
};
return commands;
};
124 changes: 124 additions & 0 deletions packages/dox/src/server/docusaurus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import {mkdir, writeFile} from 'fs/promises';
import {isAbsolute, join, resolve} from 'path';

import {spawnWith} from '@flecks/core/server';
import {themes as prismThemes} from 'prism-react-renderer';
import {rimraf} from 'rimraf';

import {
generateBuildConfigsPage,
generateConfigPage,
generateHookPage,
generateTodoPage,
} from './generate';
import {parseFlecks} from './parser';

const {
FLECKS_CORE_ROOT = process.cwd(),
} = process.env;

export function configDefaults() {
/** @type {import('@docusaurus/types').Config} */
const config = {
tagline: 'built with flecks',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
i18n: {
defaultLocale: 'en',
locales: ['en'],
},
presets: [
['classic', {
docs: {
sidebarPath: './sidebars.js',
},
pages: {
path: 'pages',
},
}],
],
themeConfig: {
// navbar: {
// title: 'flecks',
// logo: {
// alt: 'flecks logo',
// src: 'img/flecks.svg',
// },
// items: [
// ],
// },
footer: {
style: 'dark',
copyright: 'Built with flecks and Docusaurus.',
},
prism: {
theme: prismThemes.github,
darkTheme: prismThemes.dracula,
},
},
};
return config;
}

export function resolveSiteDir(siteDir) {
return isAbsolute(siteDir)
? siteDir
: resolve(FLECKS_CORE_ROOT, siteDir);
}

export async function generate(flecks, siteDir) {
// Generate "docs".
const docsDirectory = join(siteDir, 'docs', 'flecks');
await rimraf(docsDirectory);
const generatedDirectory = join(docsDirectory, '@flecks', 'dox');
await mkdir(generatedDirectory, {recursive: true});
const state = await parseFlecks(flecks);
const hookPage = generateHookPage(state.hooks, flecks);
const todoPage = generateTodoPage(state.todos, flecks);
const buildConfigsPage = generateBuildConfigsPage(state.buildConfigs);
const configPage = generateConfigPage(state.configs);
await writeFile(join(generatedDirectory, 'hooks.md'), hookPage);
await writeFile(join(generatedDirectory, 'TODO.md'), todoPage);
await writeFile(join(generatedDirectory, 'build-configs.md'), buildConfigsPage);
await writeFile(join(generatedDirectory, 'config.mdx'), configPage);
}

export function spawn(subcommand, siteDir) {
const args = [];
switch (subcommand) {
case 'start':
args.push('start', '--no-open');
break;
case 'build':
args.push('build', '--out-dir', join(FLECKS_CORE_ROOT, 'dist', 'dox'));
break;
default: {
const docusaurusCall = `npx docusaurus <subcommand> --config ${join(FLECKS_CORE_ROOT, 'build', 'docusaurus.config.js')}`;
throw new Error(`@flecks/dox only supports the 'build' and 'start' subcommands. You can run docusaurus yourself with:\n\n${docusaurusCall}`);
}
}
args.push('--config', join(FLECKS_CORE_ROOT, 'build', 'docusaurus.config.js'));
const cacheDirectory = join(FLECKS_CORE_ROOT, 'node_modules', '.cache', '@flecks', 'dox');
// Spawn `docusaurus`.
const cmd = [
// `npx` doesn't propagate signals!
// 'npx', 'docusaurus',
join(FLECKS_CORE_ROOT, 'node_modules', '.bin', 'docusaurus'),
...args,
siteDir,
];
const child = spawnWith(
cmd,
{
env: {
// Override docusaurus generation directory for cleanliness.
DOCUSAURUS_GENERATED_FILES_DIR_NAME: join(cacheDirectory, '.docusaurus'),
},
},
);
// Clean up on exit.
process.on('exit', () => {
child.kill();
});
return child;
}
Loading

0 comments on commit 95e18b9

Please sign in to comment.