Module io.github.mmm.cli
module io.github.mmm.cli
Provides the infrastructure to implement a command-line-interface (CLI) to parse, validate and bind the arguments of
a
main method and execute the selected command.Command-Line-Interface (CLI)
Building a Java application with a CLI is kind of tedious.The Problem
A regular Java application starts with amain method:
public static void main(String[] args) {
// ...
}
However, you quickly notice that this was not the end of wisdom when designing an object-oriented language as Java.
A main-program often starts easy and then over the time options and arguments are added. When you want to write a
maintainable main-program you want to have more infrastructure than just having a String-array lost in a
static method. The Solution
Simply create your main program extendingCliMain:
public class MyProgram extends CliMain {
@Override
protected void addCommands() {
super.addCommands();
group().add(MyCommand.class);
}
public static void main(String[] args) {
new MyProgram().runAndExit(args);
}
}
As you can see your main program is pretty simple and straight forward. The only specific part is the
group().add(MyCommand.class) statement. Here you could even provide multiple commands to add. Further you
could add them to a named group so their help arguments will be
grouped together. However, let us first continue with the example code of the command:
public interface MyCommand extends CliCommand {
@PropertyAlias({ "--verbose", "-v" })
BooleanProperty Verbose();
@PropertyAlias({ "--debug", "-d" })
BooleanProperty Debug();
@PropertyAlias({ "--force", "-f" })
BooleanProperty Force();
@Mandatory
@PropertyAlias("--data")
ListProperty Data();
@Mandatory
@PropertyAlias("0") // 0-based order index required for multiple values
StringProperty Value();
@Override
default int run(CliMain main) {
CliConsole console = main.console();
if (Debug().get()) {
console.debug().log("Debug mode is active");
}
if (Verbose().get()) {
console.info().log("Verbose output is active");
}
if (Force().get()) {
console.warning().log("Force mode is active - all files will be overridden without interactive confirmation");
}
for (String data : Data().get()) {
// ... do whatever your command should do ...
}
}
}
Now you can run this MyProgram program with:
MyProgram -v -d -f --data file1 --data file2 my-valueYou can quickly guess what will happen, but you can also do the same thing with:
MyProgram -vdf --data file1,file2 my-valueAlso you could do the same thing with:
MyProgram -vdf --data=file1 --data=file2 my-valueThere is build-in support to print the help via
-h or --help:
MyProgram --helpAll you need to do is add resource bundles for your commands what even supports internationalization. So assuming the qualified name for your command is
net.example.app.MyCommand then you create a file
src/main/resources/l10n/net/example/app/MyCommand.properties with the following content:
help=...does what my command should do... Debug=Activate debug mode to get additional debug log output. Force=Activate force mode to overwrite files without interactive confirmation. Verbose=Activate verbose output. Data=The data file(s) to process. Value=The actual value to assign.So for localization to other languages you could even create resource bundle files for additional languages (E.g.
MyCommand_es.properties).
Also if you have a manifest file with the version you can even get the program version:
MyProgram --versionAlso there is support for
-- in case you want to provide an argument value starting with a hyphen (e.g.
"-foo-value" what would otherwise be considered as short options):
MyProgram -vdf --data file1,file2 -- -foo-valueFurther, to provide option values starting with a hyphen or comma always use option assignments:
MyProgram -vdf --data=-file1 --data=file,2 -- -my-value
Conclusion
Simply implement your main program based onCliMain and you do not need to worry about
all the boring stuff and directly focus on implementing the actual logic providing the features.-
Packages
ExportsPackageDescriptionContains the API and implementation to parse the arguments of amainmethod from a command-line-interface (CLI).Contains CLI arguments as options and values.ContainsCliCommandinterface with default commands for help and version.Contains common exceptions for CLI.