You're viewing documentation for an older version. View the latest version

Command Overview#

This guide will introduce you to the Command module by showing you how to create your own CLI. For this example, we will implement cowsay, a command that prints an ASCII picture of a cow with a message.

Tip

You can install the real cowsay program using brew install cowsay.

$ cowsay Hello
  -----
< Hello >
  -----
          \   ^__^
           \  (oo\_______
              (__)\       )\/\
                   ||----w |
                   ||     ||

Command#

The first step is to create a type that conforms to Command.

/// Generates ASCII picture of a cow with a message.
struct CowsayCommand: Command {
    ...
}

Now let’s implement the required methods.

Arguments#

Commands can have zero or more CommandArguments. These arguments will be required for the command to run.

/// Generates ASCII picture of a cow with a message.
struct CowsayCommand: Command {
    /// See `Command`
    var arguments: [CommandArgument] {
        return [.argument(name: "message")]
    }
    
    ...
}

Here we are defining one argument, the message that the cow will say. This is required to run the cowsay command.

Options#

Commands can have zero or more CommandOptions. These options are not required for the command to run and can be passed using -- or - syntax.

/// Generates ASCII picture of a cow with a message.
struct CowsayCommand: Command {
    ...
    /// See `Command`
    var options: [CommandOption] {
        return [
            .value(name: "eyes", short: "e", default: "oo", help: ["Change cow's eyes"]),
            .value(name: "tongue", short: "t", default: " ", help: ["Change cow's tongue"]),
        ]
    }
    ...
}

Here we are defining two options, eyes and tongue. These will let the user optionally change how the cow looks.

Help#

Next we can define an optional help message to display when the user passes --help.

/// Generates ASCII picture of a cow with a message.
struct CowsayCommand: Command {
    ...
    /// See `Command`
    var help: [String] {
        return ["Generates ASCII picture of a cow with a message."]
    }
    ...
}

Let’s take a look at how this will look once our command is complete:

Usage: <executable> cowsay <message> [--eyes,-e] [--tongue,-t] 

Generates ASCII picture of a cow with a message.

Arguments:
  message n/a

Options:
     eyes Change cow's eyes
   tongue Change cow's tongue

Run#

Finally, we need to write our implementation:

/// Generates ASCII picture of a cow with a message.
struct CowsayCommand: Command {
    ...
    
    /// See `Command`.
    func run(using context: CommandContext) throws -> Future<Void> {
        let message = try context.argument("message")
        /// We can use requireOption here since both options have default values
        let eyes = try context.requireOption("eyes")
        let tongue = try context.requireOption("tongue")
        let padding = String(repeating: "-", count: message.count)
        let text: String = """
          \(padding)
        < \(message) >
          \(padding)
                  \\   ^__^
                   \\  (\(eyes)\\_______
                      (__)\\       )\\/\\
                        \(tongue)  ||----w |
                           ||     ||
        """
        context.console.print(text)
        return .done(on: context.container)
    }
}

The CommandContext gives you access to everything you will need, including a Container. Now that we have a complete Command, the next step is to configure it.

Config#

Use the CommandConfig struct to register commands to your container. This is usually done in configure.swift

/// Create a `CommandConfig` with default commands.
var commandConfig = CommandConfig.default()
/// Add the `CowsayCommand`.
commandConfig.use(CowsayCommand(), as: "cowsay")
/// Register this `CommandConfig` to services.
services.register(commandConfig)

Check that your command was properly configured using --help.

swift run Run cowsay --help

That’s it!

$ swift run Run cowsay 'Good job!' -e ^^ -t U
  ---------
< Good job! >
  ---------
          \   ^__^
           \  (^^\_______
              (__)\       )\/\
                U  ||----w |
                   ||     ||