Last active
March 5, 2020 14:22
-
-
Save pathikrit/a0aab4b5da4493baf2dac79a38f11945 to your computer and use it in GitHub Desktop.
Better Config
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.util.control.NonFatal | |
import better.files.Scanner.Read | |
/** | |
* Extend this trait to create your application config | |
* | |
* Pros of this approach: | |
* 1) Library free approach - only 15 lines of dependency free "library" (four one-line defs for you to override) | |
* 2) Failures happen when the Config object is loaded instead of when a config value is accessed | |
* 3) Strongly typed | |
* 4) Overrides can be provided using both system properties and/or environment variables | |
* 5) No more config file DSL - your configs are in plain old Scala | |
* 6) Easily understandable error messages | |
* 7) You can define your own Read instances to read complex objects as configs | |
*/ | |
trait Config { | |
protected def configValue(key: String): Option[String] = | |
sys.props.get(key) orElse sys.env.get(key) | |
protected def config[A](key: String)(implicit read: Read[A]): Option[A] = | |
configValue(key) map {c => | |
try { | |
read(c) | |
} catch { | |
case NonFatal(e) => throw new IllegalArgumentException(s"Could not parse config value=$c for key=$key", e) | |
} | |
} | |
protected def config[A: Read](key: String, defaultValue: => A): A = | |
config(key).getOrElse(defaultValue) | |
protected def configOrError[A: Read](key: String, errorMsgPrefix: String = "Missing config"): A = | |
config(key, throw new NoSuchElementException(s"$errorMsgPrefix key=$key")) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// usage | |
object MyConfig extends Config { | |
object db { | |
val host: String = config("db.host", "postgres.rds.com") | |
val port: Int = config("db.port", 9099) | |
val pass: String = configOrError("db.password") | |
} | |
object aws { | |
val secret: String = config("aws.secret").getOrElse(new AWSPasswordManager().load().getPassword()) | |
} | |
} | |
// access | |
val driver = new PsqlDriver(host = MyConfig.db.host, host = MyConfig.db.port) |
@alwins0n: It just imports a Read
typeclass which many common libraries like cats and better-files have it. You can just implement the Read
typeclass yourself then if you want truly library free - it will be 15 more lines of code then...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
hey nice, but its not library free if it imports, well, a library