Skip to content

Commit 5dba955

Browse files
Merge pull request #8888 from rubygems/deivid-rodriguez/detect-empty-checksums
Raise an error in frozen mode if some registry gems have empty checksums (cherry picked from commit 3a42889)
1 parent d17a276 commit 5dba955

File tree

5 files changed

+113
-12
lines changed

5 files changed

+113
-12
lines changed

bundler/lib/bundler/checksum.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,12 @@ def missing?(spec)
205205
@store[spec.lock_name].nil?
206206
end
207207

208+
def empty?(spec)
209+
return false unless spec.source.is_a?(Bundler::Source::Rubygems)
210+
211+
@store[spec.lock_name].empty?
212+
end
213+
208214
def register(spec, checksum)
209215
register_checksum(spec.lock_name, checksum)
210216
end

bundler/lib/bundler/definition.rb

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ def lockfile_changes_summary(update_refused_reason)
531531

532532
return unless added.any? || deleted.any? || changed.any? || resolve_needed?
533533

534-
msg = String.new("#{change_reason.capitalize.strip}, but ")
534+
msg = String.new("#{change_reason[0].upcase}#{change_reason[1..-1].strip}, but ")
535535
msg << "the lockfile " unless msg.start_with?("Your lockfile")
536536
msg << "can't be updated because #{update_refused_reason}"
537537
msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
@@ -557,6 +557,7 @@ def something_changed?
557557
@missing_lockfile_dep ||
558558
@unlocking_bundler ||
559559
@locked_spec_with_missing_checksums ||
560+
@locked_spec_with_empty_checksums ||
560561
@locked_spec_with_missing_deps ||
561562
@locked_spec_with_invalid_deps
562563
end
@@ -844,6 +845,7 @@ def lockfile_changed_reason
844845
[@missing_lockfile_dep, "your lockfile is missing \"#{@missing_lockfile_dep}\""],
845846
[@unlocking_bundler, "an update to the version of Bundler itself was requested"],
846847
[@locked_spec_with_missing_checksums, "your lockfile is missing a CHECKSUMS entry for \"#{@locked_spec_with_missing_checksums}\""],
848+
[@locked_spec_with_empty_checksums, "your lockfile has an empty CHECKSUMS entry for \"#{@locked_spec_with_empty_checksums}\""],
847849
[@locked_spec_with_missing_deps, "your lockfile includes \"#{@locked_spec_with_missing_deps}\" but not some of its dependencies"],
848850
[@locked_spec_with_invalid_deps, "your lockfile does not satisfy dependencies of \"#{@locked_spec_with_invalid_deps}\""],
849851
].select(&:first).map(&:last).join(", ")
@@ -903,13 +905,23 @@ def check_lockfile
903905
@locked_spec_with_invalid_deps = nil
904906
@locked_spec_with_missing_deps = nil
905907
@locked_spec_with_missing_checksums = nil
908+
@locked_spec_with_empty_checksums = nil
906909

907910
missing_deps = []
908911
missing_checksums = []
912+
empty_checksums = []
909913
invalid = []
910914

911915
@locked_specs.each do |s|
912-
missing_checksums << s if @locked_checksums && s.source.checksum_store.missing?(s)
916+
if @locked_checksums
917+
checksum_store = s.source.checksum_store
918+
919+
if checksum_store.missing?(s)
920+
missing_checksums << s
921+
elsif checksum_store.empty?(s)
922+
empty_checksums << s
923+
end
924+
end
913925

914926
validation = @locked_specs.validate_deps(s)
915927

@@ -918,6 +930,7 @@ def check_lockfile
918930
end
919931

920932
@locked_spec_with_missing_checksums = missing_checksums.first.name if missing_checksums.any?
933+
@locked_spec_with_empty_checksums = empty_checksums.first.name if empty_checksums.any?
921934

922935
if missing_deps.any?
923936
@locked_specs.delete(missing_deps)

bundler/spec/commands/update_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1852,7 +1852,7 @@
18521852
system_gems "bundler-9.9.9", path: local_gem_path
18531853

18541854
bundle "update --bundler=9.9.9", env: { "BUNDLE_FROZEN" => "true" }, raise_on_error: false
1855-
expect(err).to include("An update to the version of bundler itself was requested, but the lockfile can't be updated because frozen mode is set")
1855+
expect(err).to include("An update to the version of Bundler itself was requested, but the lockfile can't be updated because frozen mode is set")
18561856
end
18571857
end
18581858

bundler/spec/install/gemfile/git_spec.rb

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,25 @@
22

33
RSpec.describe "bundle install with git sources" do
44
describe "when floating on main" do
5-
before :each do
6-
build_git "foo" do |s|
7-
s.executables = "foobar"
8-
end
9-
10-
install_gemfile <<-G
5+
let(:base_gemfile) do
6+
<<-G
117
source "https://gem.repo1"
128
git "#{lib_path("foo-1.0")}" do
139
gem 'foo'
1410
end
1511
G
1612
end
1713

14+
let(:install_base_gemfile) do
15+
build_git "foo" do |s|
16+
s.executables = "foobar"
17+
end
18+
19+
install_gemfile base_gemfile
20+
end
21+
1822
it "fetches gems" do
23+
install_base_gemfile
1924
expect(the_bundle).to include_gems("foo 1.0")
2025

2126
run <<-RUBY
@@ -26,17 +31,57 @@
2631
expect(out).to eq("WIN")
2732
end
2833

34+
it "does not (yet?) enforce CHECKSUMS" do
35+
build_git "foo"
36+
revision = revision_for(lib_path("foo-1.0"))
37+
38+
bundle "config set lockfile_checksums true"
39+
gemfile base_gemfile
40+
41+
lockfile <<~L
42+
GIT
43+
remote: #{lib_path("foo-1.0")}
44+
revision: #{revision}
45+
specs:
46+
foo (1.0)
47+
48+
GEM
49+
remote: https://gem.repo1/
50+
specs:
51+
52+
PLATFORMS
53+
#{lockfile_platforms}
54+
55+
DEPENDENCIES
56+
foo!
57+
58+
CHECKSUMS
59+
foo (1.0)
60+
61+
BUNDLED WITH
62+
#{Bundler::VERSION}
63+
L
64+
65+
bundle "config set frozen true"
66+
67+
bundle "install"
68+
expect(the_bundle).to include_gems("foo 1.0")
69+
end
70+
2971
it "caches the git repo" do
72+
install_base_gemfile
3073
expect(Dir["#{default_bundle_path}/cache/bundler/git/foo-1.0-*"]).to have_attributes size: 1
3174
end
3275

3376
it "does not write to cache on bundler/setup" do
77+
install_base_gemfile
3478
FileUtils.rm_r(default_cache_path)
3579
ruby "require 'bundler/setup'"
3680
expect(default_cache_path).not_to exist
3781
end
3882

3983
it "caches the git repo globally and properly uses the cached repo on the next invocation" do
84+
install_base_gemfile
4085
pristine_system_gems
4186
bundle "config set global_gem_cache true"
4287
bundle :install
@@ -48,6 +93,7 @@
4893
end
4994

5095
it "caches the evaluated gemspec" do
96+
install_base_gemfile
5197
git = update_git "foo" do |s|
5298
s.executables = ["foobar"] # we added this the first time, so keep it now
5399
s.files = ["bin/foobar"] # updating git nukes the files list
@@ -66,6 +112,7 @@
66112
end
67113

68114
it "does not update the git source implicitly" do
115+
install_base_gemfile
69116
update_git "foo"
70117

71118
install_gemfile bundled_app2("Gemfile"), <<-G, dir: bundled_app2
@@ -84,6 +131,7 @@
84131
end
85132

86133
it "sets up git gem executables on the path" do
134+
install_base_gemfile
87135
bundle "exec foobar"
88136
expect(out).to eq("1.0")
89137
end
@@ -136,7 +184,7 @@
136184

137185
it "still works after moving the application directory" do
138186
bundle "config set --local path vendor/bundle"
139-
bundle "install"
187+
install_base_gemfile
140188

141189
FileUtils.mv bundled_app, tmp("bundled_app.bck")
142190

@@ -145,7 +193,7 @@
145193

146194
it "can still install after moving the application directory" do
147195
bundle "config set --local path vendor/bundle"
148-
bundle "install"
196+
install_base_gemfile
149197

150198
FileUtils.mv bundled_app, tmp("bundled_app.bck")
151199

bundler/spec/lock/lockfile_spec.rb

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1638,14 +1638,48 @@
16381638
G
16391639

16401640
expect(err).to eq <<~L.strip
1641-
Your lockfile is missing a checksums entry for \"myrack_middleware\", but can't be updated because frozen mode is set
1641+
Your lockfile is missing a CHECKSUMS entry for \"myrack_middleware\", but can't be updated because frozen mode is set
16421642
16431643
Run `bundle install` elsewhere and add the updated Gemfile.lock to version control.
16441644
L
16451645

16461646
expect(the_bundle).not_to include_gems "myrack_middleware 1.0"
16471647
end
16481648

1649+
it "raises a clear error when frozen mode is set and lockfile has empty checksums in CHECKSUMS section, and does not install any gems" do
1650+
lockfile <<-L
1651+
GEM
1652+
remote: https://gem.repo2/
1653+
specs:
1654+
myrack (0.9.1)
1655+
1656+
PLATFORMS
1657+
#{lockfile_platforms}
1658+
1659+
DEPENDENCIES
1660+
myrack
1661+
1662+
CHECKSUMS
1663+
myrack (0.9.1)
1664+
1665+
BUNDLED WITH
1666+
#{Bundler::VERSION}
1667+
L
1668+
1669+
install_gemfile <<-G, env: { "BUNDLE_FROZEN" => "true" }, raise_on_error: false
1670+
source "https://gem.repo2"
1671+
gem "myrack"
1672+
G
1673+
1674+
expect(err).to eq <<~L.strip
1675+
Your lockfile has an empty CHECKSUMS entry for \"myrack\", but can't be updated because frozen mode is set
1676+
1677+
Run `bundle install` elsewhere and add the updated Gemfile.lock to version control.
1678+
L
1679+
1680+
expect(the_bundle).not_to include_gems "myrack 0.9.1"
1681+
end
1682+
16491683
it "automatically fixes the lockfile when it's missing deps, they conflict with other locked deps, but conflicts are fixable" do
16501684
build_repo4 do
16511685
build_gem "other_dep", "0.9"

0 commit comments

Comments
 (0)