From ee89b74e1ed044fd420d88f8d6144f839fea7922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ey=C3=BE=C3=B3r=20Magn=C3=BAsson?= Date: Tue, 29 May 2018 07:20:53 +0200 Subject: [PATCH] refactor: move invalid flags check to command setup function --- src/cli/cli.ts | 28 +++++++++++----------------- src/cli/helpers.ts | 22 +++++++++++++++------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/cli/cli.ts b/src/cli/cli.ts index 1d3762d631..138dba5825 100644 --- a/src/cli/cli.ts +++ b/src/cli/cli.ts @@ -7,7 +7,7 @@ */ import * as sywac from "sywac" -import { difference, merge, intersection } from "lodash" +import { merge, intersection } from "lodash" import { resolve } from "path" import { safeDump } from "js-yaml" import stringify = require("json-stringify-safe") @@ -59,7 +59,7 @@ import { Writer } from "../logger/writers/base" import { falsifyConflictingParams, - getAliases, + failOnInvalidOptions, getArgSynopsis, getKeys, getOptionSynopsis, @@ -204,19 +204,6 @@ export class GardenCli { const root = resolve(process.cwd(), parsedOpts.root) const { env, loglevel, silent, output } = parsedOpts - // Validate options (feels like the parser should handle this) - const builtinOptions = ["help", "h", "version", "v"] - const availableOptions = [...getAliases(options), ...getAliases(GLOBAL_OPTIONS), ...builtinOptions] - const passedOptions = cliContext.args - .filter(str => str.startsWith("-") || str.startsWith("--")) - .map(str => str.startsWith("--") ? str.slice(2) : str.slice(1)) - .map(str => str.split("=")[0]) - const invalid = difference(passedOptions, availableOptions) - if (invalid.length > 0) { - cliContext.cliMessage(`Received invalid flag(s): ${invalid.join(" ")}`) - return - } - // Init logger const level = LogLevel[loglevel] let writers: Writer[] = [] @@ -264,16 +251,23 @@ export class GardenCli { subCommands.forEach(subCommandCls => this.addCommand(new subCommandCls(command), parser)) argKeys.forEach(key => parser.positional(getArgSynopsis(key, args[key]), prepareArgConfig(args[key]))) optKeys.forEach(key => parser.option(getOptionSynopsis(key, options[key]), prepareOptionConfig(options[key]))) + + // We only check for invalid flags for the last command since it might contain flags that + // the parent is unaware of, thus causing the check to fail for the parent + if (subCommands.length < 1) { + parser.check(failOnInvalidOptions) + } + return parser } - const commandOpts = { + const commandConfig = { setup, aliases: command.alias, desc: command.help, run: action, } - program.command(command.name, commandOpts) + program.command(command.name, commandConfig) } async parse(): Promise { diff --git a/src/cli/helpers.ts b/src/cli/helpers.ts index 9ec346817d..8743a1edcd 100644 --- a/src/cli/helpers.ts +++ b/src/cli/helpers.ts @@ -7,7 +7,7 @@ */ import chalk from "chalk" -import { flatten, reduce } from "lodash" +import { difference, flatten, reduce } from "lodash" import { ChoicesParameter, ParameterValues, @@ -59,11 +59,6 @@ export const filterByArray = (obj: any, arr: string[]): any => { }, {}) } -export function getAliases(params: ParameterValues) { - return flatten(Object.entries(params) - .map(([key, param]) => param.alias ? [key, param.alias] : [key])) -} - export type FalsifiedParams = { [key: string]: false } /** @@ -92,7 +87,7 @@ export function falsifyConflictingParams(argv, params: ParameterValues): Fa }, {}) } -// Sywac transformers +// Sywac specific transformers and helpers export function getOptionSynopsis(key: string, param: Parameter): string { return param.alias ? `-${param.alias}, --${key}` : `--${key}` } @@ -143,3 +138,16 @@ export function prepareOptionConfig(param: Parameter): SywacOptionConfig { } return config } + +export function failOnInvalidOptions(argv, ctx) { + const validOptions = flatten( + ctx.details.types + .filter(t => t.datatype !== "command") + .map(t => t.aliases), + ) + const receivedOptions = Object.keys(argv) + const invalid = difference(receivedOptions, validOptions) + if (invalid.length > 0) { + ctx.cliMessage(`Received invalid flag(s): ${invalid.join(", ")}`) + } +}