Skip to content

Instantly share code, notes, and snippets.

@luk3thomas
Last active August 7, 2018 21:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luk3thomas/3fe75fda645c3aa71528e42e54fa7d43 to your computer and use it in GitHub Desktop.
Save luk3thomas/3fe75fda645c3aa71528e42e54fa7d43 to your computer and use it in GitHub Desktop.
A config wrapper for Elixir
defmodule Config do
@moduledoc """
A module for fetching system environment variables at runtime
"""
@doc """
Retrieve an environment variable from the application runtime.
"""
def get(app, key) do
app
|> Application.get_env(key)
|> get
end
def get(list) when is_list(list), do: Enum.map(list, &get/1)
def get({key, {:system, value, fallback}}) do
res = get({key, {:system, value}})
{_, v} = res
if v do
res
else
{key, fallback}
end
end
def get({key, {:system, value}}), do: {key, get_env(value)}
def get({:system, value, fallback}), do: get({:system, value}) || fallback
def get({:system, value}), do: get_env(value)
def get(value), do: value
defp get_env(name) do
name
|> System.get_env
|> maybe_parse
end
defp maybe_parse("true"), do: true
defp maybe_parse("false"), do: false
defp maybe_parse(v) when is_bitstring(v) do
try do
String.to_integer(v)
rescue
_ -> v
end
end
defp maybe_parse(v), do: v
end
defmodule ConfigTest do
use ExUnit.Case
describe "single env variable" do
test "gets an env variable" do
System.put_env("FOO", "a")
assert "a" == Config.get({:system, "FOO"})
end
test "uses fallback" do
assert "a" == Config.get({:system, "BLAH_BLAH", "a"})
end
test "converts to integer" do
System.put_env("FOO", "1")
assert 1 == Config.get({:system, "FOO"})
end
test "converts to boolean" do
System.put_env("FOO", "false")
assert false == Config.get({:system, "FOO"})
System.put_env("FOO", "true")
assert true == Config.get({:system, "FOO"})
end
test "does not convert integer look alikes" do
System.put_env("FOO", "0.0.0.0")
assert "0.0.0.0" == Config.get({:system, "FOO"})
end
end
describe "keyd env variable" do
test "single" do
System.put_env("FOO", "a")
assert {:name, "a"} == Config.get({:name, {:system, "FOO"}})
end
test "uses fallback" do
assert {:name, "a"} == Config.get({:name, {:system, "BLAH_BLAH", "a"}})
end
test "list" do
Application.put_env(:sstell, Repo, [
adapter: Ecto.Adapters.MySQL,
database: {:system, "TEST_DATABASE_NAME"},
username: {:system, "TEST_DATABASE_USER"},
])
System.put_env("TEST_DATABASE_NAME", "some_name")
result = Config.get(:sstell, Repo)
assert [ adapter: Ecto.Adapters.MySQL,
database: "some_name",
username: nil
] == result
end
end
describe "list" do
test "gets a list" do
System.put_env("FOO", "a")
result = Config.get([
{:port, 4001},
{:name, {:system, "FOO"}},
])
assert result == [{:port, 4001}, {:name, "a"}]
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment