From b86a7ba49252e00e19c22bbcdc821b5acc31ff92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 20 Dec 2021 19:54:08 +0100 Subject: [rubygems/rubygems] Fix error when gem specified twice in gemfile under different platforms https://github.com/rubygems/rubygems/commit/83bc87ca98 --- lib/bundler/definition.rb | 16 ++++++++++------ spec/bundler/commands/install_spec.rb | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 9a94bd3ed3..19e5569fad 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -87,10 +87,11 @@ module Bundler @platforms = @locked_platforms.dup @locked_bundler_version = @locked_gems.bundler_version @locked_ruby_version = @locked_gems.ruby_version + @originally_locked_specs = SpecSet.new(@locked_gems.specs) if unlock != true @locked_deps = @locked_gems.dependencies - @locked_specs = SpecSet.new(@locked_gems.specs) + @locked_specs = @originally_locked_specs @locked_sources = @locked_gems.sources else @unlock = {} @@ -691,13 +692,16 @@ module Bundler def converge_specs(specs) deps = [] converged = [] - specs.each do |s| - # Replace the locked dependency's source with the equivalent source from the Gemfile - dep = @dependencies.find {|d| s.satisfies?(d) } - if dep && (!dep.source || s.source.include?(dep.source)) + @dependencies.each do |dep| + if specs[dep].any? {|s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) } deps << dep end + end + + specs.each do |s| + # Replace the locked dependency's source with the equivalent source from the Gemfile + dep = @dependencies.find {|d| s.satisfies?(d) } s.source = (dep && dep.source) || sources.get(s.source) || sources.default_source unless Bundler.frozen_bundle? @@ -830,7 +834,7 @@ module Bundler def additional_base_requirements_for_resolve return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources) - converge_specs(@locked_gems.specs).map do |locked_spec| + converge_specs(@originally_locked_specs).map do |locked_spec| name = locked_spec.name dep = Gem::Dependency.new(name, ">= #{locked_spec.version}") DepProxy.get_proxy(dep, locked_spec.platform) diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb index 918dc28acb..dd4d31a1ad 100644 --- a/spec/bundler/commands/install_spec.rb +++ b/spec/bundler/commands/install_spec.rb @@ -391,6 +391,22 @@ RSpec.describe "bundle install with gem sources" do expect(err).to include("While it's not a problem now, it could cause errors if you change the version of one of them later.") end + it "throws a warning if a gem is added twice under different platforms and does not crash when using the generated lockfile" do + build_repo2 + + install_gemfile <<-G + source "#{file_uri_for(gem_repo2)}" + gem "rack", :platform => :jruby + gem "rack" + G + + bundle "install" + + expect(err).to include("Your Gemfile lists the gem rack (>= 0) more than once.") + expect(err).to include("Remove any duplicate entries and specify the gem only once.") + expect(err).to include("While it's not a problem now, it could cause errors if you change the version of one of them later.") + end + it "does not throw a warning if a gem is added once in Gemfile and also inside a gemspec as a development dependency" do build_lib "my-gem", :path => bundled_app do |s| s.add_development_dependency "my-private-gem" -- cgit v1.2.3