diff --git a/bundler/lib/bundler/definition.rb b/bundler/lib/bundler/definition.rb index efc749e9b326..f312a23f7f2f 100644 --- a/bundler/lib/bundler/definition.rb +++ b/bundler/lib/bundler/definition.rb @@ -988,6 +988,8 @@ def converge_sources end end + sources.metadata_source.checksum_store.merge!(@locked_gems.metadata_source.checksum_store) if @locked_gems + changes end diff --git a/bundler/lib/bundler/lockfile_generator.rb b/bundler/lib/bundler/lockfile_generator.rb index 6b6cf9d9eaee..e23263048c76 100644 --- a/bundler/lib/bundler/lockfile_generator.rb +++ b/bundler/lib/bundler/lockfile_generator.rb @@ -71,7 +71,8 @@ def add_checksums checksums = definition.resolve.map do |spec| spec.source.checksum_store.to_lock(spec) end - add_section("CHECKSUMS", checksums) + + add_section("CHECKSUMS", checksums + bundler_checksum) end def add_locked_ruby_version @@ -100,5 +101,17 @@ def add_section(name, value) raise ArgumentError, "#{value.inspect} can't be serialized in a lockfile" end end + + def bundler_checksum + return [] if Bundler.gem_version.to_s.end_with?(".dev") + + require "rubygems/package" + + bundler_spec = definition.sources.metadata_source.specs.search(["bundler", Bundler.gem_version]).last + package = Gem::Package.new(bundler_spec.cache_file) + definition.sources.metadata_source.checksum_store.register(bundler_spec, Checksum.from_gem_package(package)) + + [definition.sources.metadata_source.checksum_store.to_lock(bundler_spec)] + end end end diff --git a/bundler/lib/bundler/lockfile_parser.rb b/bundler/lib/bundler/lockfile_parser.rb index ac0ce1ef3d0a..a837f994cd90 100644 --- a/bundler/lib/bundler/lockfile_parser.rb +++ b/bundler/lib/bundler/lockfile_parser.rb @@ -28,6 +28,7 @@ def to_s attr_reader( :sources, + :metadata_source, :dependencies, :specs, :platforms, @@ -97,6 +98,7 @@ def self.bundled_with def initialize(lockfile, strict: false) @platforms = [] @sources = [] + @metadata_source = Source::Metadata.new @dependencies = {} @parse_method = nil @specs = {} @@ -252,7 +254,12 @@ def parse_checksum(line) version = Gem::Version.new(version) platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY full_name = Gem::NameTuple.new(name, version, platform).full_name - return unless spec = @specs[full_name] + spec = @specs[full_name] + + if name == "bundler" + spec ||= LazySpecification.new(name, version, platform, @metadata_source) + end + return unless spec if checksums checksums.split(",") do |lock_checksum| diff --git a/bundler/lib/bundler/source/metadata.rb b/bundler/lib/bundler/source/metadata.rb index fd959cd64ee2..ecf889518715 100644 --- a/bundler/lib/bundler/source/metadata.rb +++ b/bundler/lib/bundler/source/metadata.rb @@ -58,6 +58,10 @@ def hash def version_message(spec) "#{spec.name} #{spec.version}" end + + def checksum_store + @checksum_store ||= Checksum::Store.new + end end end end diff --git a/bundler/spec/commands/update_spec.rb b/bundler/spec/commands/update_spec.rb index cdaeb75c4a33..3fc6bd38e41a 100644 --- a/bundler/spec/commands/update_spec.rb +++ b/bundler/spec/commands/update_spec.rb @@ -1537,6 +1537,7 @@ checksums = checksums_section do |c| c.checksum(gem_repo4, "myrack", "1.0") + c.checksum(gem_repo4, "bundler", "999.0.0") end install_gemfile <<-G @@ -1621,6 +1622,7 @@ checksums = checksums_section do |c| c.checksum(gem_repo4, "myrack", "1.0") + c.checksum(gem_repo4, "bundler", "9.9.9") end install_gemfile <<-G @@ -1745,6 +1747,7 @@ # Only updates properly on modern RubyGems. checksums = checksums_section_when_enabled do |c| c.checksum(gem_repo4, "myrack", "1.0") + c.checksum(local_gem_path, "bundler", "9.0.0", Gem::Platform::RUBY, "cache") end expect(lockfile).to eq <<~L diff --git a/bundler/spec/support/checksums.rb b/bundler/spec/support/checksums.rb index cf8ea417d67a..03147bf6f463 100644 --- a/bundler/spec/support/checksums.rb +++ b/bundler/spec/support/checksums.rb @@ -14,9 +14,9 @@ def initialize_copy(original) @checksums = @checksums.dup end - def checksum(repo, name, version, platform = Gem::Platform::RUBY) + def checksum(repo, name, version, platform = Gem::Platform::RUBY, folder = "gems") name_tuple = Gem::NameTuple.new(name, version, platform) - gem_file = File.join(repo, "gems", "#{name_tuple.full_name}.gem") + gem_file = File.join(repo, folder, "#{name_tuple.full_name}.gem") File.open(gem_file, "rb") do |f| register(name_tuple, Bundler::Checksum.from_gem(f, "#{gem_file} (via ChecksumsBuilder#checksum)")) end