Skip to content

Instantly share code, notes, and snippets.

@arathunku
Forked from jmglov/config.ex
Created April 21, 2017 07:32
Show Gist options
  • Save arathunku/632c0ca23bc1bfeba621d5a1ded54bcd to your computer and use it in GitHub Desktop.
Save arathunku/632c0ca23bc1bfeba621d5a1ded54bcd to your computer and use it in GitHub Desktop.
Elixir: override Mix config with environment variables
defmodule Config do
defmacro __using__(_) do
quote do
import unquote(__MODULE__), only: :macros
end
end
defmacro cfg(key, type \\ :string) do
quote do
defp unquote(key)() do
unquote(__MODULE__).get(__MODULE__, unquote(key), unquote(type))
end
end
end
@app_name :my_app
def get(module, key, type \\ :string) do
case System.get_env(env_var(module, key)) do
nil -> Application.get_env(@app_name, module)[key]
str -> parse_val(str, type)
end
end
def get_all do
Application.get_all_env(@app_name)
|> Enum.map(fn {module, _} -> {module_name(module), get_module(module)} end)
|> Enum.into(Map.new)
end
def get_module(module) do
Application.get_env(@app_name, module)
|> Enum.map(fn {key, _} -> {key, get(module, key)} end)
|> Enum.into(Map.new)
end
defp env_var(module, key) do
String.upcase "#{stringify module}_#{stringify key}"
end
defp module_name(module) do
module
|> to_string
|> String.replace_leading("Elixir.", "")
end
defp stringify(atom) do
atom
|> module_name
|> String.replace(".", "_")
|> String.replace_trailing("?", "")
end
defp parse_val(str, type) do
fun =
case type do
:atom -> &String.to_atom/1
:boolean -> &to_boolean/1
:float -> &String.to_float/1
:integer -> &String.to_integer/1
{:list, element_type} -> &to_list(&1, element_type)
{:set, element_type} -> &to_set(&1, element_type)
:string -> &(&1)
end
fun.(str)
end
defp to_boolean(str) do
String.downcase(str) == "true"
end
defp to_list(str, element_type) do
str |> String.split(",") |> Enum.map(&parse_val(&1, element_type))
end
defp to_set(str, element_type) do
str |> to_list(element_type) |> MapSet.new
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment