Swiftpack.co - Package - SDGGiesbrecht/SDGCommandLine

macOS • Linux



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).

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:

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


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

import SDGCommandLine

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

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

                        if let specific = options.value(for: phrase) {
                        } else {

let phrase = Option<StrictString>(name: UserFacing<StrictString, MyLocalizations>({ _ in "phrase" }),
                                  description: UserFacing<StrictString, MyLocalizations>({ _ 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

Tests are easy to set up:

func testParrot() {
    switch parrot.execute(with: ["speak", "•phrase", "Hello, world!"]) {
    case .success(let output):
        XCTAssertEqual(output, "Hello, world!")
    case .failure:
        XCTFail("The parrot is not co‐operating.")


SDGCommandLine provides libraries for use with the Swift Package Manager.

Simply add SDGCommandLine as a dependency in Package.swift and specify which of the libraries to use:

let package = Package(
    name: "MyPackage",
    dependencies: [
        .package(url: "https://github.com/SDGGiesbrecht/SDGCommandLine", from: Version(1, 1, 0)),
    targets: [
        .target(name: "MyTarget", dependencies: [
            .productItem(name: "SDGCommandLine", package: "SDGCommandLine"),
            .productItem(name: "SDGCommandLineTestUtilities", package: "SDGCommandLine"),
            .productItem(name: "SDGExportedCommandLineInterface", package: "SDGCommandLine"),

The libraries’ modules can then be imported in source files:

import SDGCommandLine
import SDGCommandLineTestUtilities
import SDGExportedCommandLineInterface


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: 3
Help us keep the lights on



1.1.0 - Jul 30, 2019

New Features

  • The provided interface elements are localized into German.

1.0.2 - Jul 11, 2019

Dependency updates.

1.0.1 - Jul 3, 2019

Bug Fixes

Dependency updates.

1.0.0 - Jun 13, 2019

Breaking Changes

  • Modules do not export each other. Each must be imported separately.
    • The @_exported attribute was never officially supported by Swift anyway. As the last remaining thing blocking the 1.0.0 release, it was deemed not important enough to delay until official support. Since it is not strictly necessary for any functionality, it has been removed instead of waiting.

0.7.4 - Jun 1, 2019

Bug Fixes

Dependency updates.