Package - SDGGiesbrecht/SDGCommandLine

APIs: macOSLinux


SDGCommandLine provides tools for implementing a command line interface.

יְהַלְלוּ אֶת־שֵׁם יהוה כִּי הוּא צִוָּה וְנִבְרָאוּ׃
May they praise the name of the Lord, for He commanded and they came into being!

                                                                                                    ―a psalmist


  • Automatic parsing of options and subcommands
  • Automatic help subcommand
  • Testable output
  • Colour formatting tools
    • Automatic •no‐colour option
  • Interface localization
    • Automatic set‐language subcommand to set language preferences.
    • Automatic •language option to run in a specific language only once.
  • Versioning tools
    • Automatic version subcommand
    • Automatic •use‐version option to attempt to download and temporarily use a specific version instead of the one which is installed (only for public Swift packages).

(For a list of related projecs, see here.)


SDGCommandLine is intended for use with the Swift Package Manager.

Simply add SDGCommandLine as a dependency in Package.swift:

let package = Package(
    dependencies: [
        .Package(url: "", versions: "0.1.2" ..< "0.2.0"),

SDGCommandLine can then be imported in source files:

import SDGCommandLine

Example Usage

 This example creates a tool with the following interface:

 $ parrot speak

 $ parrot speak •phrase "Hello, world!"
 Hello, world!

 // main.swift must consist of the following lines:

 import Foundation
 import SDGCommandLine

 SDGCommandLine.initialize(applicationIdentifier: "tld.Developper.Parrot", version: Version(1, 0, 0), packageURL: URL(string: "https://website.tld/Parrot"))


// The rest can be anywhere in the project:
// (putting it in a separate, testable library module is recommended)

import SDGCornerstone // See
import SDGCommandLine

public let parrot = Command(name: UserFacingText<MyLocalizations, Void>({ _, _ in "parrot" }),
                            description: UserFacingText<MyLocalizations, Void>({ _, _ in "behaves like a parrot." }),
                            subcommands: [speak])

let speak = Command(name: UserFacingText<MyLocalizations, Void>({ _, _ in "speak" }),
                    description: UserFacingText<MyLocalizations, Void>({ _, _ in "speaks." }),
                    directArguments: [],
                    options: [phrase],
                    execution: { (_, options: Options, output: inout Command.Output) throws -> Void in

                        if let specific = options.value(for: phrase) {
                            print(specific, to: &output)
                        } else {
                            print("Squawk!", to: &output)

let phrase = Option<StrictString>(name: UserFacingText<MyLocalizations, Void>({ _, _ in "phrase" }),
                                  description: UserFacingText<MyLocalizations, Void>({ _, _ in "A custom phrase to speak." }),
                                  type: ArgumentType.string)

enum MyLocalizations : String, InputLocalization {
    case english = "en"
    internal static let cases: [MyLocalizations] = [.english]
    internal static let fallbackLocalization: MyLocalizations = .english

// It is easy to set up tests:

func testParrot() {
    do {
        let output = try parrot.execute(with: ["speak", "•phrase", "Hello, world!"])
        XCTAssertEqual(output, "Hello, world!")
    } catch {
        XCTFail("The parrot is not co‐operating.")


The SDGCommandLine project is maintained by Jeremy David Giesbrecht.

If SDGCommandLine saves you money, consider giving some of it as a donation.

If SDGCommandLine saves you time, consider devoting some of it to contributing back to the project.

Ἄξιος γὰρ ὁ ἐργάτης τοῦ μισθοῦ αὐτοῦ ἐστι.
For the worker is worthy of his wages.



Stars: 1



0.1.2 - Nov 11, 2017

No differences to published API.

0.1.1 - Nov 3, 2017

New Features

  • A new Command method, execute(withArguments:options:output), makes it easier to run one command within the execution of another.

0.1.0 - Oct 18, 2017

Initial Release