CommandCougar alternatives and similar libraries
Based on the "Command Line" category.
Alternatively, view CommandCougar alternatives based on common mentions on social networks and blogs.
-
Marathon
Marathon makes it easy to write, run and manage your Swift scripts -
CommandLine
A pure Swift library for creating command-line interfaces -
Swiftline
Swiftline is a set of tools to help you create command line applications. -
Guaka
The smartest and most beautiful (POSIX compliant) Command line framework for Swift 🤖 -
ModuleInterface
Swift tool to generate Module Interfaces for Swift projects. -
Scaffold
Tool for generating code from Stencil templates, similar to rails gen
Appwrite - The Open Source Firebase alternative introduces iOS support
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of CommandCougar or a related project?
README
An elegant pure Swift library for building command line applications.
Features
- [x] Tons of class, but no classes. 100% organic pure value types.
- [x] Auto generated help menus for main command and sub-commands.
- [x] Help menu format is based on swift package manager
- [x] Supports multi command callbacks.
- [x] Swift 4 compatibility
- [x] Zero dependency
- [x] Supports Linux and
swift build
Requirements
- Mac OS X 10.10+ / Ubuntu 14.10
- Xcode 8
- Swift 4
Installation
Swift Package Manager
dependencies: [
.Package(url: "https://github.com/surfandneptune/CommandCougar.git", from: "1.0.0")
]
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
var helloCommand = Command(
name: "hello",
overview: "Say Hello",
callback: { print($0.options, $0.parameters) },
options: [
Option(flag: .short("v"), overview: "Increase verbosity"),
Option(flag: .short("w"), overview: "Wave hello")
],
parameters:[.optional("Name")])
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
.
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.
helloCommand.options // ['-v', '-w']
helloEvaluation.options // ['-v']
helloEvaluation.parameters // ['Mr.Rogers']
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
EBNF
A EBNF of the language supported by CommandCougar is as follows
<command> ::= <word> {<option>} ([<command>] | {<parameter>})
<option> ::= <single> | <double>
<single> ::= -<letter>=[<parameter>]
<double> ::= --<word>=[<parameter>]
<parameter> ::= <word>
<word> ::= <letter>+
<letter> ::= a | b | c | d | e...
CLOC
A line count breakdown to show overall size of the project
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Swift 11 133 411 451
-------------------------------------------------------------------------------
SUM: 11 133 411 451
-------------------------------------------------------------------------------
Communication
- If you found a bug, open an issue.
- If you have a feature request, open an issue.
- If you want to contribute, open an issue or submit a pull request.
License
CommandCougar is released under the MIT license. See LICENSE for details.
*Note that all licence references and agreements mentioned in the CommandCougar README section above
are relevant to that project's source code only.