Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dependency definitions for multiple-major support #884

Closed
nbibler opened this issue Apr 15, 2014 · 10 comments
Closed

Dependency definitions for multiple-major support #884

nbibler opened this issue Apr 15, 2014 · 10 comments
Milestone

Comments

@nbibler
Copy link

nbibler commented Apr 15, 2014

So, looking into an activeadmin issue (activeadmin/activeadmin#3077), we noticed that:

>> Gem::Requirement.new("< 4", ">= 3.0.0") =~ Gem::Version.new("4.0.0.rc2")
=> true
>> Gem::Requirement.new("~> 3.0") =~ Gem::Version.new("4.0.0.rc2")
=> false

For gems like devise, where they support rails 3.x and 4.x, but don't yet work with the not-yet-released 5.x, what is the appropriate way to define a dependency which will exclude 5.0.0.beta/alpha/rc releases?

>> Gem::Requirement.new("<5", ">= 3.2.6") =~ Gem::Version.new("5.0.0.beta1")
=> true

I would have presumed the above requirement would have been sufficient to say anything greater or equal to 3.2.6 but less than all 5.x releases (including pre-releases).

At the very least this is unintuitive... more likely, though, this is a bug, I think.

@drbrain
Copy link
Member

drbrain commented Apr 21, 2014

How about:

>> Gem::Requirement.new("<5.a", ">= 3.2.6") =~ Gem::Version.new("5.0.0.beta1")
=> false

@drbrain drbrain added this to the 2.3 milestone Apr 21, 2014
@nbibler
Copy link
Author

nbibler commented Apr 21, 2014

I don't know ... at the end of the day, we're trying to train hundreds (thousands?) of gem developers how to properly identify what dependencies they have and what versions they work against. It's hard enough to get people to use and understand a pessimistic lock, let alone describe that "if you want to span multiple major versions you have to use a fictitious alpha release marker on the top end to get around an unintuitive feature of gem dependencies."

@drbrain
Copy link
Member

drbrain commented Apr 21, 2014

Changing the ways dependencies match involves breaking the expectations of all RubyGems users.

Note that if you leave it at "<5" then the beta version will only install with --prerelease.

@nbibler
Copy link
Author

nbibler commented Apr 21, 2014

Changing the ways dependencies match involves breaking the expectations of all RubyGems users.

Agreed. And certainly I don't want to make a change that isn't necessary.

Note that if you leave it at "<5" then the beta version will only install with --prerelease.

Hmm. That is not the behavior I was seeing when the dependency is a sub dependency if a gem. I was seeing the beta version being installed without a prerelease tag. That was what started this ticket.

I'll try to put together another example later tonight if this has been unclear.

@drbrain
Copy link
Member

drbrain commented Apr 21, 2014

There are some bugs around prerelease behavior with 2.2.2 that I haven't yet fixed so I welcome more reproductions.

@nbibler
Copy link
Author

nbibler commented Apr 21, 2014

$ rvm gemset create rubygems-884
ruby-2.1.1 - #gemset created /.../.rvm/gems/ruby-2.1.1@rubygems-884
ruby-2.1.1 - #generating rubygems-884 wrappers.........
$ gem --version
2.2.2
$ ruby --version
ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin13.0]
$ gem install activeadmin
ERROR:  While executing gem ... (Gem::DependencyResolutionError)
    conflicting dependencies arel (~> 2.0.2) and arel (~> 4.0.0)
  Activated arel-4.0.0 via:
    arel-4.0.0 (~> 4.0.0), activerecord-4.0.0.rc2 (= 4.0.0.rc2), rails-4.0.0.rc2 (< 4, >= 3.0.0), activeadmin-0.6.3 (= 0.6.3)
  instead of (~> 2.0.2) via:
    meta_search-1.0.0 (~> 1.0), activeadmin-0.6.3 (= 0.6.3)

Installing activeadmin directly results in dependency resolution errors, as shown above. That shouldn't happen and Bundler handles it correctly with an "empty" Gemfile:

source "https://rubygems.org"
gem "activeadmin", "0.6.2"
$ bundle
Fetching gem metadata from https://rubygems.org/............
Fetching additional metadata from https://rubygems.org/..
Resolving dependencies...
Installing rake (10.3.1)
Installing i18n (0.6.9)
Installing multi_json (1.9.2)
Installing activesupport (3.2.17)
Installing builder (3.0.4)
Installing activemodel (3.2.17)
Installing erubis (2.7.0)
Installing journey (1.0.4)
Installing rack (1.4.5)
Installing rack-cache (1.2)
Installing rack-test (0.6.2)
Installing hike (1.2.3)
Installing tilt (1.4.1)
Installing sprockets (2.2.2)
Installing actionpack (3.2.17)
Installing mime-types (1.25.1)
Installing polyglot (0.3.4)
Installing treetop (1.4.15)
Installing mail (2.5.4)
Installing actionmailer (3.2.17)
Installing arbre (1.0.1)
Installing sass (3.3.5)
Installing thor (0.19.1)
Installing bourbon (3.2.0)
Installing bcrypt (3.1.7)
Installing orm_adapter (0.5.0)
Installing rack-ssl (1.3.4)
Using json (1.8.1)
Installing rdoc (3.12.2)
Installing railties (3.2.17)
Installing thread_safe (0.3.3)
Installing warden (1.2.3)
Installing devise (3.2.4)
Installing formtastic (2.2.1)
Installing has_scope (0.5.1)
Installing responders (0.9.3)
Installing inherited_resources (1.4.0)
Installing jquery-rails (2.3.0)
Installing kaminari (0.15.1)
Installing arel (3.0.3)
Installing tzinfo (0.3.39)
Installing activerecord (3.2.17)
Installing polyamorous (0.5.0)
Installing meta_search (1.1.3)
Installing activeresource (3.2.17)
Using bundler (1.5.3)
Installing rails (3.2.17)
Installing activeadmin (0.6.3)
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.

Further, the Rubygem dependency error contains the lines:

  Activated arel-4.0.0 via:
    arel-4.0.0 (~> 4.0.0), activerecord-4.0.0.rc2 (= 4.0.0.rc2), rails-4.0.0.rc2 (< 4, >= 3.0.0), activeadmin-0.6.3 (= 0.6.3)

rails-4.0.0.rc2 (<4, >= 3.0.0) should not match, intuitively. It seems incredibly difficult to explain to someone that 4.0.0.rc2 can match a <4 requirement.

Now, certainly in the case of activeadmin, <4, >= 3.0.0 should be able to be replaced with a ~> 3.0 constraint (although that doesn't work when crossing multiple major versions). Except! The two are not functionally equivalent, despite all documentation and training material on the topics, because the ~> constraint will not match 4.0.0.rc2 while the <4 constraint will.

@nbibler
Copy link
Author

nbibler commented Apr 22, 2014

I don't think that this provides much useful new information, but here's the output of a gem install --verbose activeadmin:

$ gem install --verbose activeadmin
GET https://api.rubygems.org/latest_specs.4.8.gz
302 Moved Temporarily
GET https://s3.amazonaws.com/production.s3.rubygems.org/latest_specs.4.8.gz
304 Not Modified
HEAD https://api.rubygems.org/api/v1/dependencies
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=activeadmin
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=sass
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=rails
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=railties
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=actionmailer
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=activerecord
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=actionpack
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=activesupport
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=activemodel
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=meta_search
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=kaminari
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=jquery-rails
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=inherited_resources
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=formtastic
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=devise
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=bourbon
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=arbre
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=sprockets-rails
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=bundler
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=thor
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=rake
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=mail
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=activerecord-deprecated_finders
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=arel
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=erubis
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=rack-test
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=rack
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=builder
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=thread_safe
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=minitest
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=tzinfo
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=multi_json
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=i18n
200 OK
ERROR:  While executing gem ... (Gem::DependencyResolutionError)
    conflicting dependencies arel (~> 2.0.2) and arel (~> 4.0.0)
  Activated arel-4.0.0 via:
    arel-4.0.0 (~> 4.0.0), activerecord-4.0.0.rc2 (= 4.0.0.rc2), rails-4.0.0.rc2 (< 4, >= 3.0.0), activeadmin-0.6.3 (= 0.6.3)
  instead of (~> 2.0.2) via:
    meta_search-1.0.0 (~> 1.0), activeadmin-0.6.3 (= 0.6.3)

@nbibler
Copy link
Author

nbibler commented Apr 22, 2014

If there's some way for me to gather more useful debugging information or something, please let me know!

drbrain added a commit that referenced this issue May 29, 2014
@drbrain
Copy link
Member

drbrain commented May 29, 2014

I think I fixed this properly in #853. Prerelease versions were chosen due to confusing API similarities.

@drbrain drbrain closed this as completed May 29, 2014
@nbibler
Copy link
Author

nbibler commented May 29, 2014

Thanks! I'll take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants