-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
When arguments() argument is provided, unrecognized flags are silently deleted (no error prints) #561
Comments
@mcclure have you found a workaround for this? I agree that not throwing when invalid arguments or options are given can be very dangerous. It's so easy to just type a wrong command and accidentally delete something important! |
I'll add that I just got bitten by this today, spending a while debugging my code only to find my command line inputs were wrong. Expected valid option was Just for the sake of clarity, my invalid command line was: node loadtester.js --condurrency 100 --users 1000 devtest_noop_follower.js but it should have been: node loadtester.js --concurrency 100 --users 1000 devtest_noop_follower.js My code that uses commander is something like this: const program = require('commander')
program
.usage('[options] <file>')
.arguments('<file>')
.option('-c, --concurrency <number>', 'Max number of concurrent users.', parseInt)
.option('-u, --users <number>', 'Max number of users.', parseInt)
.action(file => {
testPlanFile = file;
})
.parse(process.argv); If I do not pass the argument, the invalid option error: unknown option `--condurrency' |
I think I found the place in the Command.prototype.parseArgs = function(args, unknown) {
var name;
if (args.length) {
name = args[0];
if (this.listeners(name).length) {
this.emit(args.shift(), args, unknown);
} else {
this.emit('*', args);
}
} else {
outputHelpIfNecessary(this, unknown);
// If there were no args and we have unknown options,
// then they are extraneous and we need to error.
if (unknown.length > 0) {
this.unknownOption(unknown[0]);
}
}
return this;
}; However, I'm not sure which use case this should really be valid for. By this point in the code, the Also, this implementation changes behavior depending on whether or not As an experiment, I changed the code to: Command.prototype.parseArgs = function(args, unknown) {
var name;
if (args.length) {
name = args[0];
if (this.listeners(name).length) {
this.emit(args.shift(), args, unknown);
} else {
this.emit('*', args);
}
} else {
outputHelpIfNecessary(this, unknown);
}
// Handle unknown options whether or not args are passed.
if (unknown.length > 0) {
this.unknownOption(unknown[0]);
}
return this;
}; This had the desired effect (desired by me anyway ;)): Both of the following command lines produced a useful error message: node loadtester.js --condurrency 100
error: unknown option `--condurrency' and node loadtester.js --condurrency 100 path_to_file
error: unknown option `--condurrency' I'd love to submit a pull request to fix this, but I don't know enough about the rest of the project (at the moment) to know whether I'm on the right track, or missing something important. Anyone care to guide me at this point? Thanks! |
@vanesyan @abetomo you two appear to be the last two to commit code to this library. I would really like to have this fixed and would be willing to send a PR. Any feedback on this before I make a PR? |
In my case the command works without any options being passed but when i try to pass a option it gives me this error 😕 This is my code: |
This has not seen a lot of activity, but it is a clear bug, and I have reproduced it on Mac. |
Had a script passing accidentally // test.ts
import * as commander from "commander";
const fn = (opt: string) => (a: string) => console.log(`in ${opt}${a ? ` -- got: '${a}'` : ""}`);
commander
.option("-a, --abc <arg>", "Pass me a value", fn("abc"))
.option("-x", "Dummy x", fn("x"))
.option("-y", "Dummy y", fn("y"))
.parse(process.argv); Fine/good:
I guess this is okay (at least there's an error -- after my option-handling function is called with "garbage"):
But ICK!!
|
#965 will fix the detection of unknown options in the case the program has an action handler. The original report in this issue (#561 (comment)) does not have an action handler so won't be changed by #965. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
The invalid option will get detected if the program has an action handler, even an empty one. This is a limitation due to the current implementation rather than by design. This is actually mentioned in the README, although easily missed!
|
…ng (#1152) * Add tests for Utility Conventions before changing code to match * Switch from preflight including normalise to just testing parseOptions * Only refactor known options Do the work in .parseOptions and delete single-pass .normalize * Add short flag processing to READMEm, and literal -- * Improve character description * Add a note that options not positional. * Remove regression tests for bug not really fixed by this * Add back #561 into known issues * Refactor to make a little clearer and symmetrical * Use template to construct strings consistently within parseOptions
Unknown options are reliably detected whether or not there is an action handler in the published pre-release of Commander v5.0.0 (#1163) |
Commander v5.0.0 has been released with significant improvements to argument parsing. |
I am using commander 2.9.0 (graceful-readlink 1.0.1) on node v4.4.7 (on Windows, running in MSYS2, if it matters).
I run the following test program:
I find that if I do not supply the
<file>
argument, if I pass a nonsense flag like --nonsense, I will get a nice error message. If I do supply the<file>
argument, then any nonsense flags included will be silently discarded. Moreover, commander appears to assume each nonsense flag takes one option-argument, and it silently discards that, too. These flags are not appended to commander.args or anything. They just disappear.A demonstration:
Expected behavior: A --flag which is not recognized should result in commander printing an error.
This is a pretty bad bug. Not only does commander allow something which should be an error, and not only does it do it inconsistently for the same script depending on input, but since commander does this totally silently I cannot even write my own recovery code. If the lost arguments had been appended to
commander.args
at least I could detect it and raise my own error.The text was updated successfully, but these errors were encountered: