Skip to content

Commit ea8f62b

Browse files
committed
Support ecto config
Ecto has mix tasks that will attempt to start the repo. In some of these scenarios, the application will not yet have been started. Most notable are ecto.create and ecto.migrate. These are aliased for you in a brand new phoenix project under `mix test`. With this new `Provider.ecto_config/3` function, we ensure that the given config process is running, and we will also shut it down afterwards to ensure that when your application starts, we do not have an issue with the process already being started.
1 parent e1da858 commit ea8f62b

File tree

4 files changed

+69
-11
lines changed

4 files changed

+69
-11
lines changed

README.md

+12-10
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,18 @@ defmodule MySystem.Repo do
9797
adapter: Ecto.Adapters.Postgres
9898

9999
@impl Ecto.Repo
100-
def init(_type, config) do
101-
{:ok,
102-
Keyword.merge(
103-
config,
104-
hostname: MySystem.Config.db_host(),
105-
database_name: MySystem.Config.db_name(),
106-
pool_size: MySystem.Config.db_pool_size(),
107-
# ...
108-
)
109-
}
100+
def init(context, config) do
101+
Provider.ecto_config(MySystem.Config, context, fn ->
102+
{:ok,
103+
Keyword.merge(
104+
config,
105+
hostname: MySystem.Config.db_host(),
106+
database_name: MySystem.Config.db_name(),
107+
pool_size: MySystem.Config.db_pool_size(),
108+
# ...
109+
)
110+
}
111+
end)
110112
end
111113
end
112114
```

lib/provider.ex

+14
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ defmodule Provider do
102102
@type type :: :string | :integer | :float | :boolean
103103
@type value :: String.t() | number | boolean | nil
104104
@type data :: %{param_name => value}
105+
@type ecto_context :: :supervisor | :runtime
105106

106107
# ------------------------------------------------------------------------
107108
# API
@@ -129,6 +130,19 @@ defmodule Provider do
129130
end
130131
end
131132

133+
@spec ecto_config(module(), ecto_context(), (-> {:ok, Keyword.t()})) :: {:ok, Keyword.t()}
134+
def ecto_config(mod, context, fun) do
135+
mod.start_link(nil)
136+
137+
ret = fun.()
138+
139+
if context == :runtime do
140+
GenServer.stop(mod)
141+
end
142+
143+
ret
144+
end
145+
132146
# ------------------------------------------------------------------------
133147
# Private
134148
# ------------------------------------------------------------------------

mix.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule Provider.MixProject do
22
use Mix.Project
33

4-
@version "0.2.0"
4+
@version "0.2.1"
55

66
def project do
77
[

test/provider_test.exs

+42
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,48 @@ defmodule ProviderTest do
3737
end
3838
end
3939

40+
describe "ecto_config" do
41+
test "starts and stops the server when the context is :runtime" do
42+
System.put_env("OPT_1", "some data")
43+
System.put_env("OPT_2", "42")
44+
System.put_env("OPT_6", "false")
45+
System.put_env("OPT_7", "3.14")
46+
47+
pid = Process.whereis(TestModule)
48+
assert is_nil(pid)
49+
50+
config =
51+
Provider.ecto_config(TestModule, :runtime, fn ->
52+
{:ok, [hostname: TestModule.opt_1()]}
53+
end)
54+
55+
assert {:ok, [hostname: "some data"]} = config
56+
57+
pid = Process.whereis(TestModule)
58+
assert is_nil(pid)
59+
end
60+
61+
test "starts but not stops the server when the context is :supervisor" do
62+
System.put_env("OPT_1", "some data")
63+
System.put_env("OPT_2", "42")
64+
System.put_env("OPT_6", "false")
65+
System.put_env("OPT_7", "3.14")
66+
67+
pid = Process.whereis(TestModule)
68+
assert is_nil(pid)
69+
70+
config =
71+
Provider.ecto_config(TestModule, :supervisor, fn ->
72+
{:ok, [hostname: TestModule.opt_1()]}
73+
end)
74+
75+
assert {:ok, [hostname: "some data"]} = config
76+
77+
pid = Process.whereis(TestModule)
78+
assert not is_nil(pid)
79+
end
80+
end
81+
4082
describe "generated module" do
4183
setup do
4284
Enum.each(1..7, &System.delete_env("OPT_#{&1}"))

0 commit comments

Comments
 (0)