If I have 2 options defined as required such as:
public static void main(String [] args){
Options options= new Options();
Option inputFileOp=Option.builder("i").longOpt("input").hasArg().desc("Input file").argName("file").required().build();
options.addOption(inputFileOp);
Option outputFileOp=Option.builder("o").longOpt("output").hasArg().desc("Output file").argName("file").required().build();
options.addOption(outputFileOp);
and a help option
Option helpOp =new Option("h",false,"Show Help");
helpOp.setLongOpt("help");
helpOptions.addOption(helpOp);
and parser
DefaultParser parser = new DefaultParser();
CommandLine cmd=parser.parse(options,args);
if(cmd.hasOption(helpOp.getOpt())){
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp( "MyApp.sh", options );
System.exit(0);
}
}
When the user input for example myApp -h .. An exception is raised in the parsing step that there are missing required options, While I want to print the help data.
How to allow calling the help while keeping these options declared as required?
Add another method, as the previous poster said, but make sure you stop at the first unrecognized argument.
If
stopAtNonOption
is set to false, then this function would throw for valid arguments, likejava -jar app.jar -doStuff
The code for
DefaultParser
appears to always call thecheckRequiredArgs()
method. Which seems to indicate that you cannot, in one fell swoop, avoid the problem.The way we have addressed this situation in the past, perhaps in a suboptimal fashion, is to parse the command line twice. The parsing is fast, so the overhead it minimal.
We created a method
checkForHelp(String[] args)
that takes the (String[] args). It adds only the help option to an options, parses the command line, and then ascertains whether help is specified. If so, the help is printed, and the program exits. Otherwise, the full set of options is processed. This approach allows for the required fields to be processed as expected. Note that the help option must also be added in the main list.Then in the
main
method, something akin to:EDIT: as it turns out, this approach is similar to the answer provided here: Commons CLI required groups. I guess I feel better that our approach has others supporting what we believed.
EDIT2: In a quick test, I believe the problem of having required options may be avoided by using an "OptionGroup". Here is a revised
checkForHelp
that works by adding all of the options to an OptionGroup. In my quick testing, it avoids the problem that was present if one did, e.g., ("--arg1 --help").Wouldn't it be easier to just parse raw args and check for
--help/-h
orhelp.getOpt()/help.getLongOpt()
keyword before parsing usingDefaultParser
? This way you avoid double parsing overhead.