Skip to content

Elixir library providing dynamic hierarchical configurations loading for your application.

License

Notifications You must be signed in to change notification settings

alexiob/spellbook

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

64 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Spellbook

Build Status Inline docs Hex version Coverage Status hex.pm downloads

Introduction

Spellbook is an Elixir library providing dynamic hierarchical configurations loading for your application. It is based on the ideas implemented in the Javascript node-config module.

It lets you define a set of default parameters, and extend them for different deployment environments (development, staging, production, etc.) or custom needs (client id, hostname, etc.).

Configurations are stored in default or custom folders containing configuration files and can be overridden and extended by environment variables.

Custom configuration static and dynamic filenames and file formats can be added as needed.

Installation

Add Spellbook as a dependency to your mix.exs file.

defp deps do
  [{:spellbook, "~> 2.0.3"}]
end

Documentation

The API reference can be found here.

Quick Start

Read the configuration files from the standard <CWD>/config folder

config = Spellbook.load_config_folder()

Using Spellbook.load_config_folder/0 by default will use the following filename templates (in the listed order and if they exist) with the {SOMETHING} template variables substituted:

<CWD>/config/default.{EXT}
<CWD>/config/default-{INSTANCE}.{EXT}
<CWD>/config/{ENV}.{EXT}
<CWD>/config/{ENV}-{INSTANCE}.{EXT}
<CWD>/config/{SHORT_HOSTNAME}.{EXT}
<CWD>/config/{SHORT_HOSTNAME}-{INSTANCE}.{EXT}
<CWD>/config/{SHORT_HOSTNAME}-{ENV}.{EXT}
<CWD>/config/{SHORT_HOSTNAME}-{ENV}-{INSTANCE}.{EXT}
<CWD>/config/{FULL_HOSTNAME}.{EXT}
<CWD>/config/{FULL_HOSTNAME}-{INSTANCE}.{EXT}
<CWD>/config/{FULL_HOSTNAME}-{ENV}.{EXT}
<CWD>/config/{FULL_HOSTNAME}-{ENV}-{INSTANCE}.{EXT}
<CWD>/config/local.{EXT}
<CWD>/config/local-{INSTANCE}.{EXT}
<CWD>/config/local-{ENV}.{EXT}
<CWD>/config/local-{ENV}-{INSTANCE}.{EXT}
<CWD>/config/custom-env-variables.{EXT}

Spellbook will use the default environment ({ENV} = dev) and the full hostname of the machine the code gets executed on ({FULL_HOSTNAME} = my-machine.spellbook.domain). As the other template variables are not defined, the filenames using them are ignored. The resulting filenames searched/merged will be:

<CWD>/config/default.json
<CWD>/config/default.yaml
<CWD>/config/dev.json
<CWD>/config/dev.yaml
<CWD>/config/my-machine.spellbook.domain.json
<CWD>/config/my-machine.spellbook.domain.yaml
<CWD>/config/my-machine.spellbook.domain-dev.json
<CWD>/config/my-machine.spellbook.domain-dev.yaml
<CWD>/config/local.json
<CWD>/config/local.yaml
<CWD>/config/local-dev.json
<CWD>/config/local-dev.yaml
<CWD>/config/custom-env-variables.json
<CWD>/config/custom-env-variables.yaml

By default Spellbook supports JSON and YAML file formats.

Read brand's configuration from a specific folder with custom settings for a specific client

config = Spellbook.default_config()
|> Spellbook.add_filename_format("clients/#{brand}.#{ext}")
|> Spellbook.load_config(
  folder: "./test/support/brand",
  config_filename: "brand-conf",
  vars: [instance: "job-processor", brand: "elixir", env: "prod", short_hostname: "worker"]
)

Here we specify a specific folder were to look for the configuration files (with the folder option), a custom configuration file name (with the config_filename option). The vars configuration field is used to define the variable values used in the filename templates.

The Spellbook.default_config/0 function (and the Spellbook.load_config/0 one as well) configures the Spellbook to search for the following file templates:

./test/support/brand/{CONFIG\_FILENAME}.{EXT}
./test/support/brand/{CONFIG\_FILENAME}-{INSTANCE}.{EXT}
./test/support/brand/{CONFIG\_FILENAME}-{ENV}.{EXT}
./test/support/brand/{CONFIG\_FILENAME}-{SHORT_HOSTNAME}-{ENV}-{INSTANCE}.{EXT}
./test/support/brand/{CONFIG\_FILENAME}-{FULL_HOSTNAME}-{ENV}-{INSTANCE}.{EXT}
./test/support/brand/clients/{BRAND}.{EXT}
./test/support/brand/custom-env-variables.{EXT}

In this case the searched/merged files will be:

./test/support/brand/brand-conf.json
./test/support/brand/brand-conf.yaml
./test/support/brand/brand-conf-job-processor.json
./test/support/brand/brand-conf-job-processor.yaml
./test/support/brand/brand-conf-prod.json
./test/support/brand/brand-conf-prod.yaml
./test/support/brand/brand-conf-worker-prod-job-processor.json
./test/support/brand/brand-conf-worker-prod-job-processor.yaml
./test/support/brand/brand-conf-worker1.spellbook.domain-prod-job-processor.json
./test/support/brand/brand-conf-worker1.spellbook.domain-prod-job-processor.yaml
./test/support/brand/clients/elixir.json
./test/support/brand/clients/elixir.yaml
./test/support/brand/custom-env-variables.json
./test/support/brand/custom-env-variables.yaml

Get a value out of a Spellbook configuration

A configuration is just a Map.

iex> config = Spellbook.load_config_folder()
%{ "some" => %{ "value" => %{ "from" => %{ "config" => "a value" }}}}
iex> is_map(config) == true
true

You can access the configuration values using the standard language features

iex> value = config["some"]["value"]["from"]["config"]
"a value"

or using the Spellbook.get method that supports dot notation to access elements deep down the configuration structure:

iex> value = Spellbook.get(config, "some.value.from.config")
"a value"

Use environment variables in configuration files

Some situations rely heavily on environment variables to configure secrets and settings best left out of a codebase. Spellbook lets you use map the environment variable names into your configuration structure using a custom-env-variables.{EXT} file:

{
  "database": {
    "username": "DB_USERNAME",
    "password": "DB_PASSWORD"
  }
}

If the DB_USERNAME and DB_PASSWORD environment variable exist, they would override the values for database.username and database.password in the configuration.

A special syntax allows environment variables typecast as well:

{
  "database": {
    "port": "DB_PORT.integer"
  }
}

Will convert the "DB_PORT" environment variable into an integer. Supported typecasts are:

  • "integer" (also "int", "i")
  • "float" (also "f")
  • "boolean" (also "bool", "b"): converts "false", "f", "0" to false, everything else to true.

Custom environment variables have precedence and override all configuration files, including local.json.

License

Spellbook is provided under the MIT license

About

Elixir library providing dynamic hierarchical configurations loading for your application.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages