From a5525eab1e96d5b08fbb6442275b1e92f7f8d806 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 19 Sep 2022 17:46:30 +0200 Subject: taler-util: fix CLI parsing for numberic options --- packages/taler-util/src/clk.test.ts | 46 +++++++++++++++++++++++++++++++++++++ packages/taler-util/src/clk.ts | 46 +++++++++++++++++++++++++------------ 2 files changed, 77 insertions(+), 15 deletions(-) create mode 100644 packages/taler-util/src/clk.test.ts (limited to 'packages/taler-util') diff --git a/packages/taler-util/src/clk.test.ts b/packages/taler-util/src/clk.test.ts new file mode 100644 index 000000000..bec93947b --- /dev/null +++ b/packages/taler-util/src/clk.test.ts @@ -0,0 +1,46 @@ +/* + This file is part of GNU Taler + (C) 2018-2019 GNUnet e.V. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * Type-safe codecs for converting from/to JSON. + */ + +import test from "ava"; +import { clk } from "./clk.js"; +import { + Codec, + buildCodecForObject, + codecForConstString, + codecForString, + buildCodecForUnion, +} from "./codec.js"; + +test("bla", (t) => { + const prog = clk.program("foo", { + help: "Hello", + }); + + let success = false; + + prog.maybeOption("opt1", ["-o", "--opt1"], clk.INT).action((args) => { + success = true; + t.deepEqual(args.foo.opt1, 42); + }); + + prog.run(["bla", "-o", "42"]); + + t.true(success); +}); diff --git a/packages/taler-util/src/clk.ts b/packages/taler-util/src/clk.ts index d172eed48..e99ebf733 100644 --- a/packages/taler-util/src/clk.ts +++ b/packages/taler-util/src/clk.ts @@ -20,6 +20,7 @@ import process from "process"; import path from "path"; import readline from "readline"; +import { devNull } from "os"; export namespace clk { class Converter {} @@ -329,6 +330,20 @@ export namespace clk { const myArgs: any = (parsedArgs[this.argKey] = {}); const foundOptions: { [name: string]: boolean } = {}; const currentName = this.name ?? progname; + const storeOption = (def: OptionDef, value: string) => { + foundOptions[def.name] = true; + if (def.conv === INT) { + myArgs[def.name] = Number.parseInt(value); + } else if (def.conv == null || def.conv === STRING) { + myArgs[def.name] = value; + } else { + throw Error("unknown converter"); + } + }; + const storeFlag = (def: OptionDef, value: boolean) => { + foundOptions[def.name] = true; + myArgs[def.name] = value; + }; for (i = 0; i < unparsedArgs.length; i++) { const argVal = unparsedArgs[i]; if (argsTerminated == false) { @@ -353,8 +368,7 @@ export namespace clk { process.exit(-1); throw Error("not reached"); } - foundOptions[d.name] = true; - myArgs[d.name] = true; + storeFlag(d, true); } else { if (r.value === undefined) { if (i === unparsedArgs.length - 1) { @@ -362,12 +376,11 @@ export namespace clk { process.exit(-1); throw Error("not reached"); } - myArgs[d.name] = unparsedArgs[i + 1]; + storeOption(d, unparsedArgs[i + 1]); i++; } else { - myArgs[d.name] = r.value; + storeOption(d, r.value); } - foundOptions[d.name] = true; } continue; } @@ -381,8 +394,7 @@ export namespace clk { process.exit(-1); } if (opt.isFlag) { - myArgs[opt.name] = true; - foundOptions[opt.name] = true; + storeFlag(opt, true); } else { if (si == optShort.length - 1) { if (i === unparsedArgs.length - 1) { @@ -390,13 +402,12 @@ export namespace clk { process.exit(-1); throw Error("not reached"); } else { - myArgs[opt.name] = unparsedArgs[i + 1]; + storeOption(opt, unparsedArgs[i + 1]); i++; } } else { - myArgs[opt.name] = optShort.substring(si + 1); + storeOption(opt, optShort.substring(si + 1)); } - foundOptions[opt.name] = true; break; } } @@ -508,16 +519,21 @@ export namespace clk { }); } - run(): void { - const args = process.argv; - if (args.length < 2) { + run(cmdlineArgs?: string[]): void { + let args: string[]; + if (cmdlineArgs) { + args = cmdlineArgs; + } else { + args = process.argv.slice(1); + } + if (args.length < 1) { console.error( "Error while parsing command line arguments: not enough arguments", ); process.exit(-1); } - const progname = path.basename(args[1]); - const rest = args.slice(2); + const progname = path.basename(args[0]); + const rest = args.slice(1); this.mainCommand.run(progname, [], rest, {}); } -- cgit v1.2.3