Skip to content

Commit 1c90030

Browse files
hsbtclaude
andcommitted
Reject duplicate target+field in override DSL
Two override statements that target the same gem and the same field make it ambiguous which operation should win. Raise ArgumentError when the new (target, field) pair already exists in the recorded overrides, leaving the previously recorded entry untouched. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c3b7aeb commit 1c90030

2 files changed

Lines changed: 28 additions & 0 deletions

File tree

bundler/lib/bundler/dsl.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ def override(target, **operations)
198198
operations.each do |field, operation|
199199
validate_override_field!(field)
200200
validate_override_operation!(operation)
201+
validate_override_uniqueness!(target, field)
201202
end
202203

203204
operations.each do |field, operation|
@@ -290,6 +291,11 @@ def validate_override_operation!(operation)
290291
end
291292
end
292293

294+
def validate_override_uniqueness!(target, field)
295+
return unless @overrides.any? {|o| o.target == target && o.field == field }
296+
raise ArgumentError, "duplicate override for #{target.inspect} `#{field}:`"
297+
end
298+
293299
def add_dependency(name, version = nil, options = {})
294300
options["gemfile"] = @gemfile
295301
options["source"] ||= @source

spec/bundler/dsl_spec.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,5 +447,27 @@
447447
end.to raise_error(ArgumentError, /unsupported override field/)
448448
expect(subject.overrides).to eq([])
449449
end
450+
451+
it "raises ArgumentError when the same target and field are overridden twice" do
452+
subject.override("rails", version: ">= 8.0")
453+
expect do
454+
subject.override("rails", version: :ignore_upper)
455+
end.to raise_error(ArgumentError, /duplicate override for "rails" `version:`/)
456+
end
457+
458+
it "keeps the original override when a duplicate is rejected" do
459+
subject.override("rails", version: ">= 8.0")
460+
expect do
461+
subject.override("rails", version: :ignore_upper)
462+
end.to raise_error(ArgumentError)
463+
expect(subject.overrides.size).to eq(1)
464+
expect(subject.overrides.first.operation).to eq(">= 8.0")
465+
end
466+
467+
it "allows different targets with the same field" do
468+
subject.override("rails", version: ">= 8.0")
469+
subject.override("nokogiri", version: :ignore_upper)
470+
expect(subject.overrides.size).to eq(2)
471+
end
450472
end
451473
end

0 commit comments

Comments
 (0)