estatico / confide

Derived configuration for Scala

GitHub

Confide

Build Status Gitter Maven Central

Automatic configuration decoding for Scala

Setup

SBT

val confideVersion = "0.0.3"

libraryDependencies ++= Seq(
  "io.estatico" %% "confide-core" % confideVersion,
  "io.estatico" %% "confide-macros" % confideVersion,
)

To be able to use the @Conf macro, you'll need the Paradise compiler plugin.

addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full),

Maven

<properties>
  ...
  <confide.version>0.0.3</confide.version>
</properties>
...
<dependencies>
  ...
  <dependency>
    <groupId>io.estatico</groupId>
    <artifactId>confide-core_${scala.binaryVersion}</artifactId>
    <version>${confide.version}</version>
  </dependency>
  <dependency>
    <groupId>io.estatico</groupId>
    <artifactId>confide-macros_${scala.binaryVersion}</artifactId>
    <version>${confide.version}</version>
  </dependency>
</dependencies>

To be able to use the @Conf macro, you'll need the Paradise compiler plugin.

<pluginManagement>
  ...
  <plugins>
    <plugin>
      <groupId>org.scala-tools</groupId>
      <artifactId>maven-scala-plugin</artifactId>
      <version>${scala.plugin.version}</version>
      <configuration>
        <compilerPlugins>
          <compilerPlugin>
            <groupId>org.scalamacros</groupId>
            <artifactId>paradise_${scala.version}</artifactId>
            <version>2.1.0</version>
          </compilerPlugin>
        </compilerPlugins>
      </configuration>
    </plugin>
  </plugins>
</pluginManagement>

Usage

Given the configuration file below -

api {
  cache {
    enable: true
    ttl: 5m
  }
  greetings = ["Hello", "Hola", "Bonjour"]
}

We can define the following Scala classes to automatically decode the config for us -

import io.estatico.confide._

@Conf final case class AppConfig(
  api: ApiConf
)

@Conf final case class ApiConf(
  cache: CacheConf,
  greetings: List[String]
)

@Conf final case class CacheConf(
  enable: Boolean,
  ttl: FiniteDuration
)

The case classes are pretty self-evident; they simply define the structure of the config we wish to decode.

The @Conf macro will derive an instance of FromConfObj for the annotated case class. FromConf[A] and FromConfObj[A] are type classes which describes how to decode config values to type A. Derivation leverages the wonderful shapeless library. All the @Conf macro does is inject an implicit FromConfObj.derive into the case class' companion object.

scala> ConfideFactory.load[AppConfig]()
AppConfig(ApiConf(CacheConf(true,300000000000 nanoseconds),List(Hello, Hola, Bonjour)))