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
6 changes: 6 additions & 0 deletions bundler/lib/bundler/checksum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ def missing?(spec)
@store[spec.lock_name].nil?
end

def empty?(spec)
return false unless spec.source.is_a?(Bundler::Source::Rubygems)

@store[spec.lock_name].empty?
end

def register(spec, checksum)
register_checksum(spec.lock_name, checksum)
end
Expand Down
17 changes: 15 additions & 2 deletions bundler/lib/bundler/definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ def lockfile_changes_summary(update_refused_reason)

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

msg = String.new("#{change_reason.capitalize.strip}, but ")
msg = String.new("#{change_reason[0].upcase}#{change_reason[1..-1].strip}, but ")
msg << "the lockfile " unless msg.start_with?("Your lockfile")
msg << "can't be updated because #{update_refused_reason}"
msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
Expand All @@ -557,6 +557,7 @@ def something_changed?
@missing_lockfile_dep ||
@unlocking_bundler ||
@locked_spec_with_missing_checksums ||
@locked_spec_with_empty_checksums ||
@locked_spec_with_missing_deps ||
@locked_spec_with_invalid_deps
end
Expand Down Expand Up @@ -836,6 +837,7 @@ def lockfile_changed_reason
[@missing_lockfile_dep, "your lockfile is missing \"#{@missing_lockfile_dep}\""],
[@unlocking_bundler, "an update to the version of Bundler itself was requested"],
[@locked_spec_with_missing_checksums, "your lockfile is missing a CHECKSUMS entry for \"#{@locked_spec_with_missing_checksums}\""],
[@locked_spec_with_empty_checksums, "your lockfile has an empty CHECKSUMS entry for \"#{@locked_spec_with_empty_checksums}\""],
[@locked_spec_with_missing_deps, "your lockfile includes \"#{@locked_spec_with_missing_deps}\" but not some of its dependencies"],
[@locked_spec_with_invalid_deps, "your lockfile does not satisfy dependencies of \"#{@locked_spec_with_invalid_deps}\""],
].select(&:first).map(&:last).join(", ")
Expand Down Expand Up @@ -895,13 +897,23 @@ def check_lockfile
@locked_spec_with_invalid_deps = nil
@locked_spec_with_missing_deps = nil
@locked_spec_with_missing_checksums = nil
@locked_spec_with_empty_checksums = nil

missing_deps = []
missing_checksums = []
empty_checksums = []
invalid = []

@locked_specs.each do |s|
missing_checksums << s if @locked_checksums && s.source.checksum_store.missing?(s)
if @locked_checksums
checksum_store = s.source.checksum_store

if checksum_store.missing?(s)
missing_checksums << s
elsif checksum_store.empty?(s)
empty_checksums << s
end
end

validation = @locked_specs.validate_deps(s)

Expand All @@ -910,6 +922,7 @@ def check_lockfile
end

@locked_spec_with_missing_checksums = missing_checksums.first.name if missing_checksums.any?
@locked_spec_with_empty_checksums = empty_checksums.first.name if empty_checksums.any?

if missing_deps.any?
@locked_specs.delete(missing_deps)
Expand Down
2 changes: 1 addition & 1 deletion bundler/spec/commands/update_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1852,7 +1852,7 @@
system_gems "bundler-9.9.9", path: local_gem_path

bundle "update --bundler=9.9.9", env: { "BUNDLE_FROZEN" => "true" }, raise_on_error: false
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")
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")
end
end

Expand Down
64 changes: 56 additions & 8 deletions bundler/spec/install/gemfile/git_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,25 @@

RSpec.describe "bundle install with git sources" do
describe "when floating on main" do
before :each do
build_git "foo" do |s|
s.executables = "foobar"
end

install_gemfile <<-G
let(:base_gemfile) do
<<-G
source "https://gem.repo1"
git "#{lib_path("foo-1.0")}" do
gem 'foo'
end
G
end

let(:install_base_gemfile) do
build_git "foo" do |s|
s.executables = "foobar"
end

install_gemfile base_gemfile
end

it "fetches gems" do
install_base_gemfile
expect(the_bundle).to include_gems("foo 1.0")

run <<-RUBY
Expand All @@ -26,17 +31,57 @@
expect(out).to eq("WIN")
end

it "does not (yet?) enforce CHECKSUMS" do
build_git "foo"
revision = revision_for(lib_path("foo-1.0"))

bundle "config set lockfile_checksums true"
gemfile base_gemfile

lockfile <<~L
GIT
remote: #{lib_path("foo-1.0")}
revision: #{revision}
specs:
foo (1.0)

GEM
remote: https://gem.repo1/
specs:

PLATFORMS
#{lockfile_platforms}

DEPENDENCIES
foo!

CHECKSUMS
foo (1.0)

BUNDLED WITH
#{Bundler::VERSION}
L

bundle "config set frozen true"

bundle "install"
expect(the_bundle).to include_gems("foo 1.0")
end

it "caches the git repo" do
install_base_gemfile
expect(Dir["#{default_bundle_path}/cache/bundler/git/foo-1.0-*"]).to have_attributes size: 1
end

it "does not write to cache on bundler/setup" do
install_base_gemfile
FileUtils.rm_r(default_cache_path)
ruby "require 'bundler/setup'"
expect(default_cache_path).not_to exist
end

it "caches the git repo globally and properly uses the cached repo on the next invocation" do
install_base_gemfile
pristine_system_gems
bundle "config set global_gem_cache true"
bundle :install
Expand All @@ -48,6 +93,7 @@
end

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

it "does not update the git source implicitly" do
install_base_gemfile
update_git "foo"

install_gemfile bundled_app2("Gemfile"), <<-G, dir: bundled_app2
Expand All @@ -84,6 +131,7 @@
end

it "sets up git gem executables on the path" do
install_base_gemfile
bundle "exec foobar"
expect(out).to eq("1.0")
end
Expand Down Expand Up @@ -136,7 +184,7 @@

it "still works after moving the application directory" do
bundle "config set --local path vendor/bundle"
bundle "install"
install_base_gemfile

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

Expand All @@ -145,7 +193,7 @@

it "can still install after moving the application directory" do
bundle "config set --local path vendor/bundle"
bundle "install"
install_base_gemfile

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

Expand Down
36 changes: 35 additions & 1 deletion bundler/spec/lock/lockfile_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1638,14 +1638,48 @@
G

expect(err).to eq <<~L.strip
Your lockfile is missing a checksums entry for \"myrack_middleware\", but can't be updated because frozen mode is set
Your lockfile is missing a CHECKSUMS entry for \"myrack_middleware\", but can't be updated because frozen mode is set

Run `bundle install` elsewhere and add the updated Gemfile.lock to version control.
L

expect(the_bundle).not_to include_gems "myrack_middleware 1.0"
end

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
lockfile <<-L
GEM
remote: https://gem.repo2/
specs:
myrack (0.9.1)

PLATFORMS
#{lockfile_platforms}

DEPENDENCIES
myrack

CHECKSUMS
myrack (0.9.1)

BUNDLED WITH
#{Bundler::VERSION}
L

install_gemfile <<-G, env: { "BUNDLE_FROZEN" => "true" }, raise_on_error: false
source "https://gem.repo2"
gem "myrack"
G

expect(err).to eq <<~L.strip
Your lockfile has an empty CHECKSUMS entry for \"myrack\", but can't be updated because frozen mode is set

Run `bundle install` elsewhere and add the updated Gemfile.lock to version control.
L

expect(the_bundle).not_to include_gems "myrack 0.9.1"
end

it "automatically fixes the lockfile when it's missing deps, they conflict with other locked deps, but conflicts are fixable" do
build_repo4 do
build_gem "other_dep", "0.9"
Expand Down