Commands
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
orswift run Server serve
Option | Default | Description |
---|---|---|
—host | 127.0.0.1 | The host to listen on |
—port | 3000 | The port to listen on |
—unixSocket | nil | The unix socket to listen on. Mutually exclusive with host & port |
—workers | 0 | The number of workers to run |
—schedule | false | Whether scheduled tasks should be scheduled |
—migrate | false | Whether any outstanding migrations should be run before serving |
—env | env | The environment to load |
Migrate
swift run Server migrate
Option | Default | Description |
---|---|---|
—rollback | false | Should migrations be rolled back instead of applied |
—env | env | The environment to load |
Queue
swift run Server queue
Option | Default | Description |
---|---|---|
—name | nil | The queue to monitor. Leave empty to monitor Queue.default |
—channels | default | The channels to monitor, separated by comma |
—workers | 1 | The number of workers to run |
—schedule | false | Whether scheduled tasks should be scheduled |
—env | env | The 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.