-
-
Save arathunku/632c0ca23bc1bfeba621d5a1ded54bcd to your computer and use it in GitHub Desktop.
Elixir: override Mix config with environment variables
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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