Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions bundler/lib/bundler/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,13 @@ def gem(name, *args)

# if there's already a dependency with this name we try to prefer one
if current = @dependencies.find {|d| d.name == dep.name }
# Always prefer the dependency from the Gemfile
deleted_dep = @dependencies.delete(current) if current.type == :development

if current.requirement != dep.requirement
current_requirement_open = current.requirements_list.include?(">= 0")

if current.type == :development
@dependencies.delete(current)

unless current_requirement_open || dep.type == :development
Bundler.ui.warn "A gemspec development dependency (#{dep.name}, #{current.requirement}) is being overridden by a Gemfile dependency (#{dep.name}, #{dep.requirement}).\n" \
"This behaviour may change in the future. Please remove either of them, or make sure they both have the same requirement\n" \
Expand All @@ -129,12 +130,13 @@ def gem(name, *args)
"You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
"#{update_prompt}"
end
elsif current.type == :development || dep.type == :development
return if deleted_dep.nil?
elsif current.source != dep.source
return if dep.type == :development
raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
"You specified that #{dep.name} (#{dep.requirement}) should come from " \
"#{current.source || "an unspecified source"} and #{dep.source}\n"
elsif current.type != :development && dep.type != :development
else
Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
"You should probably keep only one of them.\n" \
"Remove any duplicate entries and specify the gem only once.\n" \
Expand Down
35 changes: 35 additions & 0 deletions bundler/spec/commands/install_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,41 @@
expect(the_bundle).to include_gems("rubocop 1.37.1")
end

it "does not warn if a gem is added once in Gemfile and also inside a gemspec as a development dependency, with same requirements, and different sources" do
build_lib "my-gem", :path => bundled_app do |s|
s.add_development_dependency "activesupport"
end

build_repo4 do
build_gem "activesupport"
end

build_git "activesupport", "1.0", :path => lib_path("activesupport")

install_gemfile <<~G
source "#{file_uri_for(gem_repo4)}"

gemspec

gem "activesupport", :git => "#{file_uri_for(lib_path("activesupport"))}"
G

expect(err).to be_empty
expect(the_bundle).to include_gems "activesupport 1.0", :source => "git@#{lib_path("activesupport")}"

# if the Gemfile dependency is specified first
install_gemfile <<~G
source "#{file_uri_for(gem_repo4)}"

gem "activesupport", :git => "#{file_uri_for(lib_path("activesupport"))}"

gemspec
G

expect(err).to be_empty
expect(the_bundle).to include_gems "activesupport 1.0", :source => "git@#{lib_path("activesupport")}"
end

it "considers both dependencies for resolution if a gem is added once in Gemfile and also inside a local gemspec as a runtime dependency, with different requirements" do
build_lib "my-gem", :path => bundled_app do |s|
s.add_dependency "rubocop", "~> 1.36.0"
Expand Down