-
-
Save torrick/dd87943d46f58448156c21fee3c26dd1 to your computer and use it in GitHub Desktop.
Elixir: override Mix config with environment variables
This file contains 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