Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
35 changes: 6 additions & 29 deletions bin/cli.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,21 @@ import process from 'node:process';
import { Command, Option } from 'commander';

import commands from './commands/index.mjs';
import { errorWrap } from './utils.mjs';
import { LogLevel } from '../src/logger/constants.mjs';
import logger from '../src/logger/index.mjs';

const logLevelOption = new Option('--log-level <level>', 'Log level')
.choices(Object.keys(LogLevel))
.default('info');

const program = new Command()
.name('@nodejs/doc-kit')
.description('CLI tool to generate the Node.js API documentation')
.addOption(logLevelOption)
.addOption(
new Option('--log-level <level>', 'Log level')
.default('info')
.choices(Object.keys(LogLevel))
)
.hook('preAction', cmd => logger.setLogLevel(cmd.opts().logLevel));

// Registering commands
commands.forEach(({ name, description, options, action }) => {
const cmd = program.command(name).description(description);

// Add options to the command
Object.values(options).forEach(({ flags, desc, prompt }) => {
const option = new Option(flags.join(', '), desc).default(
prompt.initialValue
);

if (prompt.required) {
option.makeOptionMandatory();
}

if (prompt.type === 'multiselect') {
option.choices(prompt.options.map(({ value }) => value));
}

cmd.addOption(option);
});

// Set the action for the command
cmd.action(errorWrap(action));
});
commands.forEach(command => program.addCommand(command));

// Parse and execute command-line arguments
program.parse(process.argv);
30 changes: 0 additions & 30 deletions bin/commands/__tests__/index.test.mjs

This file was deleted.

223 changes: 76 additions & 147 deletions bin/commands/generate.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { cpus } from 'node:os';
import { resolve } from 'node:path';

import { Command, Option } from 'commander';
import { coerce } from 'semver';

import { NODE_CHANGELOG_URL, NODE_VERSION } from '../../src/constants.mjs';
Expand All @@ -10,153 +10,82 @@ import logger from '../../src/logger/index.mjs';
import { parseTypeMap } from '../../src/parsers/json.mjs';
import { parseChangelog, parseIndex } from '../../src/parsers/markdown.mjs';
import { DEFAULT_TYPE_MAP } from '../../src/utils/parser/constants.mjs';
import { errorWrap } from '../utils.mjs';

const availableGenerators = Object.keys(publicGenerators);
export default new Command('generate')
.description('Generate API docs')
.addOption(
new Option(
'-i, --input <patterns...>',
'Input file patterns (glob)'
).makeOptionMandatory()
)
.addOption(
new Option('--ignore <patterns...>', 'Ignore file patterns (glob)')
)
.addOption(new Option('-o, --output <directory>', 'The output directory'))
.addOption(
new Option(
'-p, --threads <number>',
'Number of threads to use (minimum: 1)'
)
.default(cpus().length)
.argParser(parseInt)
)
.addOption(
new Option(
'--chunk-size <number>',
'Number of items to process per worker thread (minimum: 1)'
)
.default(10)
.argParser(parseInt)
)
.addOption(
new Option('-v, --version <semver>', 'Target Node.js version').default(
NODE_VERSION
)
)
.addOption(
new Option('-c, --changelog <url>', 'Changelog URL or path').default(
NODE_CHANGELOG_URL
)
)
.addOption(
new Option('--git-ref', 'Git ref URL').default(
'https://github.com/nodejs/node/tree/HEAD'
)
)
.addOption(
new Option('-t, --target <generator...>', 'Target generator(s)')
.makeOptionMandatory()
.choices(Object.keys(publicGenerators))
)
.addOption(new Option('--index <url>', 'index.md URL or path'))
.addOption(
new Option('--type-map <url>', 'Type map URL or path').default(
DEFAULT_TYPE_MAP
)
)
.action(
errorWrap(async opts => {
logger.debug('Starting doc-kit', opts);

/**
* @type {import('./types').Command}
*/
export default {
description: 'Generate API docs',
name: 'generate',
options: {
input: {
flags: ['-i', '--input <patterns...>'],
desc: 'Input file patterns (glob)',
prompt: {
type: 'text',
message: 'Enter input glob patterns',
variadic: true,
required: true,
},
},
ignore: {
flags: ['--ignore [patterns...]'],
desc: 'Ignore patterns (comma-separated)',
prompt: {
type: 'text',
message: 'Enter ignore patterns',
variadic: true,
},
},
output: {
flags: ['-o', '--output <dir>'],
desc: 'Output directory',
prompt: { type: 'text', message: 'Enter output directory' },
},
threads: {
flags: ['-p', '--threads <number>'],
desc: 'Number of threads to use (minimum: 1)',
prompt: {
type: 'text',
message: 'How many threads to allow',
initialValue: String(cpus().length),
},
},
chunkSize: {
flags: ['--chunk-size <number>'],
desc: 'Number of items to process per worker thread (default: auto)',
prompt: {
type: 'text',
message: 'Items per worker thread',
initialValue: '10',
},
},
version: {
flags: ['-v', '--version <semver>'],
desc: 'Target Node.js version',
prompt: {
type: 'text',
message: 'Enter Node.js version',
initialValue: NODE_VERSION,
},
},
changelog: {
flags: ['-c', '--changelog <url>'],
desc: 'Changelog URL or path',
prompt: {
type: 'text',
message: 'Enter changelog URL',
initialValue: NODE_CHANGELOG_URL,
},
},
gitRef: {
flags: ['--git-ref <url>'],
desc: 'Git ref/commit URL',
prompt: {
type: 'text',
message: 'Enter Git ref URL',
initialValue: 'https://github.com/nodejs/node/tree/HEAD',
},
},
target: {
flags: ['-t', '--target [modes...]'],
desc: 'Target generator modes',
prompt: {
required: true,
type: 'multiselect',
message: 'Choose target generators',
options: availableGenerators.map(g => ({
value: g,
label: `${publicGenerators[g].name || g} (v${publicGenerators[g].version}) - ${publicGenerators[g].description}`,
})),
},
},
index: {
flags: ['--index <path>'],
desc: 'The index document, for getting the titles of various API docs',
prompt: {
message: 'Path to doc/api/index.md',
type: 'text',
},
},
typeMap: {
flags: ['--type-map <path>'],
desc: 'The mapping of types to links',
prompt: {
message: 'Path to doc/api/type_map.json',
type: 'text',
initialValue: DEFAULT_TYPE_MAP,
},
},
},
const { runGenerators } = createGenerator();

/**
* @typedef {Object} Options
* @property {Array<string>|string} input - Specifies the glob/path for input files.
* @property {Array<string>|string} [ignore] - Specifies the glob/path for ignoring files.
* @property {Array<keyof AvailableGenerators>} target - Specifies the generator target mode.
* @property {string} version - Specifies the target Node.js version.
* @property {string} changelog - Specifies the path to the Node.js CHANGELOG.md file.
* @property {string} typeMap - Specifies the path to the Node.js Type Map.
* @property {string} index - Specifies the path to the index document.
* @property {string} [gitRef] - Git ref/commit URL.
* @property {number} [threads] - Number of threads to allow.
* @property {number} [chunkSize] - Number of items to process per worker thread.
*
* Handles the action for generating API docs
* @param {Options} opts - The options to generate API docs.
* @returns {Promise<void>}
*/
async action(opts) {
logger.debug('Starting doc-kit', opts);
logger.debug('Starting generation', { targets: opts.target });

const { runGenerators } = createGenerator();

logger.debug('Starting generation', { targets: opts.target });

await runGenerators({
generators: opts.target,
input: opts.input,
ignore: opts.ignore,
output: opts.output && resolve(opts.output),
version: coerce(opts.version),
releases: await parseChangelog(opts.changelog),
gitRef: opts.gitRef,
threads: Math.max(parseInt(opts.threads, 10), 1),
chunkSize: Math.max(parseInt(opts.chunkSize, 10), 1),
index: await parseIndex(opts.index),
typeMap: await parseTypeMap(opts.typeMap),
});
},
};
await runGenerators({
generators: opts.target,
input: opts.input,
ignore: opts.ignore,
output: opts.output,
version: coerce(opts.version),
releases: await parseChangelog(opts.changelog),
gitRef: opts.gitRef,
threads: Math.max(opts.threads, 1),
chunkSize: Math.max(opts.chunkSize, 1),
index: await parseIndex(opts.index),
typeMap: await parseTypeMap(opts.typeMap),
});
})
);
3 changes: 1 addition & 2 deletions bin/commands/index.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import generate from './generate.mjs';
import interactive from './interactive.mjs';

export default [generate, interactive];
export default [generate];
Loading
Loading