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