rails/activeresource

ActiveModel and ActiveSupport version 6.0.0 cause gem dep clashes

vibro opened this issue · 6 comments

vibro commented

We have a number of internal gems that rely on activeresource and activesupport. We add this dependency in the gem's gemspec like so:

  s.add_runtime_dependency 'activeresource', '~> 5.0'

However, activeresource allows activemodel and activesupport versions like so:

  s.add_dependency("activesupport", ">= 5.0", "< 7")
  s.add_dependency("activemodel", ">= 5.0", "< 7")

This means that on a new bundle install, it can pick up version 6.0.0.

We end up with situations like this:

/usr/local/rvm/rubies/ruby-2.6.1/lib/ruby/2.6.0/rubygems/resolver.rb:191:in `rescue in resolve': conflicting dependencies activesupport (~> 5) and activesupport (= 6.0.0) (Gem::DependencyResolutionError)
  Activated activesupport-6.0.0
  which does not match conflicting dependency (~> 5)

  Conflicting dependency chains:
    activemodel (> 5.x, >= 5.0, < 7), 6.0.0 activated, depends on
    activesupport (= 6.0.0), 6.0.0 activated

  versus:
    readacted1 (>= 0.0.38), 0.0.38 activated, depends on
    readacted2 (>= 0.4.14), 0.4.15 activated, depends on
    readacted3 (~> 0.4.8), 0.4.8 activated, depends on
    activesupport (~> 5)

In addition, including activesupport 6.0.0 in a project that required activeresource 5.x broke several unit tests.

We've mitigated this by going through and adding an activesupport and activemodel 5 dependency in our gems, but I don't think that the 5 version of activeresource should be able to pull in version 6 of activerecord and activemodel.

activeresource supports activesupport 6.0.0. By your error it seems what doesn't allow you to install actuvesupport 6 is this line here activesupport (~> 5), probably in your readacted3 gem. ~> 5 means >= 5.0.0, < 6

activeresource 5 should be able to pull version 6 of activemodel and activesupport, that is by design, activeresource releases are not aligned with the rails releases since it was extracted from rails. But it also allow the version 5 of those gems. It doesn't force you to upgrade those dependencies.

Is the project where you get this error using Bundler?

vibro commented

The error is during an executable run from a gem that we've built ourselves. What actually installed activeresource 6 was bundler on the same machine (not in a gemset).

But when using Bundler and having it pull in activesupport and activemodel 6, we ran into test errors in a project using activeresource 5.

I guess I don't really understand this "activated" error in general. Does ruby just activate the first version a gem it finds even if it's not compatible with other dependencies in the project? Activesupport 5.x is available in the gem list on the machine.

Does ruby just activate the first version a gem it finds even if it's not compatible with other dependencies in the project?

Yes. This is exactly the problem Bundler was made to solve. Rubygems tries to activate the newest version always, and if it is not compatible it will show that message. The way to solve is to use bundler in your executables or uninstall the incompatible gems.

I'm closing since it is not an issue in activeresource, but I'm glad to answer questions.

vibro commented

Thanks for the response. I do have a few questions!

We package gem, publish them to an internal gem repository, and then install them on our systems using gem install. When developing these gems, we use bundler, but after pushing to the repository that's the end of that. How would we use bundler in a situation where we want to install these gems to provide command line tools outside of a ruby project?

That is a hard problem to solve. The short answer is that there is no way to ensure the dependencies that will be activated by your command line tool are the right one.

The long answer is to vendor the gems in your command line tool and load from them. One example of that is bundler itself. It has a few dependencies, but to avoid this already know problem it vendors them inside the bundler gem.