Main Methods
We can now combine the previous derivations together to make a main method.
This main method has 2 modes
- fully configured from the command line and environment variables
- configured from a config file plus overrides
The config file may be JSON
or YAML
and will be parsed by deriving the associated circe Decoder
instances, you can bring your own ones of these.
import com.monovore.decline._
import net.andimiller.recline.annotations._
import net.andimiller.recline.generic._
import io.circe.generic.auto._
case class GraphiteConfig(
hostname: String,
port: Int
)
case class Configuration(
port: Int,
@cli.autokebab
adminPort: Int,
graphite: Option[GraphiteConfig]
)
val main = deriveCommand[Configuration]("my program", "an example program")
// main: Command[Configuration] = com.monovore.decline.Command@5a9c66d4
main.parse(List("--help"))
// res0: Either[Help, Configuration] = Left(Usage:
// my program [--port <integer>] [--admin-port <integer>] [[--graphite-hostname <string>] [--graphite-port <integer>] | [--graphite-hostname <string>] [--graphite-port <integer>]] <config>
// my program [--port <integer>] [--admin-port <integer>] [[--graphite-hostname <string>] [--graphite-port <integer>]]
//
// an example program
//
// Options and flags:
// --help
// Display this help text.
// --port <integer>
//
// --admin-port <integer>
//
// --graphite-hostname <string>
//
// --graphite-port <integer>
//
//
// Environment Variables:
// PORT=<integer>
//
// ADMIN_PORT=<integer>
// GRAPHITE_HOSTNAME=<string>
// GRAPHITE_PORT=<integer>)
So we’ve derived our main method, we can run it with a config file:
main.parse(List("./docs/src/main/resources/example.yml"))
// res1: Either[Help, Configuration] = Right(Configuration(8080,8080,Some(GraphiteConfig(localhost,2003))))
We can run it with a config file and override parts of it from the CLI or env variables:
main.parse(List("./docs/src/main/resources/example.yml", "--port", "1234"), env = Map("ADMIN_PORT" -> "9876"))
// res2: Either[Help, Configuration] = Right(Configuration(1234,9876,Some(GraphiteConfig(localhost,2003))))
We could configure the whole thing via flags:
main.parse(List(
"--port", "123",
"--admin-port", "456"
))
// res3: Either[Help, Configuration] = Right(Configuration(123,456,None))