Compilation fails because it checks if the implementation exists
alexcastano opened this issue · 2 comments
In the following example:
defmodule MyGreatcheckBehaviour do
use Knigge, otp_app: :my_application
@callback my_great_callback(my_argument :: any()) :: any()
end
defmodule MyGreatImplementation do
@behaviour MyGreatBehaviour
@impl true
def my_great_callback(_), do: true
end
# config.exs
config :my_application, MyGreatBehaviour, MyGreatImplementation
It doesn't work in dev
or prod
because MyGreatImplementation
depends on MyGreatBehaviour
on compilation time, and Knigge
tries to Code.load?(MyGreatImplementation)
when compiling MyGreatBehaviour
.
Now, I'm using the check_if_exists?: false
option, however, it is not explained in the README and this example doesn't work without it. Another solution would be to use a third module for the behaviour, but if the main purpose is to avoid boilerplate code I don't think it is a great idea.
I don't know if it would be possible to try to check if the implementation exists in the @after_compile
hook using the Code.ensure_compile(implementation_module)
Thank you!
Hey @alexcastano thanks for the report.
I've recently became aware of this issue and I invested some time to track down what's happening. To make a long story short, due to the implementing module being defined in the config - and not explicitly in the use
- the compiler sometimes hasn't even opened the implementing module which leads the existence check to fail.
Sadly, there seems to be no easy fix for that.
My plan is to move the existence check into a separate mix task which then can be run on the CI when building the release to ensure all modules exist. Since a mix task runs after compilation this would eliminate said problem.
Until I've had some time to work on that using check_if_exists?: false
is your only option. Sorry for the hassle.
Please try version 1.2.0 (which I published today).
It removes the compile-time check and instead introduces a mix knigge.verify
task. Checkout this "article" for details. 🙂