Umbrella applications / config.ex recommandation

Hello,

it’s been a while since my last post and i’m happy to see the elixir community growing :slight_smile:

I encounter a known issue and I wonder what is the most appropriate way to tackle it:

I’ve set up my project as a umbrella. It gathers a common library and two application relying on the library.

The common library defines a behaviour implemented by two modules. The common library is in charge of using one of the implementation. One one hand, i want the first application to use one module and on the other hand, i want the second to use the other one.

I’ve used the standard (at least for me) method of defining in the config.ex files of both applications, the module that the common lib should run. The common lib read the configuration thanks to Application.get_env .

Here comes the first problem, as I’m in a umbrella project (defined basically), all config files are read and one of the configuration is always overridden (not that bad will you tell, at least you still have one application working … ) .

I though to use manual import to try to be a bit more selective in the way files are loaded, Second problem, mix detects that I try to import twice the same file.

The final idea is to remove the config from the common library and duplicate everything in application config but… kind of … meahhh :confused:

Other solution, instead of using the get_env, i could pas the module as parameter. As it’s not supposed to be a runtime behaviour, I’m still not convinced by the idea.

So is there a clean and proper way of acheiving this ?

Bonus question: José posted some hours ago about elixir 1.9 changes:

Is there a way to be 1.9 compliant in one shot ?

Thanks a lot !!

Fred

I’m assuming you want to run both applications and the library together. Then the library needs some way to differenciate the two applications (and in turn which impl. to use). The simple and strongy suggested way is function parameters. The more complex one is something like Ecto.Repo, where the actual functionality is stored in a module of the application using ecto, a.k.a. MyApp.Repo. The latter could work with macros or processes to store the data.

To be 1.9 “compliant” (old code is still compliant, it just have additional “cases” for handling the sub apps) you can do:

for env in config prod dev test; do; cat apps/*/config/$env.exs >> config/$env.exs; done

And then you need to remove import_config that imports apps/*/config/config.exs from the config/config.exs and that is it. I used that approach in my application even before it was used as “default”.


Next thing is to encourage people to use :env configuration in application configuration for values that do not change between environments, for example :ecto_repos.

1 Like

Ok, so let’s go for the refacto :slight_smile:

Thanks for the answers gentlemen !

Fred