-
Notifications
You must be signed in to change notification settings - Fork 782
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(cli): fix bug with parsing --fooBar=baz type CLI flags #3483
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,9 +51,13 @@ export const parseFlags = (args: string[], sys?: CompilerSystem): ConfigFlags => | |
} | ||
} | ||
|
||
flags.unknownArgs = flags.args.filter((arg: string) => { | ||
return !flags.knownArgs.includes(arg); | ||
}); | ||
// to find unknown / unrecognized arguments we filter `args`, including only | ||
// arguments whose normalized form is not found in `knownArgs`. `knownArgs` | ||
// is populated during the call to `parseArgs` above. For arguments like | ||
// `--foobar` the string `"--foobar"` will be added, while for more | ||
// complicated arguments like `--bizBoz=bop` or `--bizBoz bop` just the | ||
// string `"--bizBoz"` will be added. | ||
flags.unknownArgs = flags.args.filter((arg: string) => !flags.knownArgs.includes(parseEqualsArg(arg)[0])); | ||
|
||
return flags; | ||
}; | ||
|
@@ -259,17 +263,18 @@ const getValue = ( | |
|
||
let value: string | undefined; | ||
let matchingArg: string | undefined; | ||
|
||
args.forEach((arg, i) => { | ||
if (arg.startsWith(`--${dashCaseName}=`) || arg.startsWith(`--${configCaseName}=`)) { | ||
value = getEqualsValue(arg); | ||
matchingArg = arg; | ||
// our argument was passed at the command-line in the format --argName=arg-value | ||
[matchingArg, value] = parseEqualsArg(arg); | ||
} else if (arg === `--${dashCaseName}` || arg === `--${configCaseName}`) { | ||
// the next value in the array is assumed to be a value for this argument | ||
value = args[i + 1]; | ||
matchingArg = arg; | ||
} else if (alias) { | ||
if (arg.startsWith(`-${alias}=`)) { | ||
value = getEqualsValue(arg); | ||
matchingArg = arg; | ||
[matchingArg, value] = parseEqualsArg(arg); | ||
} else if (arg === `-${alias}`) { | ||
value = args[i + 1]; | ||
matchingArg = arg; | ||
|
@@ -287,13 +292,43 @@ interface CLIArgValue { | |
} | ||
|
||
/** | ||
* When a parameter is set in the format `--foobar=12` at the CLI (as opposed to | ||
* `--foobar 12`) we want to get the value after the `=` sign | ||
* Parse an 'equals' argument, which is a CLI argument-value pair in the | ||
* format `--foobar=12` (as opposed to a space-separated format like | ||
* `--foobar 12`). | ||
* | ||
* To parse this we split on the `=`, returning the first part as the argument | ||
* name and the second part as the value. We join the value on `"="` in case | ||
* there is another `"="` in the argument. | ||
* | ||
* This function is safe to call with any arg, and can therefore be used as | ||
* an argument 'normalizer'. If CLI argument is not an 'equals' argument then | ||
* the return value will be a tuple of the original argument and an empty | ||
* string `""` for the value. | ||
* | ||
* In code terms, if you do: | ||
* | ||
* @param commandArgument the arg in question | ||
* @returns the value after the `=` | ||
* ```ts | ||
* const [arg, value] = parseEqualsArg("--myArgument") | ||
* ``` | ||
* | ||
* Then `arg` will be `"--myArgument"` and `value` will be `""`, whereas if | ||
* you do: | ||
* | ||
* | ||
* ```ts | ||
* const [arg, value] = parseEqualsArg("--myArgument=myValue") | ||
* ``` | ||
* | ||
* Then `arg` will be `"--myArgument"` and `value` will be `"myValue"`. | ||
* | ||
* @param arg the arg in question | ||
* @returns a tuple containing the arg name and the value (if present) | ||
*/ | ||
const getEqualsValue = (commandArgument: string) => commandArgument.split('=').slice(1).join('='); | ||
export const parseEqualsArg = (arg: string): [string, string] => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I refactored this function to return a tuple of the argument name (parsed from the CLI input) and the value it is set to if present (and The first value in the tuple will be parseEqualsArg("--foobar")[0] === parseEqualsArgs("--foobar=baz")[0] being true |
||
const [originalArg, ...value] = arg.split('='); | ||
|
||
return [originalArg, value.join('=')]; | ||
}; | ||
|
||
/** | ||
* Small helper for getting type-system-level assurance that a `string` can be | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I use
parseEqualsArg
to normalize arguments for buildingunknownArgs
, here