`Code.require_file/2` not working when running mix release
Closed this issue · 1 comments
Steps to reproduce
Implement a script (myapp/config/settings.exs) that loads settings, like so:
defmodule Settings do
@fields [:foo, :bar]
@enforce_keys @fields
defstruct @fields
def new do
struct(__MODULE__, %{foo: "load stuff", bar: "from somewhere"})
end
end
Call settings script from myapp/config/config.exs like so:
load_cfg = fn ->
with [{settings, _}] <- Code.require_file("settings.exs", "./config") do
settings.new
else
_noop -> IO.inspect "not working!?"
end
end
cfg = load_cfg.()
config :myapp, MyApp.MyModule,
foo: cfg.foo,
bar: cfg.bar
Verbose Logs
Generated myapp app
==> Assembling release..
==> Building release myapp:0.0.1 using environment prod
"not working!?"
==> Release failed: argument error
:erlang.apply("not working!?", :foo, [])
(stdlib) erl_eval.erl:680: :erl_eval.do_apply/6
(stdlib) erl_eval.erl:888: :erl_eval.expr_list/6
(stdlib) erl_eval.erl:240: :erl_eval.expr/5
(stdlib) erl_eval.erl:232: :erl_eval.expr/5
(stdlib) erl_eval.erl:233: :erl_eval.expr/5
(stdlib) erl_eval.erl:888: :erl_eval.expr_list/6
(stdlib) erl_eval.erl:240: :erl_eval.expr/5
(stdlib) erl_eval.erl:232: :erl_eval.expr/5
(stdlib) erl_eval.erl:888: :erl_eval.expr_list/6
(stdlib) erl_eval.erl:411: :erl_eval.expr/5
(stdlib) erl_eval.erl:126: :erl_eval.exprs/5
(elixir) src/elixir.erl:258: :elixir.eval_forms/4
(elixir) lib/code.ex:232: Code.eval_string/3
(mix) lib/mix/config.ex:220: Mix.Config.eval!/2
(distillery) lib/mix/lib/releases/config/providers/elixir.ex:80: Mix.Releases.Config.Providers.Elixir.eval!/2
(distillery) lib/mix/lib/releases/assembler.ex:663: Mix.Releases.Assembler.generate_base_config/2
(distillery) lib/mix/lib/releases/assembler.ex:619: Mix.Releases.Assembler.generate_sys_config/1
(distillery) lib/mix/lib/releases/assembler.ex:262: Mix.Releases.Assembler.write_release_scripts/1
(distillery) lib/mix/lib/releases/assembler.ex:50: Mix.Releases.Assembler.assemble/1
Description of issue
- What are the expected results?
The cfg
variable is a Settings struct with settings.
- What version of Distillery?
distillery-2.0.12
- What OS, Erlang/Elixir versions are you seeing this issue on?
Ubuntu 18.04.2 LTS
Erlang/OTP 21 [erts-10.2.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]
Elixir 1.8.1 (compiled with Erlang/OTP 20)
- If possible, also provide your
rel/config.exs
, as it is often
my first troubleshooting question, and you'll save us both time :)
probably not interesting, standard stuff.
- Is there documentation that says one thing, but Distillery does
another? If so, please link the doc here so it can be updated if
it's a documentation issue, or so that the fix can be based around
what's documented.
didn't find anything in particular.
- If this is a runtime configuration issue, please also provide your config file
(with any sensitive information stripped of course). This is almost
always necessary to understand why some configuration may not be working.
it's definitely a runtime configuration issue, please see the steps to reproduce.
when running my app with mix phx.server
and so on, there's no problem.
the problem happens right after:
==> Building release myapp:0.0.1 using environment prod
It turns out Code.require_file/2
works just fine when running mix release.
The issue is that the Settings
module already exists in memory when Distillery loads ./config/config.exs
.
So the solution is to check whether module Settings already exists:
load_cfg = fn ->
with false <- Code.ensure_compiled?(Settings) do
with [{settings, _}] <- Code.require_file("settings.exs", "./config") do
settings.new
else
_noop -> :noop
end
else
_available -> Settings.new
end
end
cfg = load_cfg.()