How do you create hex packages while still supporting in umbrella dependencies?

I have an umbrella project for my media libraries, and several projects depend on other project in the umbrella. Now I am trying to create hex.pm packages and having trouble because you cannot have in_umbrella: true dependencies marked for a hex package (which makes sense, as hex can not resolve all the dependencies itself.

However, I am unsure of how to resolve this situation without moving to a 100% hex dependency solution. Even though each dependency is a unique and independent system, there are some scenarios that are complex enough to make it much easier to debug and iterate on a (real or possible) dependency change by running it with a child application. I don’t want to have to create a new version, publish, then deps.get just for some iteration sessions.

I tried marking the hex dependency as only: [:prod] and the umbrella as only: [:dev] and that didn’t work, as hex.publish didn’t like multiple definitions for the same dependency.

Is there any easy solution to this besides temporarily commenting out the umbrella dependency and uncommenting it out while debugging it?

You don’t have to publish a dependency in hex. Mix supports :path option for local dependency. Create a standalone package (like you would if you are to publish one to hex), and utilize the :path option when specifying the deps.

This link might help: Mix.Tasks.Deps.

Be aware that this usually means extracting your dependency app from your umbrella though (I don’t know if it works with umbrella projects). I also don’t think umbrella projects could (or should) be published to hex, which seems to me like what you’re looking into doing. There’s this little discussion that talks about it.

Perhaps you can share a project structure or dependency graph for us to get a better view of your situation?

The actual structure is at https://github.com/KallDrexx/elixir-media-libs.

The problem is I want to publish the rtmp_session project to hex and the gen_rtmp_server package to hex. gen_rtmp_server depends on rtmp_session and thus both are required to have their dependencies be from hex and not specified via path or github location.

However, due to complexities I need to be able to modify code in the rtmp_session project and then from within the umbrella structure test the gen_rtmp_server code with the changes without re-publishing a temporary version of rtmp_session to Hex.

Both are valid individual packages for hex, but sometimes it is not easy to debug and test changes in the dependency without running a project that depends on it.

Ah now I see. Sorry I don’t think I can give any solution as I think

is the most straightforward approach, however mundane.

This is the perfect use case for :path dependencies. You can publish rtmp_session to hex and use it from there, then if you want to test some changes locally you temporarily change the dependency to fetch it from a local :path. If you need both to be :path dependencies you can declare the transitive dependency with an override to make sure it it wont be fetched from hex.

Yeah I was just hoping there was some way to run it locally without temporarily changing the dependencies, but I guess that’s out of the question (and I understand why, since it ensures the integrity of Hex.pm) I just wish it was easier to do with either environment types or some more automatic way.

Since mix.exs is code, you could read an env variable, e.g. RELEASE in there and depending on the value take the deps either from path/umbrella or from hex. This should make it less painful.

3 Likes

Oh duh, that’s brilliant. Thanks!