package org.djutils.cli; import java.util.List; import picocli.CommandLine; import picocli.CommandLine.ParseResult; /** * CliIUtil offers a helper method to display --help and --version without starting the program. The method is used as follows: * *
 * public static void main(final String[] args) throws Exception
 * {
 *     Program program = new Program(); // initialize the Checkable class with the @Option information
 *     CliUtil.execute(program, args); // register Unit converters, parse the command line, catch --help, --version and error
 *     // do rest of what the main method should do
 * }
 * 
* * When the program is Checkable, the check() method is called after the arguments have been parsed. Here, further * checks on the arguments (i.e., range checks) can be carried out. Potentially, check() can also provide other initialization * of the program to be executed, but this can better be provided by other methods in main() . Make sure that expensive * initialization is not carried out in the constructor of the program class that is given to the execute method. * Alternatively, move the command line options to a separate class, e.g. called Options and initialize that class rather than * the real program class. The real program can then take the values of the program from the Options class. An example: * *
 * public class Program
 * {
 *     @Command(description = "Test program for CLI", name = "Program", mixinStandardHelpOptions = true, version = "1.0")
 *     public static class Options implements Checkable
 *     {
 *         @Option(names = {"-p", "--port"}, description = "Internet port to use", defaultValue = "80")
 *         private int port;
 * 
 *         public int getPort()
 *         {
 *             return this.port;
 *         }
 * 
 *         @Override
 *         public void check() throws Exception
 *         {
 *             if (this.port <= 0 || this.port > 65535)
 *                 throw new Exception("Port should be between 1 and 65535");
 *         }
 *     }
 * 
 *     public Program()
 *     {
 *         // initialization for the program; avoid really starting things
 *     }
 * 
 *     public static void main(final String[] args)
 *     {
 *         Options options = new Options();
 *         CliUtil.execute(options, args);
 *         System.out.println("port = " + options.getPort());
 *         // you can now call methods on the program, e.g. for real initialization using the CLI parameters in options
 *     }
 * }
 * 
* *
* Copyright (c) 2019-2019 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See * for project information www.simulation.tudelft.nl. The * source code and binary code of this software is proprietary information of Delft University of Technology. * @author Alexander Verbraeck */ public class CliIUtil { /** * Register Unit converters, parse the command line, catch --help, --version and errors. Calls the "check" method of the * class that can take care of further checks of the CLI arguments. Potentially, check() can also provide other * initialization of the program to be executed, but this can better be provided by other methods in main(). The method will * exit on requesting help or version information, or when the arguments are not complete or not correct. * @param program Checkable; the checkable program with the @Option information * @param args String[]; the arguments from the command line */ public static void execute(final Checkable program, final String[] args) { CommandLine cmd = new CommandLine(program); CliUnitConverters.registerAll(cmd); cmd.getCommandSpec().parser().collectErrors(true); ParseResult parseResult = cmd.parseArgs(args); List parseErrors = parseResult.errors(); if (parseErrors.size() > 0) { for (Exception e : parseErrors) { System.err.println(e.getMessage()); } System.exit(-1); } if (parseResult.isUsageHelpRequested()) { cmd.usage(System.out); System.exit(0); } else if (parseResult.isVersionHelpRequested()) { cmd.printVersionHelp(System.out); System.exit(0); } try { program.check(); } catch (Exception exception) { System.err.println(exception.getMessage()); System.exit(-1); } } }