tiny-bin
Version:
A library for building tiny and beautiful command line apps.
51 lines (50 loc) • 2.33 kB
JavaScript
/* IMPORT */
import colors from 'tiny-colors';
import Addon from './addon.js';
import { identity, isUndefined } from './utils.js';
/* MAIN */
class Usage extends Addon {
constructor() {
/* VARIABLES */
super(...arguments);
this.usages = new Set();
}
/* API */
print(command) {
this.stdout.group('USAGE', () => {
if (this.usages.size) {
//TODO: Maybe automatically colorize these
this.usages.forEach(usage => {
this.stdout.print(usage);
});
}
else {
const isCommandDefault = (command === this.bin.command);
const binName = this.bin.config.name;
const commandName = isCommandDefault ? '' : colors.magenta(command.name);
const name = [binName, commandName].filter(identity).join(' ');
const commands = isCommandDefault && !command.handler ? colors.magenta('[command]') : '';
const args = command.arguments.getAll().map(arg => colors.yellow(arg.name)).join(' ');
const isOptionRequired = (option) => option.required && isUndefined(option.default) && !option.hidden;
const optionsGlobalRequired = !isCommandDefault ? this.bin.command.options.getAll().filter(isOptionRequired) : [];
const optionsLocalRequired = command.options.getAll().filter(isOptionRequired);
const optionsRequired = [...optionsGlobalRequired, ...optionsLocalRequired];
const options = optionsRequired.map(option => {
const flagName = option.data.longs[0] || option.data.shorts[0];
const flag = colors.green(`--${flagName}`);
const argName = option.data.args[0];
const argVariadic = option.variadic ? '...' : '';
const arg = argName ? colors.blue(`<${argName}${argVariadic}>`) : '';
return [flag, arg].filter(identity).join(' ');
}).join(' ');
const line = [name, commands, options, args].filter(identity).join(' ');
this.stdout.print(line);
}
});
}
register(usage) {
this.usages.add(usage);
}
}
/* EXPORT */
export default Usage;