airlift / airline

Java annotation-based framework for parsing Git like command line structures
Apache License 2.0
847 stars 138 forks source link

Show help when missing a required parameter #22

Open thombergs opened 10 years ago

thombergs commented 10 years ago

When I call "command --help" when missing a required parameter specified with required=true, all I see is a stacktrace like this:

Exception in thread "main" io.airlift.command.ParseOptionMissingException:
 Required option '-rev' is missing

When specifying the help parameter the help should be displayed no matter if required parameters are missing or not.

I used the code shown on the readme page:

public static void main(String... args) {
  MyCommand command = SingleCommand.singleCommand(MyCommand.class).parse(args);

  // cancel further processing if help is displayed
  if (command.help.showHelpIfRequested()) {
    return;
  }

  command.run();
}

The exception is thrown in the parse() method naturally. Because the Help can only be triggered AFTER the command object is created, I cannot show the help if required parameters are missing. Is there an existing solution to this?

Regards, Tom

electrum commented 10 years ago

This is an interesting issue. The library was originally designed to be agnostic about the help system. Before the previous release, it was simply another command. This is an important usability problem, so we'll probably need more special casing for help.

jontodd commented 10 years ago

+1 for fixing this issue. If you want to continue to be agnostic to the help system the the Errors object pattern might be a better approach than throwing. Especially when dealing with input from a user which may actually have multiple things wrong with it, this pattern will allow for the reporting of each problem at once rather than failing once at a time.

You could still keep the current semantic you have today with:

MyCommand command = SingleCommand.singleCommand(MyCommand.class).parseFailFast(args);

But then you could also support a model like this:

ParseResult parseResult = new ParseResult();
MyCommand command = SingleCommand.singleCommand(MyCommand.class).parse(args, parseResult);

if (parseResult.hasErrors()) {
   command.helpOption.showHelpWithErrors(parseResult.errors());
}

Thoughts?

taotaotw commented 8 years ago

Seems this fix never goes into the master branch here: https://github.com/airlift/airline Is there any reason?

hristo-vrigazov commented 7 years ago

Any updates on this one?