Skip to content

Instantly share code, notes, and snippets.

@cweinberger
Last active December 12, 2019 10:03
Show Gist options
  • Save cweinberger/e43bd765d4217cbc5a12cf4ef820dd94 to your computer and use it in GitHub Desktop.
Save cweinberger/e43bd765d4217cbc5a12cf4ef820dd94 to your computer and use it in GitHub Desktop.
Custom arguments when running Vapor

How to add (and read) custom arguments when launching a vapor app.

In app.swift I have added a struct AppOptions to keep track of custom options and added another parameter options to the app(_:) function:

import Vapor

public struct AppOptions {
    public var foo: String?
    
    public init(foo: String? = nil) {
        self.foo = foo
    }
}

/// Creates an instance of `Application`. This is called from `main.swift` in the run target.
public func app(_ env: Environment, options: AppOptions? = nil) throws -> Application {
    var config = Config.default()
    var env = env
    var services = Services.default()
    try configure(&config, &env, &services)
    let app = try Application(config: config, environment: env, services: services)
    try boot(app)
    return app
}

In main.swift I have added a step to parse custom flags from the commandline (and feed them into the AppOptions struct). Then I hand this AppOptions struct to my app.

import App
import Vapor

var appOptions = AppOptions()

var commandInput = CommandInput(arguments: CommandLine.arguments)

if let value = try commandInput.parse(option: .value(name: "foo")) {
    print("foo: \(value)")
    appOptions.foo = value
}

try app(.detect(from: &commandInput), options: appOptions).run()

From there you could further use it to customize your boot/config routine.

Tested with running:

vapor run serve --env staging --hostname 127.0.0.1 --port 8099 --foo bar

Prints:

foo: 'bar'

Calling commandInput.parse(option:) will remove the parsed option from the input. Hence vapors ServeCommand won't see it (and therefore won't complain) You can probably use the same method for your custom commands so you dont have to spin up the vapor app server etc just to perform a command.

Or even simpler: use Environment.arguments to get the command you are running. Based on that you could skip steps in your configure.swift.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment