Update, a slight modification, without using Mix is marginally better:
defp available_modules_with_behaviour(behaviour) do
# compiled from `Mix.Task.run("loadpaths", [])`
build_path = Path.expand("_build/prod")
app_path = Path.join([build_path, "lib", Atom.to_string(:external_data_sync)])
Path.join(app_path, "ebin")
# Fetch all .beam files
Path.wildcard(Path.join([Path.expand("_build/prod"), "**/ebin/**/*.beam"]))
# the rest is the same
...
end
This works, but in reality it’s only because lib is right where the code expects it. So it looks like the related lib module isn’t included in the escript.
I tried several ways to include all code from lib in that escript related module, no luck. Not even :ok = Application.ensure_started(:app) seems to be working. Even just aliasing those modules doesn’t work, they need to be explicitly used. This seems to work after all:
@scenarios [
SyncData1
SyncData2
SyncData3
]
# and before requesting modules that implement `Scenario` behaviour
Enum.each(@scenarios, &Code.ensure_loaded?(&1))
# now finding those modules works
all_scenarios = available_modules_with_behaviour(Scenario)
So I guess this is all about how to actually include the main app into escript. If it’s even possible…


















