Thank you so much for your thoughts, José! It gives me a lot more confidence knowing you’ve looked the idea over and that no hard blockers immediately came to mind. ![]()
I think skipping protocols makes sense. (It also lets me strip out some code that’s transforming debug_info.)
I like the idea of the user specifying which modules to use and walking the abstract code to find dependencies. I’ll likely work on that next.
I do have one more question that you’d probably have some insight on, José: What’s the right way to handle configuration?
Let’s say you have user project proj, which depends on lib_a and lib_b, both of which depend on lib_elixir configured for different versions and modules.
Right now, lib_elixir specifies a Mix compiler (Mix.compilers() ++ [:lib_elixir]) so that it runs after it compiles its own code, but before anything depending on it compiles, and then it uses the private Mix.ProjectStack to get configuration info. This probably isn’t a good idea.
Instead, it could require that code depending on lib_elixir specify the compiler before Mix.compilers() so that it runs in the context of that project (and therefore doesn’t have to use the project stack):
def project do
[
app: :lib_a,
compilers: [:lib_elixir] ++ Mix.compilers(),
lib_elixir: [{LibA.LibElixir, "v1.17.2", [Code]],
...
]
end
Any thoughts?


















