Typed options and arguments

The described Option and Argument classes are untyped, meaning that the only get String values.

TypedOption and TypedArgument let you specify a type, so the (String) raw value is converted to the specified type.

Instead of Option and Argument, use TypedOption and TypedArgument in the CLI definition:

CLI cli = CLI.create("copy")
    .setSummary("A command line interface to copy files.")
    .addOption(new TypedOption<Boolean>()
        .setType(Boolean.class)
        .setLongName("directory")
        .setShortName("R")
        .setDescription("enables directory support")
        .setFlag(true))
    .addArgument(new TypedArgument<File>()
        .setType(File.class)
        .setIndex(0)
        .setDescription("The source")
        .setArgName("source"))
    .addArgument(new TypedArgument<File>()
        .setType(File.class)
        .setIndex(0)
        .setDescription("The destination")
        .setArgName("target"));

Then you can retrieve the converted values as follows:

CommandLine commandLine = cli.parse(userCommandLineArguments);
boolean flag = commandLine.getOptionValue("R");
File source = commandLine.getArgumentValue("source");
File target = commandLine.getArgumentValue("target");

The vert.x CLI is able to convert to classes:

  • having a constructor with a single String argument, such as File or JsonObject

  • with a static from or fromString method

  • with a static valueOf method, such as primitive types and enumeration

In addition, you can implement your own Converter and instruct the CLI to use this converter:

CLI cli = CLI.create("some-name")
    .addOption(new TypedOption<Person>()
        .setType(Person.class)
        .setConverter(new PersonConverter())
        .setLongName("person"));

For booleans, the boolean values are evaluated to true: on, yes, 1, true.

Using annotations

You can also define your CLI using annotations. Definition is done using annotation on the class and on setter methods:

@Name("some-name")
@Summary("some short summary.")
@Description("some long description")
public class AnnotatedCli {

  private boolean flag;
  private String name;
  private String arg;

 @Option(shortName = "f", flag = true)
 public void setFlag(boolean flag) {
   this.flag = flag;
 }

 @Option(longName = "name")
 public void setName(String name) {
   this.name = name;
 }

 @Argument(index = 0)
 public void setArg(String arg) {
  this.arg = arg;
 }
}

Once annotated, you can define the CLI and inject the values using:

CLI cli = CLI.create(AnnotatedCli.class);
CommandLine commandLine = cli.parse(userCommandLineArguments);
AnnotatedCli instance = new AnnotatedCli();
CLIConfigurator.inject(commandLine, instance);