Command Line Subcommands in Fortress
Here’s the translation of the Go code to Java, with explanations in Markdown format suitable for Hugo:
Our first program will demonstrate how to create command-line subcommands with their own sets of flags. This is similar to how tools like git
have different subcommands (e.g., git commit
, git push
) with their own specific flags.
import java.util.Arrays;
import org.apache.commons.cli.*;
public class CommandLineSubcommands {
public static void main(String[] args) {
// We declare options for each subcommand
Options fooOptions = new Options();
fooOptions.addOption("enable", false, "enable");
fooOptions.addOption("name", true, "name");
Options barOptions = new Options();
barOptions.addOption("level", true, "level");
// The subcommand is expected as the first argument to the program
if (args.length < 1) {
System.out.println("expected 'foo' or 'bar' subcommands");
System.exit(1);
}
// Check which subcommand is invoked
String subcommand = args[0];
String[] subcommandArgs = Arrays.copyOfRange(args, 1, args.length);
CommandLineParser parser = new DefaultParser();
HelpFormatter formatter = new HelpFormatter();
try {
switch (subcommand) {
case "foo":
// For every subcommand, we parse its own flags and
// have access to trailing positional arguments
CommandLine cmd = parser.parse(fooOptions, subcommandArgs);
System.out.println("subcommand 'foo'");
System.out.println(" enable: " + cmd.hasOption("enable"));
System.out.println(" name: " + cmd.getOptionValue("name"));
System.out.println(" tail: " + Arrays.toString(cmd.getArgs()));
break;
case "bar":
cmd = parser.parse(barOptions, subcommandArgs);
System.out.println("subcommand 'bar'");
System.out.println(" level: " + cmd.getOptionValue("level"));
System.out.println(" tail: " + Arrays.toString(cmd.getArgs()));
break;
default:
System.out.println("expected 'foo' or 'bar' subcommands");
System.exit(1);
}
} catch (ParseException e) {
System.out.println(e.getMessage());
formatter.printHelp(subcommand, subcommand.equals("foo") ? fooOptions : barOptions);
System.exit(1);
}
}
}
To run the program, compile it and use java
:
$ javac -cp commons-cli-1.4.jar CommandLineSubcommands.java
$ java -cp .:commons-cli-1.4.jar CommandLineSubcommands foo -enable -name=joe a1 a2
subcommand 'foo'
enable: true
name: joe
tail: [a1, a2]
Now try the bar subcommand:
$ java -cp .:commons-cli-1.4.jar CommandLineSubcommands bar -level 8 a1
subcommand 'bar'
level: 8
tail: [a1]
But bar won’t accept foo’s flags:
$ java -cp .:commons-cli-1.4.jar CommandLineSubcommands bar -enable a1
Unrecognized option: -enable
usage: bar
-level <arg> level
This example demonstrates how to create a command-line application with subcommands in Java. We’ve used the Apache Commons CLI library to parse command-line options, which provides similar functionality to Go’s flag
package.
Next, we’ll look at environment variables, another common way to parameterize programs.