aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-util
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2022-09-19 17:46:30 +0200
committerFlorian Dold <florian@dold.me>2022-09-19 17:46:30 +0200
commita5525eab1e96d5b08fbb6442275b1e92f7f8d806 (patch)
treed03e01c84b051373778188f8f63005257f5073d8 /packages/taler-util
parentf63765b9f7a089eb0f2a62d53f5ad1d56961fa1f (diff)
downloadwallet-core-a5525eab1e96d5b08fbb6442275b1e92f7f8d806.tar.xz
taler-util: fix CLI parsing for numberic options
Diffstat (limited to 'packages/taler-util')
-rw-r--r--packages/taler-util/src/clk.test.ts46
-rw-r--r--packages/taler-util/src/clk.ts46
2 files changed, 77 insertions, 15 deletions
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 <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * 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<T> {}
@@ -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, {});
}