Command Line Subcommands in Chapel

Here’s the translated Chapel code with explanations in Markdown format suitable for Hugo:

Our first program demonstrates how to create subcommands with their own set of flags. This is similar to how tools like git have different subcommands (e.g., git commit, git push) with their own options.

use Subprocess;
use CTypes;

proc main(args: [] string) {
  // We declare subcommands and their flags
  var fooCmd = new CommLineParser("foo");
  var fooEnable = fooCmd.addOption(name="enable", type=bool);
  var fooName = fooCmd.addOption(name="name", type=string);

  // For a different subcommand we can define different supported flags
  var barCmd = new CommLineParser("bar");
  var barLevel = barCmd.addOption(name="level", type=int);

  // The subcommand is expected as the first argument to the program
  if args.size < 2 {
    writeln("expected 'foo' or 'bar' subcommands");
    exit(1);
  }

  // Check which subcommand is invoked
  select args[1] {
    // For every subcommand, we parse its own flags and
    // have access to trailing positional arguments
    when "foo" {
      fooCmd.parse(args[2..]);
      writeln("subcommand 'foo'");
      writeln("  enable: ", fooEnable.value);
      writeln("  name: ", fooName.value);
      writeln("  tail: ", fooCmd.positionalArgs());
    }
    when "bar" {
      barCmd.parse(args[2..]);
      writeln("subcommand 'bar'");
      writeln("  level: ", barLevel.value);
      writeln("  tail: ", barCmd.positionalArgs());
    }
    otherwise {
      writeln("expected 'foo' or 'bar' subcommands");
      exit(1);
    }
  }
}

To compile and run the program:

$ chpl command_line_subcommands.chpl -o command_line_subcommands

First invoke the foo subcommand:

$ ./command_line_subcommands foo --enable --name=joe a1 a2
subcommand 'foo'
  enable: true
  name: joe
  tail: a1 a2

Now try bar:

$ ./command_line_subcommands bar --level=8 a1
subcommand 'bar'
  level: 8
  tail: a1

But bar won’t accept foo’s flags:

$ ./command_line_subcommands bar --enable a1
error: Unrecognized flag '--enable'

In Chapel, we use the CommLineParser class to handle command-line arguments and subcommands. This is similar to the flag package in other languages. The select statement is used instead of a switch to handle different subcommands.

Next, we’ll look at environment variables, another common way to parameterize programs.