Introduction

Often, you’ll want to run specific tasks around maintenance, cleanup or productivity for your Alchemy app.

The Command interface makes this a cinche, allowing you to create custom commands to run your application with. It’s built on the powerful Swift Argument Parser making it easy to add arguments, options, flags and help functionality to your custom commands. All commands have access to services registered in Application.boot so it’s easy to interact with whatever database, queues, & other functionality that your app already has.

Included Commands

Run Commands

When Alchemy is run, it takes an argument that determines how it behaves on launch. When no argument is passed, the default command is serve which boots the app and serves it on the machine.

There are also migrate and queue commands which help run migrations and queue workers/schedulers respectively.

You can run these like so.

swift run Server migrate

Each command has options for customizing how it runs. If you’re running your app from Xcode, you can configure launch arguments by editing the current scheme and navigating to Run -> Arguments.

If you’re looking to extend your Alchemy app with your own custom commands, check out Commands.

Serve

swift run or swift run Server serve

OptionDefaultDescription
—host127.0.0.1The host to listen on
—port3000The port to listen on
—unixSocketnilThe unix socket to listen on. Mutually exclusive with host & port
—workers0The number of workers to run
—schedulefalseWhether scheduled tasks should be scheduled
—migratefalseWhether any outstanding migrations should be run before serving
—envenvThe environment to load

Migrate

swift run Server migrate

OptionDefaultDescription
—rollbackfalseShould migrations be rolled back instead of applied
—envenvThe environment to load

Queue

swift run Server queue

OptionDefaultDescription
—namenilThe queue to monitor. Leave empty to monitor Queue.default
—channelsdefaultThe channels to monitor, separated by comma
—workers1The number of workers to run
—schedulefalseWhether scheduled tasks should be scheduled
—envenvThe environment to load

make Commands

Out of the box, Alchemy includes a variety of commands to boost your productivity and generate commonly used interfaces. These commands are prefaced with make:, and you can see all available ones with swift run MyApp help.

For example, the make:model command makes it easy to generate a model with the given fields. You can event generate a full populated Migration and Controller with CRUD routes by passing the --migration and --controller flags.

$ swift run Server make:model Todo id:increments:primary name:string is_done:bool user_id:bigint:references.users.id --migration --controller
🧪 create Sources/App/Models/Todo.swift
🧪 create Sources/App/Migrations/2021_09_24_11_07_02CreateTodos.swift
          └─ remember to add migration to your database config!
🧪 create Sources/App/Controllers/TodoController.swift

Like all commands, you may view the details & arguments of each make command with swift run MyApp help <command>.

Writing A Custom Command

To create a command, conform to the Command protocol, implement func start(), and register it with app.registerCommand(...). Now, when you run your Alchemy app you may pass your custom command name as an argument to execute it.

For example, let’s say you wanted a command that prints all user emails in your default database.

final class PrintUserEmails: Command {
    // see Swift Argument Parser for other configuration options
    static var configuration = CommandConfiguration(commandName: "print")

    func start() -> EventLoopFuture<Void> {
        User.all()
            .mapEach { user in
                print(user.email)
            }
            .voided()
    }
}

Now just register the command, likely in your Application.boot

app.registerCommand(PrintUserEmails.self)

and you can run your app with the print argument to run your command.

$ swift run MyApp print
...
jack@twitter.com
elon@tesla.com
mark@facebook.com

Adding Options, Flags, and help info

Because Command inherits from Swift Argument Parser’s ParsableCommand you can easily add flags, options, and configurations to your commands. There’s also support for adding help & discussion strings that will show if your app is run with the help argument.

final class SyncUserData: Command {
    static var configuration = CommandConfiguration(commandName: "sync", discussion: "Sync all data for all users.")

    @Option var id: Int?
    @Flag(help: "Loaded data but don't save it.") var dry: Bool = false

    func start() -> EventLoopFuture<Void> {
        if let userId = id {
            // sync only a specific user's data
        } else {
            // sync all users' data
        }
    }
}

You can now pass options and flags to this command like so swift run MyApp sync --id 2 --dry and it run with the given arguments.

Printing help info

Out of the box, your server can be run with the help argument to show all commands available to it, including any custom ones your may have registered.

$ swift run MyApp help
OVERVIEW: Run an Alchemy app.

USAGE: launch [--env <env>] <subcommand>

OPTIONS:
  -e, --env <env>         (default: env)
  -h, --help              Show help information.

SUBCOMMANDS:
  serve (default)
  migrate
  queue
  make:controller
  make:middleware
  make:migration
  make:model
  make:job
  make:view
  sync

  See 'launch help <subcommand>' for detailed help.

You can also pass a command name after help to get detailed information on that command, based on the information your provide in your configuration, options, flags, etc.

$ swift run MyApp help sync
OVERVIEW:
Sync all data for all users.

USAGE: MyApp sync [--id <id>] [--dry]

OPTIONS:
  -e, --env <env>         (default: env)
  --id <id>               Sync data for a specific user only.
  --dry                   Should data be loaded but not saved.
  -h, --help              Show help information.

Note that you can always pass -e, --env <env-file> to any command to have it load your environment from a custom env file before running.