Command Line Subcommands in Swift Here’s the translation of the Go code to Swift, formatted in Markdown suitable for Hugo:
Our first program demonstrates how to use command-line 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 specific flags.
import Foundation
func main () {
// We declare a subcommand using CommandLine.arguments
// and proceed to define new flags specific for this subcommand.
let fooCmd = ArgumentParser ( commandName : "foo" , usage : "foo [--enable] [--name NAME]" )
let fooEnable = fooCmd . add ( flag : "enable" , shortName : "e" , kind : Bool . self , usage : "enable" )
let fooName = fooCmd . add ( option : "name" , shortName : "n" , kind : String . self , usage : "name" )
// For a different subcommand we can define different supported flags.
let barCmd = ArgumentParser ( commandName : "bar" , usage : "bar [--level LEVEL]" )
let barLevel = barCmd . add ( option : "level" , shortName : "l" , kind : Int . self , usage : "level" )
// The subcommand is expected as the first argument to the program.
guard CommandLine . arguments . count >= 2 else {
print ( "expected 'foo' or 'bar' subcommands" )
exit ( 1 )
}
// Check which subcommand is invoked.
switch CommandLine . arguments [ 1 ] {
// For every subcommand, we parse its own flags and
// have access to trailing positional arguments.
case "foo" :
do {
let result = try fooCmd . parse ( Array ( CommandLine . arguments . dropFirst ()))
print ( "subcommand 'foo'" )
print ( " enable:" , result . get ( fooEnable ))
print ( " name:" , result . get ( fooName ) ?? "" )
print ( " tail:" , result . positionalArguments )
} catch {
print ( error )
fooCmd . printUsage ()
}
case "bar" :
do {
let result = try barCmd . parse ( Array ( CommandLine . arguments . dropFirst ()))
print ( "subcommand 'bar'" )
print ( " level:" , result . get ( barLevel ) ?? 0 )
print ( " tail:" , result . positionalArguments )
} catch {
print ( error )
barCmd . printUsage ()
}
default :
print ( "expected 'foo' or 'bar' subcommands" )
exit ( 1 )
}
}
main ()
To run the program, compile it and then use the resulting executable:
$ swiftc command_line_subcommands.swift -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: Unexpected argument --enable
Usage: bar [ --level LEVEL]
-l, --level LEVEL level
Next we’ll look at environment variables, another common way to parameterize programs.