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
4 changes: 4 additions & 0 deletions bundler/lib/bundler/dependency.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ def should_include?
@should_include && current_env? && current_platform?
end

def gemspec_dev_dep?
type == :development
end

def current_env?
return true unless @env
if @env.is_a?(Hash)
Expand Down
19 changes: 12 additions & 7 deletions bundler/lib/bundler/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,21 @@ 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
@dependencies.delete(current) if current.gemspec_dev_dep?

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

if current.type == :development
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" \
gemspec_dep = [dep, current].find(&:gemspec_dev_dep?)
if gemspec_dep
gemfile_dep = [dep, current].find(&:runtime?)

unless current_requirement_open
Bundler.ui.warn "A gemspec development dependency (#{gemspec_dep.name}, #{gemspec_dep.requirement}) is being overridden by a Gemfile dependency (#{gemfile_dep.name}, #{gemfile_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"
end

return if dep.gemspec_dev_dep?
else
update_prompt = ""

Expand All @@ -130,8 +135,8 @@ 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.gemspec_dev_dep? || dep.gemspec_dev_dep?
return if dep.gemspec_dev_dep?
elsif current.source != dep.source
raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
"You specified that #{dep.name} (#{dep.requirement}) should come from " \
Expand Down
29 changes: 29 additions & 0 deletions bundler/spec/commands/install_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,35 @@
expect(the_bundle).to include_gems("rubocop 1.37.1")
end

it "warns when a Gemfile dependency is overriding a gemspec development dependency, with different requirements" do
build_lib "my-gem", path: bundled_app do |s|
s.add_development_dependency "rails", ">= 5"
end

build_repo4 do
build_gem "rails", "7.0.8"
end

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

gem "rails", "~> 7.0.8"

gemspec
G

bundle :install

expect(err).to include("A gemspec development dependency (rails, >= 5) is being overridden by a Gemfile dependency (rails, ~> 7.0.8).")
expect(err).to include("This behaviour may change in the future. Please remove either of them, or make sure they both have the same requirement")

# This is not the best behavior I believe, it would be better if both
# requirements are considered if they are compatible, and a version
# satisfying both is chosen. But not sure about changing it right now, so
# I went with a warning for the time being.
expect(the_bundle).to include_gems("rails 7.0.8")
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"
Expand Down