Fix canonical_segments/equality to match <=> and pre-2.7.0 behaviour#2597
Fix canonical_segments/equality to match <=> and pre-2.7.0 behaviour#2597jhawthorn wants to merge 6 commits intoruby:masterfrom
Conversation
|
Thanks for opening a pull request and helping make RubyGems better! Someone from the RubyGems team will take a look at your pull request shortly and leave any feedback. Please make sure that your pull request has tests for any changes or added functionality. We use Travis CI to test and make sure your change works functionally and uses acceptable conventions, you can review the current progress of Travis CI in the PR status window below. If you have any questions or concerns that you wish to ask, feel free to leave a comment in this PR or join our #rubygems channel on Slack. For more information about contributing to the RubyGems project feel free to review our CONTRIBUTING guide |
|
Can you be a bit more explicit what this is trying to fix? I dont think this is correct, |
|
(oops. I gave this a bad title. Fixed) #2595 has the detailed description of the issue, the short version is: Previously, This restores the transitive property and reverts comparisons to the pre-2.7.0 behaviour.
(I've interpreted + as concatenation, sorry if that's wrong) IMO Oh! I came up with another example under the previous behaviour: > def v(s); Gem::Version.new(s); end
> v("1.a") < v("1.b")
=> true
> v("1.0.a") < v("1.b")
=> false |
|
I think we should fix the |
That would make this internally consistent, but I don't think Changing On the other hand I don't think changing the behaviour of |
|
@jhawthorn I had a look at this. What about this patch? diff --git a/lib/rubygems/version.rb b/lib/rubygems/version.rb
index f2f10569..7d7c15f7 100644
--- a/lib/rubygems/version.rb
+++ b/lib/rubygems/version.rb
@@ -343,8 +343,8 @@ class Gem::Version
return unless Gem::Version === other
return 0 if @version == other._version || canonical_segments == other.canonical_segments
- lhsegments = _segments
- rhsegments = other._segments
+ lhsegments = canonical_segments
+ rhsegments = other.canonical_segments
lhsize = lhsegments.size
rhsize = rhsegments.size
diff --git a/test/rubygems/test_gem_version.rb b/test/rubygems/test_gem_version.rb
index 939360c7..ece8001c 100644
--- a/test/rubygems/test_gem_version.rb
+++ b/test/rubygems/test_gem_version.rb
@@ -157,6 +157,10 @@ class TestGemVersion < Gem::TestCase
assert_equal( 1, v("1.8.2.a10") <=> v("1.8.2.a9"))
assert_equal( 0, v("") <=> v("0"))
+ assert_equal( 0, v("0.beta.1") <=> v("0.0.beta.1"))
+ assert_equal(-1, v("0.0.beta") <=> v("0.0.beta.1"))
+ assert_equal(-1, v("0.0.beta") <=> v("0.beta.1"))
+
assert_nil v("1.0") <=> "whatever"
endIt matches the behavior I personally expect for the tests you added. |
I don't think we want to break this pattern. Since the patch I just posted passes all tests for me, we should also add a new test covering this pattern in case my patch is actually breaking it. |
@deivid-rodriguez thanks for taking a look! Your patch does break this pattern and I've now added additional tests for that 🙂 (both to the version test and requirement test, where I think it's more clear). |
|
@jhawthorn Thanks! So, I wasn't accurate on defining my expectations in my last message. The way I would expect rubygems to work is so that I think the only reason I do understand people are currently relying on this bug, so it's complicated how to proceed. We could consider deprecating it and keeping it until the next major, it might be worth investigating how hard it is to do that. |
|
Actually, it might be easier to actually look out for for gems with these wrong requirements and spread out PRs changing this? 😃 |
gems using this already exist and are on rubygems, sending PRs will do nothing to "fix" existing published gems using this pattern. They're immutable (unless they are all yanked). I don't think the concept of "how gem versions work" can ever be safely deprecating and it would be best if it never changed. It's unfortunate it was changed by accident in #1659. Fortunately it changed in a mostly inconsequential (due to usage) way. We would not be so lucky with the proposed change to Personally, I'd rather we keep the current, broken (per #2595) change than to change
This is inaccurate.
I see no inconsistencies between the docs here and the current behaviour (although it's wrong about "a-z", since "A-Z" are also supported). Nothing describes internal It would be nice to hear where the desire to strip internal |
But this will only affect versions of gems depending on unreleased pre's. Once the final version is released, this problem should no longer happen, right? For example,
You're right. I misunderstood those docs, and didn't double check with the code.
You're right again. But the behavior we're currently talking about (
To me that was a good change, because of being intuitive. I do expect that To sum up, I tend to prefer to go with the option 2 you proposed in #2595, preceded by PRs to affected gems. That said, I could live with what you are proposing here too. I'd like to hear more opinions! |
|
Still it strikes as weird to me that |
|
Also, what if we had Going back in history a bit, I'm now remembering how I started learning about rubygems prereleases. It was because I originally proposed tweaking the dependency recommendation for semver dependencies when using upper bounds to include ".x" after the upper bound. @segiddins told me that would introduce a bug of not excluding ".a" prereleases (and others alphabetically sorted before ".x"). That was actually not happening, but now I realized it was only because of this bug of not comparing canonical versions. See #2266 for the discussion. |
|
I looked for gems with these kind of requirements on my system with |
2651: Restore transitiveness of version comparison r=bronzdoc a=deivid-rodriguez # Description: This is an alternative to #2597 fix to #2595. I strongly think this is the best way to fix this, even if it _could_ create some incompatibility with some gems relying on things like "~> 5.x" being lower than _all_ 5.0.0 prereleases. As explained in that discussion, the official way that's recommended in the docs to match all prereleases is "~> 5.a", because "a" is the first string in lexicographical order. I created PRs to the two gems I found relying on this: * rails/activemodel-serializers-xml#17 * rails/rails-controller-testing#45 I would consider this a bug fix and ship it normally on a bug fix release, but I can understand if others prefer a more conservative approach. # Tasks: - [x] Describe the problem / feature - [x] Write tests - [x] Write code to solve the problem - [ ] Get code review from coworkers / friends I will abide by the [code of conduct](https://github.com/rubygems/rubygems/blob/master/CODE_OF_CONDUCT.md). Co-authored-by: John Hawthorn <john@hawthorn.email>
|
Superseded by #2651. |
Technically, if the rails team released a new "5.0.1.zeitgeist" prerelease version and rubygems behavior was fixed according to ruby/rubygems#2597, this requirement would no longer do what it's supposed to do. This will clearly not happen, but I wanted to raise awareness of this xD.
Description:
This fixes #2595 by not removing 0's which precede a prerelease segment. I've split this into 4 commits, each of which should pass tests to "show my work", but they could all be squashed.
The final commit re-adds
canonical_segments == other.canonical_segments, which probably isn't necessary sincecanonical_segmentsnow match the later logic in this method, but I left it in to make the change as small as possible.I will abide by the code of conduct.