Skip to content

Commit

Permalink
Merge pull request #3889 from toy/sort-dependency-requirements
Browse files Browse the repository at this point in the history
Sort requirements in Gem::Requirement to succeed comparison with different order

(cherry picked from commit a452809)
  • Loading branch information
deivid-rodriguez committed Oct 5, 2020
1 parent a2418d0 commit cfa7c04
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 2 deletions.
29 changes: 29 additions & 0 deletions bundler/lib/bundler/rubygems_ext.rb
Expand Up @@ -129,6 +129,35 @@ def to_lock
end
end

# comparison is done order independently since rubygems 3.2.0.rc.2
unless Gem::Requirement.new("> 1", "< 2") == Gem::Requirement.new("< 2", "> 1")
class Requirement
module OrderIndependentComparison
def ==(other)
if _requirements_sorted? && other._requirements_sorted?
super
else
_with_sorted_requirements == other._with_sorted_requirements
end
end

protected

def _requirements_sorted?
return @_are_requirements_sorted if defined?(@_are_requirements_sorted)
strings = as_list
@_are_requirements_sorted = strings == strings.sort
end

def _with_sorted_requirements
@_with_sorted_requirements ||= _requirements_sorted? ? self : self.class.new(as_list.sort)
end
end

prepend OrderIndependentComparison
end
end

class Platform
JAVA = Gem::Platform.new("java") unless defined?(JAVA)
MSWIN = Gem::Platform.new("mswin32") unless defined?(MSWIN)
Expand Down
29 changes: 29 additions & 0 deletions bundler/spec/install/gemfile/platform_spec.rb
Expand Up @@ -281,6 +281,35 @@
expect(the_bundle).not_to include_gem "CFPropertyList"
end

it "works with gems with platform-specific dependency having different requirements order" do
simulate_platform x64_mac

update_repo2 do
build_gem "fspath", "3"
build_gem "image_optim_pack", "1.2.3" do |s|
s.add_runtime_dependency "fspath", ">= 2.1", "< 4"
end
build_gem "image_optim_pack", "1.2.3" do |s|
s.platform = "universal-darwin"
s.add_runtime_dependency "fspath", "< 4", ">= 2.1"
end
end

install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
G

install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "image_optim_pack"
G

expect(err).not_to include "Unable to use the platform-specific"

expect(the_bundle).to include_gem "image_optim_pack 1.2.3 universal-darwin"
end

it "fetches gems again after changing the version of Ruby" do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
Expand Down
8 changes: 6 additions & 2 deletions lib/rubygems/requirement.rb
Expand Up @@ -271,7 +271,7 @@ def ==(other) # :nodoc:
return unless Gem::Requirement === other

# An == check is always necessary
return false unless requirements == other.requirements
return false unless _sorted_requirements == other._sorted_requirements

# An == check is sufficient unless any requirements use ~>
return true unless _tilde_requirements.any?
Expand All @@ -283,8 +283,12 @@ def ==(other) # :nodoc:

protected

def _sorted_requirements
@_sorted_requirements ||= requirements.sort_by(&:to_s)
end

def _tilde_requirements
requirements.select {|r| r.first == "~>" }
@_tilde_requirements ||= _sorted_requirements.select {|r| r.first == "~>" }
end

private
Expand Down
2 changes: 2 additions & 0 deletions test/rubygems/test_gem_requirement.rb
Expand Up @@ -23,6 +23,8 @@ def test_equals2
refute_requirement_equal "~> 1.3", "~> 1.3.0"
refute_requirement_equal "~> 1.3.0", "~> 1.3"

assert_requirement_equal ["> 2", "~> 1.3", "~> 1.3.1"], ["~> 1.3.1", "~> 1.3", "> 2"]

assert_requirement_equal ["> 2", "~> 1.3"], ["> 2.0", "~> 1.3"]
assert_requirement_equal ["> 2.0", "~> 1.3"], ["> 2", "~> 1.3"]

Expand Down

0 comments on commit cfa7c04

Please sign in to comment.