skogsra v0.2.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.
- Options documentation.
- Variables defaults.
Small Example
You would create a settings module and define the e.g:
defmodule MyApp.Settings do
use Skogsra
system_env :some_service_port,
default: 4000
app_env :some_service_hostname, :my_app, :hostname,
domain: MyApp.Repo,
default: "localhost"
end
and you would use it in a module as follows:
defmodule MyApp.SomeModule do
alias MyApp.Setting
(...)
def connect do
hostname = Settings.some_service_hostname()
port = Settings.some_service_port()
SomeService.connect(hostname, port)
end
(...)
end
Example Explanation
The module MyApp.Settings will have two functions e.g:
some_service_port/0: Returns the port as an integer. Calling this function is roughly equivalent to the following code (without the automatic type casting):System.get_env("SOME_SERVICE_PORT") || 4000some_service_hostname/0: Returns the hostname as a binary. Calling this function is roughly equivalent to the following code (without the automatic type casting):case System.get_env("SOME_SERVICE_HOSTNAME") do nil -> :my_app |> Application.get_env(MyApp.Domain, []) |> Keyword.get(:hostname, "localhost") value -> value end
Things to note:
- The functions have the same name as the OS environment variable, but in lower case.
- The functions infer the type from the
defaultvalue. If no default value is provided, it will be casted as binary by default. Both functions try to retrieve and cast the value of an OS environment variable, but the one declared with
app_envsearches for:my_appconfiguration if the OS environment variable is empty:config :my_app, MyApp.Domain, hostname: "some_hostname"
If the default value is not present, Skogsra cannot infer the type, unless the
type is set with the option type. The possible values for type are
:integer, :float, :boolean, :atom and :binary.
Recommended Usage
The recommended way of using this project is to define a .env file in the
root of your project with the variables that you want to define e.g:
export SOME_SERVICE_PORT=1234
and then when sourceing the file right before you execute your application.
In bash (or zsh) would be like this:
$ source .env
The previous step can be automated by adding the following code to your
~/.bashrc (or ~/.zshrc):
#################
# BEGIN: Auto env
export LAST_ENV=
function auto_env_on_chpwd() {
env_type="$1"
env_file="$PWD/.env"
if [ -n "$env_type" ]
then
env_file="$PWD/.env.$env_type"
if [ ! -r "$env_file" ]
then
echo -e "[33mFile $env_file does not exist.[0m"
env_file="$PWD/.env"
fi
fi
if [ -n "$LAST_ENV" ] && [ -r "$LAST_ENV" ]
then
UNSET=$(cat $LAST_ENV | sed -e 's/^export ([0-9a-zA-Z_]*)=.*$/unset 1/')
source <(echo "$UNSET")
echo -e "[33mUnloaded ENV VARS defined in "$LAST_ENV"[0m"
export LAST_ENV=
fi
if [ -r "$env_file" ]
then
export LAST_ENV="$env_file"
source $LAST_ENV
echo -e "[32mLoaded "$LAST_ENV"[0m"
fi
}
chpwd_functions=(${chpwd_functions[@]} "auto_env_on_chpwd")
if [ -n "$TMUX" ]
then
auto_env_on_chpwd
fi
alias change_to='function _change_to() {auto_env_on_chpwd $1}; _change_to'
# END: Auto env
###############
The previous code will attempt to source any .env file every time you
change directory e.g:
/home/alex $ cd my_app
Loaded "/home/alex/my_app/.env"
/home/alex/my_app $ echo "$SOME_SERVICE_PORT"
1234
Additionally, the command change_to <ENV> is included. To keep your prod,
dev and test environment variables separated, just create a
.env.${MIX_ENV} in the root directory of your project. And when you want to
use the variables set in one of those files, just run the following:
$ change_to dev # Will use `.env.dev` instead of `.env`
Link to this section Summary
Functions
For now is just equivalent to use import Skogsra
Macro that receives the name of the OS environment variable, the name of
the app, the name of the option key and some optional Keyword list with
options and generates a function with arity 0 with the same name of the OS
environment variable, but in lower case e.g. "FOO" would generate the
function foo/0
Gets the OS environment variable by its name if present in the option
:name. If it’s not found, attempts to get the application configuration
option by the app name and the option key. Optionally receives a
Keyword list of options
Gets the OS environment variable by its name and cast it the the type of
the default value. If no default value is provided, returns a string.
If the OS environment variable is not found, returns the default value.
Gets the OS environment variable by its name and casts it to the provided
type. If the OS environment variable is not found, returns the default
value
Macro that receives the name of the OS environment variable and some
optional Keyword list with options and generates a function with arity 0
with the same name of the OS environment variable, but in lower case e.g.
"FOO" would generate the function foo/0
Link to this section Functions
For now is just equivalent to use import Skogsra.
Macro that receives the name of the OS environment variable, the name of
the app, the name of the option key and some optional Keyword list with
options and generates a function with arity 0 with the same name of the OS
environment variable, but in lower case e.g. "FOO" would generate the
function foo/0.
The available options are:
:static- Whether the computation of the OS environment variable or application configuration option is done on compiling time or not. By default its value isfalse.:default- Default value in case the OS environment variable and the application configuration option don’t exist. By default isnil.:type- The type of the OS environment variable. By default is the type of the default value. If there is no default value, the default type isbinary. The available types are:binary,:integer,:float,:booleanand:atom.:domain- Thekeyto search in the configuration file e.g in:config :my_app, MyApp.Repo, (...)the domain would be
MyApp.Repo. By default, there is no domain.
e.g
defmodule Settings do
use Skogsra
app_env :foo, :my_app, :foo,
default: 42,
type: :integer,
domain: MyApp.Domain
end
This would generate the function Settings.foo/0 that would search for
the OS environment variable "FOO" and cast it to integer on runtime. If the
OS environment variable is not found, attempts to search for the :foo
configuration option for the application :my_app and the domain
MyApp.Domain. If nothing is found either, it defaults to 42.
Calling Settings.foo/0 without a domain set is equivalent to:
with value when not is_nil(value) <- System.get_env("FOO"),
{number, _} <- Integer.parse(value) do
number
else
_ ->
Application.get_env(:my_app, :foo, 42)
end
Calling Settings.foo/0 with a domain set is equivalent to:
with value when not is_nil(value) <- System.get_env("FOO"),
{number, _} <- Integer.parse(value) do
number
else
_ ->
opts = Application.get_env(:my_app, MyApp.Domain, [])
Keyword.get(opts, :foo, 42)
end
Gets the OS environment variable by its name if present in the option
:name. If it’s not found, attempts to get the application configuration
option by the app name and the option key. Optionally receives a
Keyword list of options
i.e:
:name- Name of the OS environment variable. By default is"".:default- Default value in case the OS environment variable and the application configuration option don’t exist. By default isnil.:type- The type of the OS environment variable. By default is the type of the default value. If there is no default value, the default type isbinary. The available types are:binary,:integer,:float,:booleanand:atom.:domain- Thekeyto search in the configuration file e.g in:config :my_app, MyApp.Repo, hostname: "localhost", (...)the domain would be
MyApp.Repo. By default, there is no domain. If the domain is a list of atoms forces the algorithm to go recursively in the structure to find the key.
e.g:
defmodule MyApp do
def get_hostname do
Skogsra.get_app_env(:my_app, :hostname, domain: MyApp.Repo, name: "SOME_SERVICE_HOSTNAME")
end
end
Gets the OS environment variable by its name and cast it the the type of
the default value. If no default value is provided, returns a string.
If the OS environment variable is not found, returns the default value.
Gets the OS environment variable by its name and casts it to the provided
type. If the OS environment variable is not found, returns the default
value.
Macro that receives the name of the OS environment variable and some
optional Keyword list with options and generates a function with arity 0
with the same name of the OS environment variable, but in lower case e.g.
"FOO" would generate the function foo/0.
The available options are:
:static- Whether the computation of the OS environment variable is done on compiling time or not. By default its value isfalse.:default- Default value in case the OS environment variable doesn’t exist. By default isnil.:type- The type of the OS environment variable. By default is the type of the default value. If there is no default value, the default type isbinary. The available types are:binary,:integer,:float,:booleanand:atom.
e.g
defmodule Settings do
use Skogsra
system_env :foo,
default: 42,
type: :integer
end
This would generate the function Settings.foo/0 that would search for
the OS environment variable "FOO" and cast it to integer on runtime and
defaults to 42.