Command Line Subcommands in Nim
Here’s the translation of the Go code to Nim, along with explanations in Markdown format suitable for Hugo:
Some command-line tools have many subcommands, each with its own set of flags. For example, git add
and git commit
are two different subcommands of the git
tool. Nim’s parseopt
module lets us easily define simple subcommands that have their own flags.
import os, parseopt
proc main() =
# We declare subcommands and their flags using a case statement
# within the parsing loop
var p = initOptParser(commandLineParams())
var cmd = ""
for kind, key, val in p.getopt():
case kind
of cmdArgument:
if cmd == "":
cmd = key
else:
case cmd
of "foo":
echo "tail argument for foo: ", key
of "bar":
echo "tail argument for bar: ", key
else:
echo "Unknown command"
quit(1)
of cmdLongOption, cmdShortOption:
case cmd
of "foo":
case key
of "enable":
echo "foo enable: ", val
of "name":
echo "foo name: ", val
else:
echo "Unknown option for foo: ", key
of "bar":
case key
of "level":
echo "bar level: ", val
else:
echo "Unknown option for bar: ", key
else:
echo "Unknown command"
quit(1)
of cmdEnd: assert(false) # cannot happen
if cmd == "":
echo "expected 'foo' or 'bar' subcommands"
quit(1)
case cmd
of "foo":
echo "subcommand 'foo'"
of "bar":
echo "subcommand 'bar'"
else:
echo "expected 'foo' or 'bar' subcommands"
quit(1)
when isMainModule:
main()
To run the program, save it as command_line_subcommands.nim
and use the Nim compiler:
$ nim c -r command_line_subcommands.nim
First, invoke the foo subcommand:
$ ./command_line_subcommands foo --enable=true --name=joe a1 a2
subcommand 'foo'
foo enable: true
foo name: joe
tail argument for foo: a1
tail argument for foo: a2
Now try bar:
$ ./command_line_subcommands bar --level=8 a1
subcommand 'bar'
bar level: 8
tail argument for bar: a1
But bar won’t accept foo’s flags:
$ ./command_line_subcommands bar --enable a1
Unknown option for bar: enable
In Nim, we use the parseopt
module to handle command-line arguments and flags. The structure is a bit different from Go, as we parse all options in a single loop and use a case statement to handle different subcommands and their specific flags.
This example demonstrates how to create a command-line tool with subcommands in Nim. Each subcommand can have its own set of flags and handle its own logic.