I know this question has been asked many times here and elsewhere before as I am searching for the answer. However, it still puzzles me why the command line parser library doesn't provide this common usage scenario, where I have a group of subcommands, each subcommand has its own set of required and optional arguments. Similar construct can be found in git/svn, though in their case, the subcommand command is a standalone program if I am not mistaken.
To summarize, what I am looking for is an easy way to:
top_command subcmd_A [ command A's options ....]
top_command subcmd_B [ command B's options ....]
...
In java's world, two often mentioned library are Apache Command CLI and JSAP. I don't see either of them have this in mind - though you could probably tweak and customize a lot to fit ... but the basic flow of defining a option, register ... then at the end, parse them all doesn't seen to consider the case with different subcommands, the validation and parser need to behave in different way.
Maybe the common wisdom here is that this is too application specific and should be left to the application itself to handle. One way I can think of is to define a BaseCommand class, and each subcommand extends it and register themself ... as a way to break it up for easy management. If any mature framework can do this, I'd appreciate any pointer here.
I could be wrong about my understanding of current parser capability though, any insight is much appreciated.
Hi just take a look into jcommander which exactly supports the described scenario.
You mentioned Commons CLI which is true in the releases 1.X but there exists a development for CLI2 which supports this as well, but unfortunately this release has never been published.
Args4j now supports subcommands (starting with version 2.0.23 or thereabouts).
picocli supports nested subcommands to arbitrary depth.
The main command defines global options, each following level of nested commands can add options that only apply to that level.
CommandLine commandLine = new CommandLine(new MainCommand())
.addSubcommand("cmd1", new ChildCommand1()) // 1st level
.addSubcommand("cmd2", new ChildCommand2())
.addSubcommand("cmd3", new CommandLine(new ChildCommand3()) // 2nd level
.addSubcommand("cmd3sub1", new GrandChild3Command1())
.addSubcommand("cmd3sub2", new GrandChild3Command2())
.addSubcommand("cmd3sub3", new CommandLine(new GrandChild3Command3()) // 3rd
.addSubcommand("cmd3sub3sub1", new GreatGrandChild3Command3_1())
.addSubcommand("cmd3sub3sub2", new GreatGrandChild3Command3_2())
// etc
)
);
You may also like its usage help with ANSI styles and colors.
Note that usage help lists the registered subcommands in addition to options and positional parameters.
The usage help is easily customized with annotations.
- annotation-based
- git-style subcommands
- nested sub-subcommands
- strongly typed option parameters
- strongly typed positional parameters
- customizable type conversion
- multi-value options
- intuitive model for how many arguments a field consumes
- fluent API
- POSIX-style clustered short options
- GNU style long options
- allows any option prefix
- ANSI colors in usage help
- customizable usage help
- single source file: include as source to keep your application a single jar
Have a look at cli-parsec
. It features (among other things) exactly what I believe you want :-)
https://github.com/dr1fter/cli-parsec
It features arbitrary nesting of sub-commands (sub-commands may have sub-commands and so on). Each sub command may define options. A simple example is given here (two sub-commands with individual options):
https://github.com/dr1fter/cli-parsec/wiki/Example
Maven snippet:
<dependency>
<groupId>de.dr1fter</groupId>
<artifactId>de.dr1fter.cli-parsec>
<version>0.2.1</version>
</dependency>