Skip to content

Commit 8c551a3

Browse files
hsbtclaude
andcommitted
Show only mismatched dependencies in lockfile error message
Instead of listing all dependencies from both gemspec and lockfile, show only the ones that actually differ to make it easier to identify the source of the discrepancy. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent c90d778 commit 8c551a3

File tree

5 files changed

+28
-58
lines changed

5 files changed

+28
-58
lines changed

bundler/lib/bundler/errors.rb

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -277,33 +277,26 @@ def message
277277
msg = "Bundler found incorrect dependencies in the lockfile for #{spec.full_name}\n"
278278

279279
if @actual_dependencies && @lockfile_dependencies
280-
msg << "\n"
281-
msg << "The gemspec for #{spec.full_name} specifies the following dependencies:\n"
282-
if @actual_dependencies.empty?
283-
msg << " (none)\n"
284-
else
285-
@actual_dependencies.sort_by(&:to_s).each do |dep|
286-
msg << " #{dep}\n"
280+
actual_by_name = @actual_dependencies.each_with_object({}) {|d, h| h[d.name] = d }
281+
lockfile_by_name = @lockfile_dependencies.each_with_object({}) {|d, h| h[d.name] = d }
282+
all_names = (actual_by_name.keys | lockfile_by_name.keys).sort
283+
284+
all_names.each do |name|
285+
actual = actual_by_name[name]
286+
lockfile = lockfile_by_name[name]
287+
next if actual && lockfile && actual.requirement == lockfile.requirement
288+
289+
if actual && lockfile
290+
msg << " #{name}: gemspec specifies #{actual.requirement}, lockfile has #{lockfile.requirement}\n"
291+
elsif actual
292+
msg << " #{name}: gemspec specifies #{actual.requirement}, not in lockfile\n"
293+
else
294+
msg << " #{name}: not in gemspec, lockfile has #{lockfile.requirement}\n"
287295
end
288296
end
289-
290-
msg << "\n"
291-
msg << "However, the lockfile has the following dependencies recorded:\n"
292-
if @lockfile_dependencies.empty?
293-
msg << " (none)\n"
294-
else
295-
@lockfile_dependencies.sort_by(&:to_s).each do |dep|
296-
msg << " #{dep}\n"
297-
end
298-
end
299-
300-
msg << "\n"
301-
msg << "This discrepancy may be caused by manually editing the lockfile.\n"
302-
msg << "Please run `bundle install` to regenerate the lockfile with correct dependencies."
303-
else
304-
msg << "\nPlease run `bundle install` to regenerate the lockfile."
305297
end
306298

299+
msg << "Please run `bundle install` to regenerate the lockfile."
307300
msg
308301
end
309302

spec/bundler/errors_spec.rb

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,12 @@
3434

3535
subject { described_class.new(spec, actual_dependencies, lockfile_dependencies) }
3636

37-
it "provides a detailed error message showing the discrepancy" do
37+
it "shows only mismatched dependencies" do
3838
message = subject.message
3939

40-
expect(message).to include("Bundler found incorrect dependencies in the lockfile for rubocop-1.82.0")
41-
expect(message).to include("The gemspec for rubocop-1.82.0 specifies the following dependencies:")
42-
expect(message).to include("json (>= 2.3, < 4.0)")
43-
expect(message).to include("parallel (~> 1.10)")
44-
expect(message).to include("parser (>= 3.3.0.2)")
45-
expect(message).to include("However, the lockfile has the following dependencies recorded:")
46-
expect(message).to include("json (>= 2.3, < 3.0)")
47-
expect(message).to include("parser (>= 3.2.0.0)")
48-
expect(message).to include("This discrepancy may be caused by manually editing the lockfile.")
49-
expect(message).to include("Please run `bundle install` to regenerate the lockfile with correct dependencies.")
40+
expect(message).to include("json: gemspec specifies")
41+
expect(message).to include("parser: gemspec specifies")
42+
expect(message).not_to include("parallel")
5043
end
5144
end
5245

@@ -61,13 +54,10 @@
6154

6255
subject { described_class.new(spec, actual_dependencies, lockfile_dependencies) }
6356

64-
it "shows that lockfile has no dependencies" do
57+
it "shows the dependency as not in lockfile" do
6558
message = subject.message
6659

67-
expect(message).to include("The gemspec for rubocop-1.82.0 specifies the following dependencies:")
68-
expect(message).to include("myrack-test (~> 1.0)")
69-
expect(message).to include("However, the lockfile has the following dependencies recorded:")
70-
expect(message).to include("(none)")
60+
expect(message).to include("myrack-test: gemspec specifies ~> 1.0, not in lockfile")
7161
end
7262
end
7363

@@ -82,13 +72,10 @@
8272

8373
subject { described_class.new(spec, actual_dependencies, lockfile_dependencies) }
8474

85-
it "shows that gemspec has no dependencies" do
75+
it "shows the dependency as not in gemspec" do
8676
message = subject.message
8777

88-
expect(message).to include("The gemspec for rubocop-1.82.0 specifies the following dependencies:")
89-
expect(message).to include("(none)")
90-
expect(message).to include("However, the lockfile has the following dependencies recorded:")
91-
expect(message).to include("unexpected (~> 1.0)")
78+
expect(message).to include("unexpected: not in gemspec, lockfile has ~> 1.0")
9279
end
9380
end
9481
end

spec/commands/install_spec.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,10 +1659,7 @@ def run
16591659

16601660
expect(exitstatus).to eq(41)
16611661
expect(err).to include("Bundler found incorrect dependencies in the lockfile for myrack_middleware-1.0")
1662-
expect(err).to include("The gemspec for myrack_middleware-1.0 specifies the following dependencies:")
1663-
expect(err).to include("myrack (= 0.9.1)")
1664-
expect(err).to include("However, the lockfile has the following dependencies recorded:")
1665-
expect(err).to include("(none)")
1662+
expect(err).to include("myrack: gemspec specifies = 0.9.1, not in lockfile")
16661663
end
16671664

16681665
it "updates the lockfile when not frozen" do

spec/install/failure_spec.rb

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,8 @@
7878
bundle :install, raise_on_error: false, env: { "BUNDLE_FROZEN" => "true" }
7979

8080
expect(err).to include("Bundler found incorrect dependencies in the lockfile for myrack-1.0.0")
81-
expect(err).to include("The gemspec for myrack-1.0.0 specifies the following dependencies:")
82-
expect(err).to include("myrack-test (~> 1.0)")
83-
expect(err).to include("However, the lockfile has the following dependencies recorded:")
84-
expect(err).to include("(none)")
85-
expect(err).to include("This discrepancy may be caused by manually editing the lockfile.")
86-
expect(err).to include("Please run `bundle install` to regenerate the lockfile with correct dependencies.")
81+
expect(err).to include("myrack-test: gemspec specifies ~> 1.0, not in lockfile")
82+
expect(err).to include("Please run `bundle install` to regenerate the lockfile.")
8783
end
8884
end
8985
end

spec/lock/lockfile_spec.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,10 +1609,7 @@
16091609
G
16101610

16111611
expect(err).to include("Bundler found incorrect dependencies in the lockfile for myrack_middleware-1.0")
1612-
expect(err).to include("The gemspec for myrack_middleware-1.0 specifies the following dependencies:")
1613-
expect(err).to include("myrack (= 0.9.1)")
1614-
expect(err).to include("However, the lockfile has the following dependencies recorded:")
1615-
expect(err).to include("(none)")
1612+
expect(err).to include("myrack: gemspec specifies = 0.9.1, not in lockfile")
16161613
expect(the_bundle).not_to include_gems "myrack_middleware 1.0"
16171614
end
16181615

0 commit comments

Comments
 (0)