TestGemRequrement cases for spermy pre-release matching #349

Closed
wants to merge 2 commits into
from

Projects

None yet

6 participants

Contributor
dekellum commented Jul 2, 2012

I was recently bitten and surprised by the matching behavior of spermy/pessimetic requirements that contain pre-release alpha segments. Issue #198 identifies a subcase of this problem. Here is a more concerning example.

If I specify a requirement of ~> 1.4.beta, what I believe I'm saying is that I will take anything from 1.4.beta.0, to 1.4.rc.1 to release versions 1.4.0, 1.4.1, etc. This works, however I'm surprised to find that ~> 1.4.beta also matches 1.5. By comparison, ~> 1.4.0 drops both the earlier pre-releases and also avoids matching 1.5.

It appears the current logic is that a ~> 1.4.beta is effectively equivalent to ~> 1.4 which is both surprising and limits my ability to constrain the dependency in the way I would like.

Here is a simple demonstration, where I'd expect the matching version would be 1.1.3:

% gem list bundler

*** LOCAL GEMS ***
bundler (1.2.0.pre.1, 1.1.3, 1.1.0, 1.1.rc.8)

% ruby -rubygems -e "gem 'bundler', '~> 1.1.rc'; require 'bundler'; puts Bundler::VERSION"
1.2.0.pre.1

The current commit provides two test cases which show the behavior that I would have expected, but fail as shown below. If you could let me know if these tests cases are valid, then I could attempt to fix the Requirement handling to make this pull request mergeable.

  1) Failure:
test_satisfied_by_boxed_pre_plus(TestGemRequirement) [./test/rubygems/test_gem_requirement.rb:253]:
~> 1.4.beta.0 is not satisfied by 1.4

  2) Failure:
test_satisfied_by_boxed_pre(TestGemRequirement) [./test/rubygems/test_gem_requirement.rb:242]:
~> 1.4.beta is not satisfied by 1.5.alpha.0

This pull request fails (merged 1ee3b2a into 1e97cce).

Member

@dekellum as reported by travis, this fails:
http://travis-ci.org/#!/rubygems/rubygems/builds/1760647

Please review the changes and run test locally on different versions before sending a pull request.

Thank you.

This pull request fails (merged d060666 into 1e97cce).

Contributor
dekellum commented Jul 2, 2012

I'm sure you see a lot of these @luislavena. This pull request is known bad, since I'm demonstrating unit tests that I believe should pass, but instead fail. Its not complete. Sorry to all including @travisbot, if I should be doing this some other way. What would you suggest?

Member

@drbrain @zenspider @evanphx what do you guys think? pessimistic operator should work under those cases?

Contributor

ETA: I think this ticket should be rejected and closed.

Seems to work fine to me:

>> r = Gem::Requirement.new "~> 1.4.beta"
=> #<Gem::Requirement:0x1018375c8 @requirements=[["~>", #<Gem::Version "1.4.beta">]], @none=false>
>> r.satisfied_by? Gem::Version.new("1.4.0")
=> true
>> r.satisfied_by? Gem::Version.new("1.4.0.beta1")
=> true
>> r.satisfied_by? Gem::Version.new("1.5.0.beta1")
=> true

vs

>> r = Gem::Requirement.new "~> 1.4.0.beta"
=> #<Gem::Requirement:0x101815ea0 @requirements=[["~>", #<Gem::Version "1.4.0.beta">]], @none=false>
>> r.satisfied_by? Gem::Version.new("1.5.0.beta1")
=> false
>> r.satisfied_by? Gem::Version.new("1.4.0.beta1")
=> true
>> r.satisfied_by? Gem::Version.new("1.4.0")
=> true

vs

>> r = Gem::Requirement.new "~> 1.4.0"
=> #<Gem::Requirement:0x1017ff538 @requirements=[["~>", #<Gem::Version "1.4.0">]], @none=false>
>> r.satisfied_by? Gem::Version.new("1.4.0.beta1")
=> false
Owner
evanphx commented Jul 2, 2012

~> match was really never designed to be used with a prerelease token, which is what is happening here. I believe that in this case ~> 1.4.beta would be read as "The 1.4 beta release or later" which is what the current behavior shows.

What you probably wanted was not this but rather ~> 1.4.0.beta to mean "Anything inside the 1.4 newer than 0.beta".

Based on this, we could use some docs to explain what it means, but I'm not inclined to change the current behavior.

@evanphx evanphx closed this Jul 2, 2012
Contributor
dekellum commented Jul 4, 2012

Thanks for this explanation @zenspider and @evanphx as I definitely didn't find the "by design" behavior here obvious.

An important conclusion, is that if anyone makes the apparent mistake of a prerelease that will later be released with a 0 in the same segment, like following progression:

  • 1.0.0
  • 1.1.beta.0
  • 1.1.0
  • 1.1.1
  • 1.2.0

Then, if you are development in parallel and try and depend on the beta with ~> 1.1.beta, you will not get what you want: 1.1.beta.0 now, 1.1.0 and 1.1.1 when they are released, but not 1.2.0. In fact as far as my testing shows, there is no way to actually specify such a requirement (using ranges,etc.)!

But gems i18n, pg, mongo, bundler are all examples of popular gems that have released with this pattern.

If instead:

  • 1.1.0.beta.0

is used, then ~> 1.1.0.beta has the desired behavior, as @evanphx suggests.

Assuming this continues to match your understanding of desired behavior, would it be helpful if a warning was issues on Gem::Specification creation with a version with a alphanumeric segment proceeded by a non-zero segment?

I will open a new issue for some other oddities I'm finding in the requirement range handling with prereleases.

Owner
drbrain commented Jul 4, 2012

I think '> 1', '< 1.2' will grab prerelease versions in the range you want.

Contributor
dekellum commented Jul 4, 2012

@drbrain, but it will also grab 1.2.beta.0 (or 1.2.0.beta.0) which in this and other cases I don't want. See #350 for those test cases.

Owner
drbrain commented Jul 5, 2012

Then '> 1', '< 1.2.a' will do what you want.

".a" is the first allowable prerelease.

Contributor
dekellum commented Jul 5, 2012

And I guess refining it further to [ '> 1.0.999', '< 1.2.a' ] then also avoids a potential undesired match of any current or after the fact releases in the 1.0.x series. So at least there is a workaround, albeit rather odd looking, thanks.

Contributor
dekellum commented Jul 5, 2012

Or slightly better, [ '>= 1.1.beta', '< 1.2.a' ]

Contributor

A bit of a report on this:

http://gravitext.com/2012/07/22/versioning.html#rubygems

In case it helps any users finding this issue, or inspires anyone to improve any documentation.

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