Skogsrå

Build Status Hex pm hex.pm downloads

The Skogsrå was a mythical creature of the forest that appears in the form of a small, beautiful woman with a seemingly friendly temperament. However, those who are enticed into following her into the forest are never seen again.

This library attempts to improve the use of OS environment variables for application configuration:

  • Automatic type casting of values.
  • Variable defaults.
  • Automatic documentation generation for variables.
  • Runtime reloading.
  • Setting variable's values at runtime.
  • Fast cached values access by using :persistent_term as temporal storage.

Small Example

You would create a settings module e.g:

defmodule MyApp.Settings do
  use Skogsra

  @envdoc "My hostname"
  app_env :my_hostname, :myapp, :hostname,
    default: "localhost"
end

Calling MyApp.Settings.my_hostname() will retrieve the value for the hostname in the following order:

  1. From the OS environment variable $MYAPP_HOSTNAME.
  2. From the configuration file e.g:
   config :myapp,
     hostname: "my.custom.host"
  1. From the default value if it exists (In this case, it would return "localhost").

Handling different environments

If it's necessary to keep several environments, it's possible to use a namespace e.g:

Calling MyApp.Settings.my_hostname(Test) will retrieve the value for the hostname in the following order:

  1. From the OS environment variable $TEST_MYAPP_HOSTNAME.
  2. From the configuration file e.g:
   config :myapp, Test,
     hostname: "my.custom.test.host"
  1. From the OS environment variable $MYAPP_HOSTNAME.
  2. From the configuraton file e.g:
   config :myapp,
     hostname: "my.custom.host"
  1. From the default value if it exists.

Required variables

It is possible to set a environment variable as required with the required option e.g:

defmodule MyApp.Settings do
  use Skogsra

  @envdoc "My port"
  app_env :my_port, :myapp, :port,
    required: true
end

If the variable $MYAPP_PORT is undefined and the configuration is missing, calling to MyApp.Settings.my_port() will return an error tuple. Calling $MyApp.Settings.my_port!() (with the bang) will raise a runtime exception.

Automatic casting

If the default value is set, the OS environment variable value will be casted as the same type of the default value. Otherwise, it is possible to set the type for the variable with the option type. The available types are :binary (default), :integer, :float, :boolean and :atom. Additionally, you can create a function to cast the value and specify it as {module_name, function_name} e.g:

defmodule MyApp.Settings do
  use Skogsra

  @envdoc "My channels"
  app_env :my_channels, :myapp, :channels,
    type: {__MODULE__, channels},
    required: true

  def channels(value), do: String.split(value, ", ")
end

If $MYAPP_CHANNELS's value is "ch0, ch1, ch2" then the casted value will be ["ch0", "ch1", "ch2"].

Setting and reloading variables

It's possible to set a value for the variable at runtime with e.g. MyApp.Settings.put_my_hostname("my.other.hostname").

Also, for debugging purposes is possible to reload variables at runtime with e.g. MyApp.Settings.reload_my_hostname().

Using with Hab

Hab is an Oh My ZSH plugin for loading OS environment variables automatically.

By default, Hab will try to load .envrc file, but it's possible to have several of those files for different purposes e.g:

  • .envrc.prod for production OS variables.
  • .envrc.test for testing OS variables.
  • .envrc for development variables.

Hab will load the development variables by default, but it can load the other files using the command load_hab <extension> e.g. loading .envrc.prod would be as follows:

~/my_project $ load_hab prod
[SUCCESS]  Loaded hab [/home/user/my_project/.envrc.prod]

Installation

The package can be installed by adding skogsra to your list of dependencies in mix.exs.

  • For Elixir < 1.7 and Erlang < 21:
  def deps do
    [{:skogsra, "~> 1.0.4"}]
  end
  • For Elixir < 1.8 and ≥ 1.7 and Erlang < 22 and ≥ 21
  def deps do
    [{:skogsra, "~> 1.2"}]
  end
  • For Elixir ≥ 1.8 and Erlang ≥ 22
  def deps do
    [{:skogsra, "~> 1.3"}]
  end

Author

Alexander de Sousa.

License

Skogsrå is released under the MIT License. See the LICENSE file for further details.