Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Apache Commons CLI options parser ignore unknown command-line options?

Tags:

I am writing a Java application that takes command line arguments which are processed using Apache Commons CLI with the GnuParser. For reasons that are not interesting to get into, I would like it to silently ignore unknown command line options instead of throwing a ParseException but I don't see a way to do that. I see that there is a stopAtNonOption boolean option on GnuParser.parse() but what I want is more like ignoreAtNonOption where it will keep processing options after encountering an unknown token.

I could implement my own parser to accomplish this but I'm surprised there isn't this functionality built in so I thought I'd check before going down that road.

Example code for what I'm talking about:

try {   CommandLine commandLine = parser.parse(options, args);   // stopAtNonOption set to true (below) is also not what I want   // CommandLine commandLine = parser.parse(options, args, true); } catch (ParseException e) {   LOG.error("error parsing arguments", e);   throw new RuntimeException(e); } 
like image 972
Michael Ridley Avatar asked May 18 '11 18:05

Michael Ridley


2 Answers

This works for me (other parsers can be derived, too):

public class ExtendedGnuParser extends GnuParser {      private boolean ignoreUnrecognizedOption;      public ExtendedGnuParser(final boolean ignoreUnrecognizedOption) {         this.ignoreUnrecognizedOption = ignoreUnrecognizedOption;     }      @Override     protected void processOption(final String arg, final ListIterator iter) throws     ParseException {         boolean hasOption = getOptions().hasOption(arg);          if (hasOption || !ignoreUnrecognizedOption) {             super.processOption(arg, iter);         }     }  } 
like image 91
Pascal Schäfer Avatar answered Sep 21 '22 14:09

Pascal Schäfer


As mentioned in a comment, the accepted solution is no more suitable because the processOption method has been deprecated and removed.

Here's my solution:

public class ExtendedParser extends DefaultParser {      private final ArrayList<String> notParsedArgs = new ArrayList<>();      public String[] getNotParsedArgs() {         return notParsedArgs.toArray(new String[notParsedArgs.size()]);     }      @Override     public CommandLine parse(Options options, String[] arguments, boolean stopAtNonOption) throws ParseException {         if(stopAtNonOption) {             return parse(options, arguments);         }         List<String> knownArguments = new ArrayList<>();         notParsedArgs.clear();         boolean nextArgument = false;         for (String arg : arguments) {             if (options.hasOption(arg) || nextArgument) {                 knownArguments.add(arg);             } else {                 notParsedArgs.add(arg);             }          nextArgument = options.hasOption(arg) && options.getOption(arg).hasArg();         }         return super.parse(options, knownArguments.toArray(new String[knownArguments.size()]));     }  } 

Compared with the solution proposed by Pascal, it also checks for options with arguments and it keeps not parsed args in a separate list.

like image 37
SimoV8 Avatar answered Sep 18 '22 14:09

SimoV8