Search code examples
javacommand-line-interfaceapache-commons-cli

commons cli complex argument list


I am trying to build a complex list of arguments without chaining multiple parsers using commons-cli project...

Basically I am trying to understand how the arguments and optional arguments are working together...

Sample Command help

$ admin <endpoint> <update> <name> [<type>] [<endpoint>] [<descriptions>]

//sample option creation for a    
options.addOption(OptionBuilder.hasArgs(3).hasOptionalArgs(2)
                .withArgName("name> <type> <uri> [<description>] [<endpoint>]")
                .withValueSeparator(' ')
                .create("add"));

CommandLine line = parser.parse(options, args, true);

The CommandLine does not differentiate between required and optional arguments... how can I retrieve them without have to chain a second parser for the optional options?


Solution

  • I'm not sure Commons CLI works with unnamed, position-dependent arguments which, it seems like, is what you're looking for. The way I would write this would be:

    Option endpoint    = OptionBuilder.hasArgs(2)   .isRequired(true) .create("endpoint");
    Option update      = OptionBuilder.hasArg(false).isRequired(false).create("update");
    Option name        = OptionBuilder.hasArg(true) .isRequired(true) .create("name");
    Option type        = OptionBuilder.hasArg(true) .isRequired(false).create("type");
    Option description = OptionBuilder.hasArg(true) .isRequired(false).create("description");
    

    I'm not 100% sure if the first one, endpoint, will require two arguments or just require one but can accept up to two; it would probably be clearer to use two different arguments completely.

    This would result in a help line looking something like:

    usage: admin
    -endpoint <point> [<point>]
    -update
    -name <name>
    [-type <type>]
    [-description <description>]
    

    I generally use a constant for the string name:

    public static final String ENDPOINT = "endpoint";
    ...
    Option endpoint = OptionBuilder.hasArg().create(ENDPOINT);
    

    so that this way you can refer to it later:

    CommandLine opts = parser.parse(myopts, argv);
    String endpoint = opts.getOptionValue(ENDPOINT);
    

    Hope that helps!