defmodule Alembix do
@moduledoc ~S"""
## Install
In your `mix.exs` file add alembix to the release config
```
defp releases do
[
api: [
include_executables_for: [:unix],
applications: [
runtime_tools: :permanent,
alembic: :permanent,
api: :permanent
],
runtime_config_path: "config/releases.exs",
]
]
end
```
## Use
In your release.exs file use Alembix to fetch variables.
```
config :api, :server, Alembic.fetch_boolean!("START_SERVER")
```
"""
@spec fetch_env(String.t()) :: any
@spec fetch_env(String.t(), any) :: any
def fetch_env(name, default \\ nil), do: System.get_env(name) || default
@spec fetch_env!(String.t()) :: String.t() | :no_return
def fetch_env!(name) do
case fetch_env(name) do
nil ->
raise "Missing enviroment env variable #{name}"
value ->
value
end
end
@spec fetch_boolean(String.t()) :: boolean | nil
@spec fetch_boolean(String.t(), any) :: boolean | nil
def fetch_boolean(name, default \\ []) do
name
|> fetch_env(default)
|> parse_boolean(name)
end
@spec fetch_boolean!(String.t()) :: boolean | :no_return
def fetch_boolean!(name) do
case fetch_boolean(name) do
boolean when boolean in [true, false] -> boolean
value -> raise("Expected boolean for #{name} got #{value}")
end
end
# sobelow_skip ["DOS.StringToAtom"]
@spec fetch_atom(String.t()) :: atom
@spec fetch_atom(String.t(), any) :: atom
def fetch_atom(name, default \\ nil) do
case fetch_env(name, default) do
value when is_atom(value) -> value
value -> String.to_atom(value)
end
end
# sobelow_skip ["DOS.StringToAtom"]
@spec fetch_atom!(String.t()) :: atom | :no_return
def fetch_atom!(name) do
case fetch_atom(name) do
nil -> raise "Missing enviroment env variable #{name}"
value -> value
end
end
@spec fetch_integer(String.t()) :: integer | nil
def fetch_integer(name, default \\ nil) do
case fetch_env(name, default) do
nil -> nil
value when is_integer(value) -> value
value -> String.to_integer(value)
end
end
@spec fetch_integer!(String.t()) :: integer
def fetch_integer!(name) do
case fetch_integer(name) do
nil -> raise "Missing enviroment env variable #{name}"
value -> value
end
end
@spec fetch_base_16(String.t()) :: binary | nil
def fetch_base_16(name, default \\ nil) do
case fetch_env(name, default) do
nil ->
nil
value ->
value
|> Base.decode16(case: :mixed)
|> case do
:error ->
raise "Invalid base 16 enviroment env variable #{name}"
{:ok, value} ->
value
end
end
end
def fetch_base_16!(name) do
case fetch_base_16(name) do
nil -> raise "Missing enviroment env variable #{name}"
value -> value
end
end
defp parse_boolean("true", _), do: true
defp parse_boolean("false", _), do: false
defp parse_boolean(value, _) when is_boolean(value), do: value
defp parse_boolean(_, _), do: nil
end