Skip to content
Massimiliano Ziccardi edited this page Jan 24, 2017 · 7 revisions

Creating an ant like command line

A commons-cli equivalent

In this document. we are going to describe how to create a command line by using the ls example (the example syntax has been taken from the commons-cli documentation.

ant [options] [target [target2 [target3] ...]]
  Options: 
  -help                  print this message
  -projecthelp           print project help information
  -version               print the version information and exit
  -quiet                 be extra quiet
  -verbose               be extra verbose
  -debug                 print debugging information
  -emacs                 produce logging information without adornments
  -logfile <file>        use given file for log
  -logger <classname>    the class which is to perform logging
  -listener <classname>  add an instance of class as a project listener
  -buildfile <file>      use given buildfile
  -D<property>=<value>   use value for given property
  -find <file>           search for buildfile towards the root of the
                         filesystem and use it

The following code can be used to parse this command line with YACLP:

Parser parser = ParserBuilder
    .forOptionsBasedCli()
    .withOption(
        OptionBuilder.forOption("--help").description("print this message").build(),
        OptionBuilder.forOption("--projecthelp").description("print project help information").build(),
        OptionBuilder.forOption("--version").description("print the version information and exit").build(),
        OptionBuilder.forOption("--quiet").description("be extra quiet").build(),
        OptionBuilder.forOption("--verbose").description("be extra verbose").build(),
        OptionBuilder.forOption("--debug").description("print debugging information").build(),
        OptionBuilder.forOption("--emacs").description("produce logging information without adornments").build(),
        OptionBuilder.forOption("--logfile").description("use given file for log")
            .argument(ArgumentBuilder.forArgument("file").build())
            .build(),
        OptionBuilder.forOption("--logger").description("the class which is to perform logging")
            .argument(ArgumentBuilder.forArgument("classname").build())
            .build(),
        OptionBuilder.forOption("--listener").description("add an instance of class as a project listener")
            .argument(ArgumentBuilder.forArgument("classname").build())
            .build(),
        OptionBuilder.forOption("--buildfile").description("use given buildfile")
            .argument(ArgumentBuilder.forArgument("file").build())
                    .build(),
        OptionBuilder.forPropertyOption("-D").description("use value for given property").build(),
        OptionBuilder.forOption("--find")
            .description("search for buildfile towards the root of the filesystem and use it")
            .argument(ArgumentBuilder.forArgument("file").build())
            .build()
    )
    .build();

try {
    CommandLine commandLine = parser.parse(args);
} catch (ParsingException pe) {
    System.out.println ("ERROR: " + pe.getMessage());
    HelpFormatter hf = new HelpFormatter("ant", parser);
    hf.printUsage(System.out);
    hf.printHelp(System.out);
}

The above code does exactly the same thing as the commons-cli ant example.

Using YACLP effectively

There are many improvement to the previous code we could do by using YACLP:

  • if --help is specified, no other parameter should be accepted. Same for --version
  • --quite can't be used together with --verbose
  • --buildfile must point to an accessible file
  • ...

All those improvements can be achieved by the use of MutuallyExclusiveOptions (see here) and a argument validators (see here).

To check, for example, that the argument passed to --buildfile is an accessible file, we could use the following code:

OptionBuilder.forOption("--buildfile").description("use given buildfile")
    .argument(ArgumentBuilder.forArgument("file")
        .withValidator(
            ValidatorBuilder.forFile()
                .exists()
                .isFile()
                .isReadable()
                .build()
        )
        .build())
    .build(),
Clone this wiki locally