README.md

# 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">>}}