Handle --long=value format in the cli parser

This commit is contained in:
Asher 2020-02-19 10:54:23 -06:00
parent fa30639784
commit 0263188431
No known key found for this signature in database
GPG Key ID: D63C1EF81242354A
2 changed files with 19 additions and 12 deletions

View File

@ -128,8 +128,11 @@ export const parse = (argv: string[]): Args => {
// Options start with a dash and require a value if non-boolean. // Options start with a dash and require a value if non-boolean.
if (!ended && arg.startsWith("-")) { if (!ended && arg.startsWith("-")) {
let key: keyof Args | undefined let key: keyof Args | undefined
let value: string | undefined
if (arg.startsWith("--")) { if (arg.startsWith("--")) {
key = arg.replace(/^--/, "") as keyof Args const split = arg.replace(/^--/, "").split("=", 2)
key = split[0] as keyof Args
value = split[1]
} else { } else {
const short = arg.replace(/^-/, "") const short = arg.replace(/^-/, "")
const pair = Object.entries(options).find(([, v]) => v.short === short) const pair = Object.entries(options).find(([, v]) => v.short === short)
@ -148,13 +151,17 @@ export const parse = (argv: string[]): Args => {
continue continue
} }
// A value is only valid if it doesn't look like an option. // Might already have a value if it was the --long=value format.
let value = argv[i + 1] && !argv[i + 1].startsWith("-") ? argv[++i] : undefined if (typeof value === "undefined") {
// A value is only valid if it doesn't look like an option.
value = argv[i + 1] && !argv[i + 1].startsWith("-") ? argv[++i] : undefined
}
if (!value && option.type === OptionalString) { if (!value && option.type === OptionalString) {
;(args[key] as OptionalString) = new OptionalString(value) ;(args[key] as OptionalString) = new OptionalString(value)
continue continue
} else if (!value) { } else if (!value) {
throw new Error(`${arg} requires a value`) throw new Error(`--${key} requires a value`)
} }
if (option.path) { if (option.path) {
@ -174,7 +181,7 @@ export const parse = (argv: string[]): Args => {
case "number": case "number":
;(args[key] as number) = parseInt(value, 10) ;(args[key] as number) = parseInt(value, 10)
if (isNaN(args[key] as number)) { if (isNaN(args[key] as number)) {
throw new Error(`${arg} must be a number`) throw new Error(`--${key} must be a number`)
} }
break break
case OptionalString: case OptionalString:
@ -182,7 +189,7 @@ export const parse = (argv: string[]): Args => {
break break
default: { default: {
if (!Object.values(option.type).find((v) => v === value)) { if (!Object.values(option.type).find((v) => v === value)) {
throw new Error(`${arg} valid values: [${Object.values(option.type).join(", ")}]`) throw new Error(`--${key} valid values: [${Object.values(option.type).join(", ")}]`)
} }
;(args[key] as string) = value ;(args[key] as string) = value
break break

View File

@ -36,19 +36,16 @@ describe("cli", () => {
"error", "error",
"--help", "--help",
"--open", "--open",
"--socket", "--socket=mumble",
"mumble",
"3", "3",
"--user-data-dir", "--user-data-dir",
"bar", "bar",
"--cert", "--cert=baz",
"baz",
"--cert-key", "--cert-key",
"qux", "qux",
"--version", "--version",
"--json", "--json",
"--port", "--port=8081",
"8081",
"--host", "--host",
"0.0.0.0", "0.0.0.0",
"4", "4",
@ -117,6 +114,9 @@ describe("cli", () => {
it("should error if value isn't provided", () => { it("should error if value isn't provided", () => {
assert.throws(() => parse(["--auth"]), /--auth requires a value/) assert.throws(() => parse(["--auth"]), /--auth requires a value/)
assert.throws(() => parse(["--auth=", "--log=debug"]), /--auth requires a value/)
assert.throws(() => parse(["--auth", "--log"]), /--auth requires a value/)
assert.throws(() => parse(["--auth", "--invalid"]), /--auth requires a value/)
}) })
it("should error if number option is invalid", () => { it("should error if number option is invalid", () => {