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:
parent
b3d1cf2ede
commit
39c0e4ba76
155
src/index.ts
155
src/index.ts
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue