Why can I not publish a hex package when a dependency uses a manager?

My library is dependent on the Erlang ranch library in order to function. In order for mix deps.compile to built ranch I have to define my dependency as: {:ranch, "~> 1.2.1", manager: :rebar},.

Unfortunately, hex.pm tells me:

** (Mix) Can’t build package when :manager is set for dependency ranch, remove manager: ...

Since I cannot build the ranch dependency without that manager flag I seem to be stuck.

Anyone have any ideas on how to get around this?

2 Likes

:manager sets the build tool that will be used to build the dependency. The idea is that all packages in hex should already have the correct manager so the registry does not include this information for dependencies of a package, you can only set it for the package itself. ranch[1] declares make as its build tool, can you elaborate on why make doesn’t work and why you need to set the manager?

[1] https://hex.pm/packages/ranch

1 Like

For whatever reason ranch was not designed to compile on windows without cygwin/msys2, so using make to compile it causes an error because uname is not available.

Rebar gets around this for whatever reason and everything works flawlessly, but now that Hex.pm is rejecting it I am now stuck.

Edit: And just to clarify, it’s impossible for me to compile ranch even in msys2 without me completely re-adjusting some things since the erlang make file does not like directories with spaces in it.

1 Like

Sorry about this issue with ranch, it’s my bad, I published it without explicitly annotating that it also works with rebar. Future releases of rebar will have this fixed.

Until a new version of ranch is released you can use the same workaround that @michalmuskala mentioned in the other thread How do you create hex packages while still supporting in umbrella dependencies? when publishing the package.

1 Like

Do you mean future releases of ranch will have this fixed? Also how does that annotation work out of curiosity, does it try make and if that fails tries rebar?

Not sure I totally follow, sorry. The solution in that thread says to use code statements to switch which dependency is being used based on the environment or some other variable. That won’t work for me because there’s no way for me to specify ranch as a dependency at all in a way that mix hex.publish accepts on my windows machine.

The only possibility I see is to have it so when I’m performing a hex.publish to use the ranch statement without the manager keyword, but then set up a Linux VM somewhere and only use that VM for hex.publish calls.

Am I missing something?

You can specify the build tools manually when publishing a hex package. If Mix sees a dependency that can build with both rebar and make it will always choose rebar out of the two because it generally has better compatibility, as you have noticed :).

You can do something like this:

def project do
  [deps: deps(Mix.env)]
end

defp deps(:publish), do: [{:ranch, "~> 1.0"}]
defp deps(_), do: [{:ranch, "~> 1.0", manager: :rebar}]

When you publish your package you do this: MIX_ENV=publish mix hex.publish.

Makes sense, thanks!

I think I’ll still have to use a Linux VM for publishing, since I can’t deps.compile without the manager keyword (thus hex.publish fails) but it seems like for now that’s what’s going to be required.

You don’t have to compile to publish a package. It should work on your Windows machine.

Woops sorry for being dumb. I think the reason it didn’t work yesterday was I did a mix hex.publish which failed because I needed to do a deps.get. I did that and probably just assumed I needed to do a deps.compile in order to publish and never tried to just publish after the get.

All is good now, thanks a ton! :slight_smile:

I think something changed recently and I am no longer able to publish my packages anymore.

I have the following dependencies specified in hex.pm:

  defp get_umbrella_dependencies(:umbrella) do
    [
      {:rtmp, in_umbrella: true},
    ]
  end

  defp get_umbrella_dependencies(_) do
    [
      {:rtmp, "~> 0.1.0", hex: :eml_rtmp},
    ]
  end

  defp get_ranch_dependency(:publish), do: {:ranch, "~> 1.2.1"}
  defp get_ranch_dependency(_), do: {:ranch, "~> 1.2.1", manager: :rebar}

If I then try to create a package for hex I now get the following error:

D:\code\My Projects\elixir-media-libs\apps\gen_rtmp_server
λ  mix compile
Compiling 5 files (.ex)
Generated gen_rtmp_server app
D:\code\My Projects\elixir-media-libs\apps\gen_rtmp_server
λ  mix docs
Docs successfully generated.
View them at "doc/index.html".
D:\code\My Projects\elixir-media-libs\apps\gen_rtmp_server
λ  $env:MIX_ENV="publish"
D:\code\My Projects\elixir-media-libs\apps\gen_rtmp_server
λ  mix hex.publish
Passphrase:
Publishing eml_gen_rtmp_server 0.1.1
  Dependencies:
    eml_rtmp ~> 0.1.0 (app: rtmp)
    ranch ~> 1.2.1
    uuid ~> 1.1
  Files:
    lib/gen_rtmp_server.ex
    lib/gen_rtmp_server/audio_video_data.ex
    lib/gen_rtmp_server/meta_data.ex
    lib/gen_rtmp_server/protocol.ex
    lib/gen_rtmp_server/rtmp_options.ex
    mix.exs
    README.md
  App: gen_rtmp_server
  Name: eml_gen_rtmp_server
  Description: Behaviour to make it easy to create custom RTMP servers
  Version: 0.1.1
  Build tools: mix
  Licenses: MIT
  Maintainers: Matthew Shapiro
  Links:
    GitHub: https://github.com/KallDrexx/elixir-media-libs/tree/master/apps/gen_rtmp_server
  Elixir: ~> 1.4
Before publishing, please read the Code of Conduct: https://hex.pm/policies/codeofconduct
Proceed? [Yn] Y
Building docs...
erlang.mk:73: *** Unable to detect platform. Please open a ticket with the output of uname -a..  Stop.
** (Mix) Could not compile dependency :ranch, "make" command failed. You can recompile this dependency with "mix deps.compile ranch", update it with "mix deps.update ranch" or clean it with "mix deps.clean ranch"
D:\code\My Projects\elixir-media-libs\apps\gen_rtmp_server
λ  $env:MIX_ENV="dev"
D:\code\My Projects\elixir-media-libs\apps\gen_rtmp_server
λ  mix hex.publish
** (Mix) Can't build package when :manager is set for dependency ranch, remove `manager: ...`

Did something change or am I doing something wrong?

@KallDrexx to build documentation, we need to compile the source, so you are running into issues. To fix this you can run MIX_ENV=publish mix hex.publish package to publish only the package without building the docs. And then if you need to build the docs, you can do mix hex.publish docs.

1 Like

Ok that half works.

I was able to publish the package but I can’t publish documentation, in publish environment or dev environment:

D:\code\My Projects\elixir-media-libs\apps\gen_rtmp_server
λ  $env:MIX_ENV="dev"
D:\code\My Projects\elixir-media-libs\apps\gen_rtmp_server
λ  mix hex.publish docs
** (Mix) Can't build package when :manager is set for dependency ranch, remove `manager: ...`
D:\code\My Projects\elixir-media-libs\apps\gen_rtmp_server
λ  $env:MIX_ENV="publish"
D:\code\My Projects\elixir-media-libs\apps\gen_rtmp_server
λ  mix hex.publish docs
Passphrase:
erlang.mk:73: *** Unable to detect platform. Please open a ticket with the output of uname -a..  Stop.
** (Mix) Could not compile dependency :ranch, "make" command failed. You can recompile this dependency with "mix deps.compile ranch", update it with "mix deps.update ranch" or clean it with "mix deps.clean ranch"

You do not need to set the MIX_ENV=“publish” for publishing the docs because in this case you do need to compile your deps.

Right but the console input I pasted tried it as both publish and dev environment. No matter the environment I cannot publish documentation.

Check out the earlier posts in the thread for a refresher, but the crux of the issue is that on windows it is required that the ranch dependency is specified with rebar3 set as the explicit manager. However, hex does not allow you to do any hex operations (including doc only publish) with any dependency with an explicit manager. Therefore I am in a catch 22 where I cannot compile without a specified manager, but I need to compile in order to publish hex docs.

Oh, I see. We are also checking the manager when publishing the documentation. That was not supposed to be required. I am sorry but for now I cannot offer any alternative. Or we need to wait for hex.pm to remove the manager check when publishing the docs or we need to wait for a proper ranch version to be published.

That’s fine, it’s not a super big deal as I doubt anyone is going to use this package anytime soon.

I just wanted to either raise a bug or be pointed out that I"m doing something wrong. Thanks for the responses!

2 Likes

Have you tried to alias the doc task in a way that it does nothing when run in publish env while creating docs as usual when running in any other. But you have to ensure up to date documentation by yourself then by running mix doc in dev and publishing afterwards.

I can create docs manually no problem with ‘mix docs’. However, I cannot publish that documentation because mix hex.publish tries to recreate the docs, which can’t happen because I either can’t compile or I can’t use a dependency with an explicit manager. So the only operation I can do with hex successfully is mix hex.publish package to publish only the package.

As I said… Create an alias for the doc task that does nothing when in publish.

Oh not a shell alias but an actual alias in mix, so that when I call mix hex.publish and hex calls the docs task, it doesn’t try to recompile docs and just use existing docs on the publish.