Command Line Subcommands in Karel
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, each with its own set 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();
try {
switch (subcommand) {
// For every subcommand, we parse its own flags and
// have access to trailing positional arguments
case "foo":
CommandLine fooCmd = parser.parse(fooOptions, subcommandArgs);
System.out.println("subcommand 'foo'");
System.out.println(" enable: " + fooCmd.hasOption("enable"));
System.out.println(" name: " + fooCmd.getOptionValue("name"));
System.out.println(" tail: " + Arrays.toString(fooCmd.getArgs()));
break;
case "bar":
CommandLine barCmd = parser.parse(barOptions, subcommandArgs);
System.out.println("subcommand 'bar'");
System.out.println(" level: " + barCmd.getOptionValue("level"));
System.out.println(" tail: " + Arrays.toString(barCmd.getArgs()));
break;
default:
System.out.println("expected 'foo' or 'bar' subcommands");
System.exit(1);
}
} catch (ParseException e) {
System.out.println("Error parsing command line: " + e.getMessage());
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
Error parsing command line: Unrecognized option: -enable
Note that this Java implementation uses the Apache Commons CLI library to handle command-line parsing, which provides functionality similar to the flag
package in Go. You’ll need to include this library in your classpath when compiling and running the program.
Next, we’ll look at environment variables, another common way to parameterize programs.