View Source gourd

An accessible config library for Erlang applications.

Build

rebar3 compile

Usage

Add gourd to your rebar.config:

{deps, [gourd]}.

Load the config at application startup.

-module(example_app).
-behaviour(application).
-export([start/2, stop/1]).

start(_StartType, _StartArgs) ->
    gourd:load(),
    example_sup:start_link().

stop(_State) ->
    ok.

By default gourd:load will load gourd.toml from the application's private directory and set config values for the calling application.

If the above example loaded a gourd.toml like this:

hello = "world"

The config value of hello would be accessible like this:

{ok, Hello} = application:get_env(example, hello).
Hello == <<"world">>

The first set of keys in the TOML file are converted to atoms.

Customize Loading

If gourd's default's don't suit you. The gourd library supports load/1 and load/2.

Specify the application you want priv/gourd.toml to apply to:

gourd:load(example).

To specify the application and the path to load the config file from:

gourd:load(example, "priv/other_gourd.toml")

OR outside of the priv dir:

gourd:load(example, "config.toml")

Environment Variables

It is common to need to load a environment variables at the start of your application.

This feature is supported in gourd by parsing special values in strings and replacing them with their corresponding environment variables.

Assuming these environment variables are present in the running process:

export WORLD="world"
export ENV="prod"
export AWS_REGION="us-east-1"

We can load these as part of the config with a TOML file like this:

hello = "${WORLD}"
env = "${ENV}"
aws_region = "${AWS_REGION}"

This would result in a config that looked like this:

#{hello => <<"world">>,
  env => <<"prod">>,
  aws_region => <<"us-east-1">>}

Special values can even be parsed in the middle of a string:

bucket = "example-${ENV}-${AWS_REGION}"

Would return a config like this:

#{bucket => <<"example-prod-us-east-1">>}

String replacing even works in nested data structures. With the exception that map keys are not replaced.

A toml file like this:

list_values = ["hello", "${WORLD}"]

[map_values]
key1 = "stuff"
key2 = "${ENV}stuff"

Would return a config like this:

#{list_values => [<<"hello">>, <<"world">>],
  map_values => #{<<"key1">> => <<"stuff">>,
                  <<"key2">> => <<"prodstuff">>}}