From 5c79e60238955b1c9d14d22d8fcd51cd8bec1c39 Mon Sep 17 00:00:00 2001 From: Arthur Joppart <38424924+BelgianNoise@users.noreply.github.com> Date: Mon, 5 Dec 2022 13:36:54 +0100 Subject: [PATCH] feat: return clear error when multiple values for a cli flag are given * feat: return clear error when multiple values for a cli flag are given * chore: change function signature * test: add testcase for array type yargs parameter --- src/init/cli/YargsCliExtractor.ts | 12 ++++++++++++ test/unit/init/cli/YargsCliExtractor.test.ts | 16 ++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/init/cli/YargsCliExtractor.ts b/src/init/cli/YargsCliExtractor.ts index 26ee5f701..7d9c1922e 100644 --- a/src/init/cli/YargsCliExtractor.ts +++ b/src/init/cli/YargsCliExtractor.ts @@ -71,6 +71,18 @@ export class YargsCliExtractor extends CliExtractor { */ private createYArgv(argv: readonly string[]): Argv { let yArgv = yargs(argv.slice(2)); + + // Error and show help message when multiple values were provided + // for a non Array type parameter + yArgv.check((args): boolean => { + for (const [ name, options ] of Object.entries(this.yargsArgOptions)) { + if (options.type !== 'array' && Array.isArray(args[name])) { + throw new Error(`Multiple values for --${name} (-${options.alias}) were provided where only one is allowed`); + } + } + return true; + }); + if (this.yargvOptions.usage !== undefined) { yArgv = yArgv.usage(this.yargvOptions.usage); } diff --git a/test/unit/init/cli/YargsCliExtractor.test.ts b/test/unit/init/cli/YargsCliExtractor.test.ts index 7bcc3a39c..93a8ef791 100644 --- a/test/unit/init/cli/YargsCliExtractor.test.ts +++ b/test/unit/init/cli/YargsCliExtractor.test.ts @@ -8,6 +8,7 @@ describe('A YargsCliExtractor', (): void => { const parameters: YargsParameter[] = [ new YargsParameter('baseUrl', { alias: 'b', requiresArg: true, type: 'string' }), new YargsParameter('port', { alias: 'p', requiresArg: true, type: 'number' }), + new YargsParameter('config', { alias: 'c', requiresArg: false, type: 'array' }), ]; let extractor: YargsCliExtractor; @@ -52,6 +53,21 @@ describe('A YargsCliExtractor', (): void => { expect(error).toHaveBeenCalledWith('Unknown argument: unsupported'); }); + it('can error when multiple values are provided for a non array type parameter.', async(): Promise => { + extractor = new YargsCliExtractor(parameters, { strictMode: true }); + const argv = [ 'node', 'script', '-p', '3000', '-b', 'http://localhost:3000/', '-p', '3001' ]; + await extractor.handle(argv); + expect(exit).toHaveBeenCalledTimes(1); + expect(error).toHaveBeenCalledWith('Multiple values for --port (-p) were provided where only one is allowed'); + }); + + it('accepts multiple values for array type parameters.', async(): Promise => { + const argv = [ 'node', 'script', '-c', './config/a.json', '-c', './config/b.json', '-b', 'http://localhost:3000/', '-p', '3000' ]; + await expect(extractor.handle(argv)).resolves.toEqual(expect.objectContaining({ + config: [ './config/a.json', './config/b.json' ], + })); + }); + it('can parse environment variables.', async(): Promise => { // While the code below does go into the corresponding values, // yargs does not see the new environment variable for some reason.