diff --git a/lib/provider.ex b/lib/provider.ex index 400d72a..3584658 100644 --- a/lib/provider.ex +++ b/lib/provider.ex @@ -101,54 +101,46 @@ defmodule Toml.Provider do end end - if has_config_api? do - defp persist(config, keyword) when is_list(keyword) do - config = Config.Reader.merge(config, keyword) - Application.put_all_env(config, persistent: true) - config - end - else - defp persist(config, keyword) when is_list(keyword) do - # For each app - for {app, app_config} <- keyword do - # Get base config - base = Application.get_all_env(app) - base = deep_merge(base, Keyword.get(config, app, [])) - # Merge this app's TOML config over the base config - merged = deep_merge(base, app_config) - # Persist key/value pairs for this app - for {k, v} <- merged do - Application.put_env(app, k, v, persistent: true) - end - - # Return merged config - {app, merged} + defp persist(config, keyword) when is_list(keyword) do + # For each app + for {app, app_config} <- keyword do + # Get base config + base = Application.get_all_env(app) + base = deep_merge(base, Keyword.get(config, app, [])) + # Merge this app's TOML config over the base config + merged = deep_merge(base, app_config) + # Persist key/value pairs for this app + for {k, v} <- merged do + Application.put_env(app, k, v, persistent: true) end - end - defp deep_merge(a, b) when is_list(a) and is_list(b) do - if Keyword.keyword?(a) and Keyword.keyword?(b) do - Keyword.merge(a, b, &deep_merge/3) - else - b - end + # Return merged config + {app, merged} end + end - defp deep_merge(_k, a, b) when is_list(a) and is_list(b) do - if Keyword.keyword?(a) and Keyword.keyword?(b) do - Keyword.merge(a, b, &deep_merge/3) - else - b - end + defp deep_merge(a, b) when is_list(a) and is_list(b) do + if Keyword.keyword?(a) and Keyword.keyword?(b) do + Keyword.merge(a, b, &deep_merge/3) + else + b end + end - defp deep_merge(_k, a, b) when is_map(a) and is_map(b) do - Map.merge(a, b, &deep_merge/3) + defp deep_merge(_k, a, b) when is_list(a) and is_list(b) do + if Keyword.keyword?(a) and Keyword.keyword?(b) do + Keyword.merge(a, b, &deep_merge/3) + else + b end + end - defp deep_merge(_k, _a, b), do: b + defp deep_merge(_k, a, b) when is_map(a) and is_map(b) do + Map.merge(a, b, &deep_merge/3) end + defp deep_merge(_k, _a, b), do: b + # At the top level, convert the map to a keyword list of keyword lists # Keys with no children (i.e. keys which are not tables) are dropped defp to_keyword(map) when is_map(map) do diff --git a/test/provider_test.exs b/test/provider_test.exs index a0cf0c2..4367c5e 100644 --- a/test/provider_test.exs +++ b/test/provider_test.exs @@ -1,3 +1,6 @@ +defmodule Distillery.Releases.Config.Provider do +end + defmodule Toml.Test.ProviderTest do use ExUnit.Case @@ -36,6 +39,15 @@ defmodule Toml.Test.ProviderTest do assert {:ok, "success!"} = Toml.Provider.get([:toml, :provider_test]) end + test "deep merges to ensure existing config is preserved" do + file = Path.join([__DIR__, "fixtures", "provider.toml"]) + put_all_env(toml: [nested: [deep: "success!"]]) + + Toml.Provider.init(path: file, keys: :atoms!) + + assert [deep: "success!", foo: "bar"] = Application.get_env(:toml, :nested) + end + test "exit is triggered if path provided has invalid expansion" do assert catch_exit(Toml.Provider.load([], path: "path/to/${HOME")) == :unclosed_var_expansion end