CommandCougar supports a main command as well as subcommands. This is much like
the swift package manager interface.
Command
A command is a struct that is used to outline the structure of your command line interface. It can have either a list of subcommands or a list of (.required | .optional) parameters.
Once a command has been created, it can be evaluated against a list of
arguments, usually taken from CommandLine.arguments. The evaluate function
creates and returns a CommandEvaluation.
let arguments = ["hello", "-v", "Mr.Rogers"]
let helloEvaluation = helloCommand.evaluate(arguments: arguments)
Typically, the input of the arguments will be supplied by CommandLine.arguments. Please note that CommandCougar automatically drops the first argument.
let helloEvaluation = helloCommand.evaluate(arguments: CommandLine.arguments)
Reading a CommandEvaluation
A CommandEvaluation is a struct for representing the results of evaluating a Command against a list of arguments.
Notice the evaluation only includes the options which were seen in the arguments list.
Performing callbacks
Callbacks pass the CommandEvaluation as an input to the function
that was set in the Command before evaluation.
try helloEvaluation.performCallbacks()
Help menu automatically generated
The help menu is auto generated and the option is added
to the command option set.
$ hello --help
OVERVIEW: Say Hello
USAGE: hello [option] <command>
COMMANDS:
OPTIONS:
-h, --help The help menu
-v Increase verbosity
-w Wave hello
Options
Options can have either a short flag ie -v or a long flag ie --verbose.
Options are allowed to have a single optional parameter. The flag and parameter must be joined with an = ie --path=/tmp.
// will match -v
Option(flag: .short("v"), overview: "verbose")
// will match -v | --verbose
Option(flag: .both(short: "v", long: "verbose"), overview: "verbose")
// will match --path=/etc
Option(flag: .long("path"), overview: "File path", parameterName: "/etc")
Subcommands
Many command line interfaces like git or the swift package manager allow for subcommands. CommandCougar also allows this to be expressed. A rule to notice is that a command that has subcommands is not allowed to also have parameters.
Consider this command:
swift package -v update --repin
swift is the main command.
package is a subcommand of the swift command with -v as an option.
update is a subcommand of the package command with --repin as an option.
A command to express this list of arguments would be as follows:
/// Used for callback
func echo(evaluation: Command.Evaluation) throws {
print(
"\(evaluation.name) evaluated with " +
"options: \(evaluation.options) " +
"and parameters \(evaluation.parameters)"
)
}
let swiftCommand =
Command(
name: "swift",
overview: "Swift Program",
callback: echo,
options: [],
subCommands: [
Command(
name: "package",
overview: "Perform operations on Swift packages",
callback: echo,
options: [
Option(
flag: .both(short: "v", long: "verbose"),
overview: "Increase verbosity of informational output"),
Option(
flag: .long("enable-prefetching"),
overview: "Increase verbosity of informational output")
],
subCommands: [
Command(
name: "update",
overview: "Update package dependencies",
callback: echo,
options: [
Option(
flag: .long("repin"),
overview: "Update without applying pins and repin the updated versions.")
],
subCommands: [])
])
])
Evaluating Subcommands
When evaluating the root command all subcommands will also be evaluated and their callbacks will be fired.
do {
// normally CommandLine.arguments
let args = ["swift", "package", "-v", "update", "--repin"]
let evaluation: Command.Evaluation = try swiftCommand.evaluate(arguments: args)
try evaluation.performCallbacks()
} catch {
print(error)
}
// Output
// swift evaluated with options: [] and parameters []
// package evaluated with options: [-v] and parameters []
// update evaluated with options: [--repin] and parameters []
Accessing the values of the CommandEvaluation
To directly access the values of the returned CommandEvaluation
evaluation["package"]?.name // results in "package"
evaluation["package"]?.options["v"] // results in Option.Evaluation
evaluation["package"]?.options["v"]?.flag.shortName // results in "v"
evaluation["package"]?.options["enable-prefetching"] // results in nil
evaluation["package"]?["update"]?.options["repin"]?.flag.longName // results in "repin"
Access with throw
To access parameters by index you may use parameter(at: Int) throws -> String. If the parameter does
not exist a parameterAccessError will be thrown.
This will turn:
func callback(evaluation: CommandEvaluation) throws {
guard let first = evaluation.parameters.first else {
throw CommandCougar.Errors.parameterAccessError("Parameter not found.")
}
}
Into:
func callback(evaluation: CommandEvaluation) throws {
let first = try evaluation.parameter(at: 0)
}
Help menu different for subcommands
Help is also generated for subcommands
$ swift package --help
OVERVIEW: Perform operations on Swift packages
USAGE: swift package [option] <command>
COMMANDS:
update Update package dependencies
OPTIONS:
-v, --verbose Increase verbosity of informational output
--enable-prefetching Enable prefetching in resolver
-h, --help The help menu
An elegant pure Swift library for building command line applications.
Features
swift build
Requirements
Installation
Swift Package Manager
Usage
CommandCougar supports a main command as well as subcommands. This is much like the swift package manager interface.
Command
A command is a
struct
that is used to outline the structure of your command line interface. It can have either a list of subcommands or a list of (.required
|.optional
) parameters.Creating a
Command
Evaluating a
Command
Once a command has been created, it can be evaluated against a list of arguments, usually taken from CommandLine.arguments. The evaluate function creates and returns a
CommandEvaluation
.Typically, the input of the arguments will be supplied by CommandLine.arguments. Please note that CommandCougar automatically drops the first argument.
Reading a
CommandEvaluation
A
CommandEvaluation
is astruct
for representing the results of evaluating aCommand
against a list of arguments.Notice the evaluation only includes the options which were seen in the arguments list.
Performing callbacks
Callbacks pass the
CommandEvaluation
as an input to the function that was set in theCommand
before evaluation.Help menu automatically generated
The help menu is auto generated and the option is added to the command option set.
Options
Options can have either a short flag ie
-v
or a long flag ie--verbose
. Options are allowed to have a single optional parameter. The flag and parameter must be joined with an=
ie--path=/tmp
.Subcommands
Many command line interfaces like git or the swift package manager allow for subcommands. CommandCougar also allows this to be expressed. A rule to notice is that a command that has subcommands is not allowed to also have parameters.
Consider this command:
swift
is the main command.package
is a subcommand of theswift
command with-v
as an option.update
is a subcommand of thepackage
command with--repin
as an option.A command to express this list of arguments would be as follows:
Evaluating
Subcommands
When evaluating the root command all subcommands will also be evaluated and their callbacks will be fired.
Accessing the values of the
CommandEvaluation
To directly access the values of the returned
CommandEvaluation
Access with throw
To access parameters by index you may use
parameter(at: Int) throws -> String
. If the parameter does not exist aparameterAccessError
will be thrown.This will turn:
Into:
Help menu different for subcommands
Help is also generated for subcommands
EBNF
A EBNF of the language supported by CommandCougar is as follows
CLOC
A line count breakdown to show overall size of the project
Communication
License
CommandCougar is released under the MIT license. See LICENSE for details.