alexocode/knigge

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. 🙂