gocodebox/lifterlms

View on GitHub
packages/dev/src/cmds/docgen.js

Summary

Maintainability
A
3 hrs
Test Coverage
const path = require( 'path' ),
    { Command } = require( 'commander' ), // Including for the type definition.
    { readFileSync, writeFileSync } = require( 'fs' );

/**
 * Generate a doc section for the specified command.
 *
 * @since 0.0.1
 * @since 0.1.0 Include beforeHelp and afterHelp data added by `Command.addHelpText()`.
 *
 * @param {Command} command    A commander command instance.
 * @param {string}  parentName Name of the parent command (used for subcommands).
 * @return {string} Documentation section MD text.
 */
function createCommandSection( command, parentName = '' ) {
    parentName = parentName ? `${ parentName } ` : '';

    const commandName = command.name();
    let text = '';

    if ( ! command.commands.length ) {
        text = `\n### ${ parentName }${ commandName }\n\n`;

        text += '```bash\n';
        command.emit( 'beforeHelp', { write: ( helpStr ) => text += helpStr } );
        text += command.helpInformation();
        command.emit( 'afterHelp', { write: ( helpStr ) => text += helpStr } );
        text += '\n```\n';
    } else {
        command.commands.forEach( ( subcommand ) => {
            text += createCommandSection( subcommand, commandName );
        } );
    }

    return text;
}

module.exports = {
    command: 'docgen',
    description: 'Generates documentation for the CLI.',
    action: ( env, { parent } ) => {
        const readmeFile = path.join( __dirname, '../../README.md' ),
            readmeContents = readFileSync( readmeFile, 'utf8' ),
            startToken = '<!-- START TOKEN(Autogenerated API docs) -->',
            endToken = '<!-- END TOKEN(Autogenerated API docs) -->',
            docsToken = '<!-- DOCS TOKEN -->';

        let newReadme = [],
            addLine = true;

        readmeContents.split( '\n' ).forEach( ( line ) => {
            if ( line === startToken ) {
                newReadme.push( line );
                newReadme.push( docsToken );
                addLine = false;
            } else if ( line === endToken ) {
                addLine = true;
            }

            if ( addLine ) {
                newReadme.push( line );
            }
        } );

        newReadme = newReadme.join( '\n' );

        let docs = '';
        parent.commands.forEach( ( command ) => {
            docs += createCommandSection( command );
        } );

        writeFileSync( readmeFile, newReadme.replace( docsToken, docs ) );
    },
};