1
0
Fork 0

feat: add command completion

BREAKING CHANGE: the `--mode` option has been replaced by a positional
command, but the options and defaults are unchanged.
This commit is contained in:
ssube 2019-07-04 09:44:54 -05:00
parent b3d1cf2ede
commit 39c0e4ba76
Signed by: ssube
GPG Key ID: 3EED7B957D362AF1
1 changed files with 88 additions and 67 deletions

View File

@ -19,72 +19,92 @@ const RULE_OPTION: Options = {
type: 'array',
};
const MAIN_ARGS = usage(`Usage: salty-dog [-m mode] [options]`)
.option(CONFIG_ARGS_NAME, {
default: `.${VERSION_INFO.app.name}.yml`,
group: 'Config:',
type: 'string',
})
.option(CONFIG_ARGS_PATH, {
default: [],
group: 'Config:',
type: 'array',
})
.option('coerce', {
default: false,
type: 'boolean',
})
.option('count', {
alias: ['c'],
default: false,
desc: 'Exit with error count',
type: 'boolean',
})
.option('dest', {
alias: ['d'],
default: '-',
type: 'string',
})
.option('format', {
alias: ['f'],
default: 'yaml',
type: 'string',
})
.option('mode', {
alias: ['m'],
choices: MODES,
default: 'check',
type: 'string',
})
.option('rules', {
alias: ['r'],
default: [],
desc: 'Rules file',
type: 'array',
})
.option('source', {
alias: ['s'],
default: '-',
type: 'string',
})
.option('exclude-level', RULE_OPTION)
.option('exclude-name', RULE_OPTION)
.option('exclude-tag', RULE_OPTION)
.option('include-level', RULE_OPTION)
.option('include-name', RULE_OPTION)
.option('include-tag', {
...RULE_OPTION,
alias: ['t', 'tag'],
})
.help()
.version(VERSION_INFO.app.version)
.alias('version', 'v');
const STATUS_SUCCESS = 0;
const STATUS_ERROR = 1;
export async function main(argv: Array<string>): Promise<number> {
const args = MAIN_ARGS.argv;
let mode = 'check';
const args = usage(`Usage: salty-dog <mode> [options]`)
.command({
command: ['check', '*'],
describe: 'validate the source documents',
handler: (argv) => {
mode = 'check';
},
})
.command({
command: ['fix'],
describe: 'validate the source document and insert defaults',
builder: (yargs: any) => {
return yargs.option('coerce', {
default: false,
type: 'boolean',
});
},
handler: (argv) => {
mode = 'fix';
},
})
.command({
command: ['list'],
describe: 'list active rules',
handler: (argv) => {
mode = 'list';
},
})
.option(CONFIG_ARGS_NAME, {
default: `.${VERSION_INFO.app.name}.yml`,
group: 'Config:',
type: 'string',
})
.option(CONFIG_ARGS_PATH, {
default: [],
group: 'Config:',
type: 'array',
})
.option('count', {
alias: ['c'],
default: false,
desc: 'Exit with error count',
type: 'boolean',
})
.option('dest', {
alias: ['d'],
default: '-',
type: 'string',
})
.option('format', {
alias: ['f'],
default: 'yaml',
type: 'string',
})
.option('rules', {
alias: ['r'],
default: [],
desc: 'Rules file',
type: 'array',
})
.option('source', {
alias: ['s'],
default: '-',
type: 'string',
})
.option('exclude-level', RULE_OPTION)
.option('exclude-name', RULE_OPTION)
.option('exclude-tag', RULE_OPTION)
.option('include-level', RULE_OPTION)
.option('include-name', RULE_OPTION)
.option('include-tag', {
...RULE_OPTION,
alias: ['t', 'tag'],
})
.completion('completion', 'generate command completion for bash or zsh')
.help()
.version(VERSION_INFO.app.version)
.alias('version', 'v')
.argv;
const config = await loadConfig(args[CONFIG_ARGS_NAME], ...args[CONFIG_ARGS_PATH]);
const logger = createLogger(config.data.logger);
@ -92,8 +112,8 @@ export async function main(argv: Array<string>): Promise<number> {
logger.info({ args }, 'main arguments');
// check mode
if (!MODES.includes(args.mode)) {
logger.error({ mode: args.mode }, 'unsupported mode');
if (!MODES.includes(mode)) {
logger.error({ mode }, 'unsupported mode');
return STATUS_ERROR;
}
@ -104,9 +124,10 @@ export async function main(argv: Array<string>): Promise<number> {
return STATUS_ERROR;
}
const coerce = Reflect.has(args, 'coerce') ? Reflect.get(args, 'coerce') : false;
const ctx = new VisitorContext({
coerce: args.coerce,
defaults: args.mode === 'fix',
coerce,
defaults: mode === 'fix',
logger,
});
@ -117,7 +138,7 @@ export async function main(argv: Array<string>): Promise<number> {
const rules = await loadRules(args.rules, ctx.ajv);
const activeRules = await resolveRules(rules, args as any);
if (args.mode === 'list') {
if (mode === 'list') {
logger.info({ rules: activeRules }, 'listing active rules');
return STATUS_SUCCESS;
}