UNPKG

@code-pushup/cli

Version:

A CLI to run all kinds of code quality measurements to align your team with company goals

105 lines 3.98 kB
/* eslint-disable max-lines-per-function */ import { blue, dim, green } from 'ansis'; import { createRequire } from 'node:module'; import yargs, {} from 'yargs'; import { formatSchema } from '@code-pushup/models'; import { TERMINAL_WIDTH } from '@code-pushup/utils'; import { descriptionStyle, formatNestedValues, formatObjectValue, headerStyle, titleStyle, } from './implementation/formatting.js'; import { logErrorBeforeThrow } from './implementation/global.utils.js'; export const yargsDecorator = { 'Commands:': `${green('Commands')}:`, 'Options:': `${green('Options')}:`, 'Examples:': `${green('Examples')}:`, boolean: blue('boolean'), count: blue('count'), string: blue('string'), array: blue('array'), required: blue('required'), 'default:': `${blue('default')}:`, 'choices:': `${blue('choices')}:`, 'aliases:': `${blue('aliases')}:`, }; /** * returns configurable yargs CLI for code-pushup * * @example * yargsCli(hideBin(process.argv)) * // bootstrap CLI; format arguments * .argv; */ export function yargsCli(argv, cfg) { const { usageMessage, scriptName, noExitProcess } = cfg; const commands = cfg.commands ?? []; const middlewares = cfg.middlewares ?? []; const options = cfg.options ?? {}; const groups = cfg.groups ?? {}; const examples = cfg.examples ?? []; const cli = yargs(argv); const packageJson = createRequire(import.meta.url)('../../package.json'); // setup yargs cli .updateLocale(yargsDecorator) // take minimum of TERMINAL_WIDTH or full width of the terminal .wrap(Math.max(TERMINAL_WIDTH, cli.terminalWidth())) .help('help', descriptionStyle('Show help')) .alias('h', 'help') .showHelpOnFail(false) .version('version', dim `Show version`, packageJson.version) .check(args => { const persist = args['persist']; return persist == null || validatePersistFormat(persist); }) .parserConfiguration({ 'strip-dashed': true, }) .coerce('config', (config) => Array.isArray(config) ? config.at(-1) : config) .options(formatNestedValues(options, 'describe')); // usage message if (usageMessage) { cli.usage(titleStyle(usageMessage)); } // script name if (scriptName) { cli.scriptName(scriptName); } // add examples examples.forEach(([exampleName, description]) => cli.example(exampleName, descriptionStyle(description))); // add groups Object.entries(groups).forEach(([groupName, optionNames]) => cli.group(optionNames, headerStyle(groupName))); // add middlewares middlewares.forEach(({ middlewareFunction, applyBeforeValidation }) => { cli.middleware(logErrorBeforeThrow(middlewareFunction), applyBeforeValidation); }); // add commands commands.forEach(commandObj => { cli.command(formatObjectValue({ ...commandObj, handler: logErrorBeforeThrow(commandObj.handler), ...(typeof commandObj.builder === 'function' && { builder: logErrorBeforeThrow(commandObj.builder), }), }, 'describe')); }); // this flag should be set for tests and debugging purposes // when there is an error and exitProcess is called, it suppresses the error message // more info here: https://yargs.js.org/docs/#api-reference-exitprocessenable if (noExitProcess) { cli.exitProcess(false); } // return CLI object return cli; } function validatePersistFormat(persist) { try { if (persist.format != null) { persist.format .flatMap(format => format.split(',')) .forEach(format => formatSchema.parse(format)); } return true; } catch { throw new Error(`Invalid persist.format option. Valid options are: ${formatSchema.options.join(', ')}`); } } //# sourceMappingURL=yargs-cli.js.map