Skogsrå v1.1.1 Skogsra View Source

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.
  • Configuration options documentation.
  • Variables defaults.

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 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"].

Configuration definitions

Calling MyApp.Settings.my_hostname(nil, :system) will print the expected OS environment variable name and MyApp.Settings.my_hostname(nil, :config) will print the expected Mix configuration. If the namespace is necessary, pass it as first parameter.

Reloading

For debugging purposes is possible to reload variables at runtime with MyApp.Settings.my_hostname(nil, :reload).

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]

Link to this section Summary

Types

t()

Skogsra environment variable

Functions

For now is just equivalent to use import Skogsra

Creates a function to retrieve specific environment/application variables values

Link to this section Types

Link to this type

t() View Source
t() :: %Skogsra{
  app_name: app_name :: atom(),
  cache: cache :: reference() | atom(),
  namespace: namespace :: atom(),
  options: options :: Keyword.t(),
  parameters: parameters :: [atom()]
}

Skogsra environment variable.

Link to this section Functions

For now is just equivalent to use import Skogsra.

Link to this macro

app_env(function_name, app_name, parameters, options \\ []) View Source (macro)

Creates a function to retrieve specific environment/application variables values.

The function created is named function_name and will get the value associated with an application called app_name and one or several parameters keys. Optionally, receives a list of options.

Options:

  • default - Default value for the variable in case is not present.
  • type - Type of the variable. Used for casting the value. By default, casts the value to the same type of the default value. If the default value is not present, defaults to :binary. The available values are: :binary, :integer, :float, :boolean, :atom. Additionally, you can provide {module, function} for custom types. The function must receive the binary and return the custom type.
  • os_env - Alias for the variable in the OS. If the alias is nil will use the default name. This option is ignoredif the option skip_system is true (default is false).
  • namespace - Namespace of the variable.
  • skip_system - If true, doesn't look for the variable value in the system. Defaults to false.
  • skip_config - If true, doesn't look for the variable value in the configuration. Defaults to false.
  • required - Errors when the value is nil. Defaults to false.
  • cached - Caches the value on the first read. Defaults to true.

e.g:

For the following declaration:

app_env :db_password, :myapp, [:mydb, :password],
  default: "password",

It will generate the functions db_password/0 and db_password/1. The optional parameter is useful to specify namespaces.

A call to db_password/0 will try to:

  1. Look for the value of $MYAPP_MYDB_PASSWORD OS environment variable. If it's nil, then it will try 2.
  2. Look for the value in the configuration e.g:
   config :myapp,
     mydb: [password: "some password"]

If it's nil, then it will try 3.

  1. Return the value of the default value or nil.

A call to db_password/1 with namespace Test will try to:

  1. Look for the value of $TEST_MYAPP_MYDB_PASSWORD OS environment variable. If it's nil, then it will try 2.
  2. Look for the value in the configuration e.g:
   config :myapp, Test,
     mydb: [password: "some password"]

If it's nil, then it will try 3.

  1. Return the value of the default value or nil.