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
:
and you do not need to worry about
all the boring stuff and directly focus on implementing the actual logic providing the features.
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 extendinginvalid reference
CliMain
public class MyProgram extendsAs you can see your main program is pretty simple and straight forward. The only specific part is the{ @Override protected void addCommands() { super.addCommands(); group().add(MyCommand.class); } public static void main(String[] args) { new MyProgram().runAndExit(args); } }invalid reference
CliMain
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) {
invalid reference
CliConsole
console = main.
invalid reference
console()
;
if (Debug().get()) {
console.
invalid reference
debug()
.
invalid reference
log("Debug mode is active")
;
}
if (Verbose().get()) {
console.
invalid reference
info()
.
invalid reference
log("Verbose output is active")
;
}
if (Force().get()) {
console.
invalid reference
warning()
.
invalid reference
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 oninvalid reference
CliMain
-
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.