diff --git a/lib/bundler.rb b/lib/bundler.rb index ee08a2dab8..cc6c2c075c 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -39,6 +39,7 @@ module Bundler environment_preserver.replace_with_backup SUDO_MUTEX = Thread::Mutex.new + autoload :Checksum, File.expand_path("bundler/checksum", __dir__) autoload :Definition, File.expand_path("bundler/definition", __dir__) autoload :Dependency, File.expand_path("bundler/dependency", __dir__) autoload :Deprecate, File.expand_path("bundler/deprecate", __dir__) diff --git a/lib/bundler/checksum.rb b/lib/bundler/checksum.rb new file mode 100644 index 0000000000..2e0a80cac2 --- /dev/null +++ b/lib/bundler/checksum.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module Bundler + class Checksum + attr_reader :name, :version, :platform + attr_accessor :checksum + + SHA256 = /\Asha256-([a-z0-9]{64}|[A-Za-z0-9+\/=]{44})\z/.freeze + + def initialize(name, version, platform, checksum = nil) + @name = name + @version = version + @platform = platform || Gem::Platform::RUBY + @checksum = checksum + + if @checksum && @checksum !~ SHA256 + raise ArgumentError, "invalid checksum (#{@checksum})" + end + end + + def match_spec?(spec) + name == spec.name && + version == spec.version && + platform.to_s == spec.platform.to_s + end + + def to_lock + out = String.new + + if platform == Gem::Platform::RUBY + out << " #{name} (#{version})" + else + out << " #{name} (#{version}-#{platform})" + end + + out << " #{checksum}" if checksum + out << "\n" + + out + end + end +end diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index d9c2670d6d..6b066051d8 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -15,6 +15,7 @@ module Bundler :dependencies, :locked_deps, :locked_gems, + :locked_checksums, :platforms, :ruby_version, :lockfile, @@ -92,6 +93,7 @@ module Bundler @locked_bundler_version = @locked_gems.bundler_version @locked_ruby_version = @locked_gems.ruby_version @originally_locked_specs = SpecSet.new(@locked_gems.specs) + @locked_checksums = @locked_gems.checksums if unlock != true @locked_deps = @locked_gems.dependencies @@ -112,6 +114,7 @@ module Bundler @originally_locked_specs = @locked_specs @locked_sources = [] @locked_platforms = [] + @locked_checksums = [] end locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) } diff --git a/lib/bundler/endpoint_specification.rb b/lib/bundler/endpoint_specification.rb index 863544b1f9..4c41285043 100644 --- a/lib/bundler/endpoint_specification.rb +++ b/lib/bundler/endpoint_specification.rb @@ -104,6 +104,11 @@ module Bundler @remote_specification = spec end + def to_checksum + digest = "sha256-#{checksum}" if checksum + Bundler::Checksum.new(name, version, platform, digest) + end + private def _remote_specification diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index c9b161dc0e..b4aadb0b5c 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -76,6 +76,18 @@ module Bundler out end + #def materialize_for_checksum + #if @specification + #yield + #else + #materialize_for_installation + + #yield + + #@specification = nil + #end + #end + def materialize_for_installation source.local! @@ -134,6 +146,20 @@ module Bundler " #{source.revision[0..6]}" end + def to_checksum + return nil unless @specification + + # + # See comment about #ruby_platform_materializes_to_ruby_platform? + # If the old lockfile format is present where there is no specific + # platform, then we should skip locking checksums as it is not + # deterministic which platform variant is locked. + # + return nil unless ruby_platform_materializes_to_ruby_platform? + + @specification.to_checksum + end + private def use_exact_resolved_specifications? diff --git a/lib/bundler/lockfile_generator.rb b/lib/bundler/lockfile_generator.rb index f7ba51b3e6..11e8e3f103 100644 --- a/lib/bundler/lockfile_generator.rb +++ b/lib/bundler/lockfile_generator.rb @@ -19,6 +19,7 @@ module Bundler add_sources add_platforms add_dependencies + add_checksums add_locked_ruby_version add_bundled_with @@ -65,6 +66,24 @@ module Bundler end end + def add_checksums + out << "\nCHECKSUMS\n" + + definition.resolve.sort_by(&:full_name).each do |spec| + checksum = spec.to_checksum if spec.respond_to?(:to_checksum) + + #if spec.is_a?(LazySpecification) + #spec.materialize_for_checksum do + #checksum ||= spec.to_checksum if spec.respond_to?(:to_checksum) + #end + #end + + checksum ||= definition.locked_checksums.find {|c| c.match_spec?(spec) } + + out << checksum.to_lock if checksum + end + end + def add_locked_ruby_version return unless locked_ruby_version = definition.locked_ruby_version add_section("RUBY VERSION", locked_ruby_version.to_s) diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb index 31f57f14e8..fc331a928c 100644 --- a/lib/bundler/lockfile_parser.rb +++ b/lib/bundler/lockfile_parser.rb @@ -2,10 +2,11 @@ module Bundler class LockfileParser - attr_reader :sources, :dependencies, :specs, :platforms, :bundler_version, :ruby_version + attr_reader :sources, :dependencies, :specs, :platforms, :bundler_version, :ruby_version, :checksums BUNDLED = "BUNDLED WITH" DEPENDENCIES = "DEPENDENCIES" + CHECKSUMS = "CHECKSUMS" PLATFORMS = "PLATFORMS" RUBY = "RUBY VERSION" GIT = "GIT" @@ -21,6 +22,7 @@ module Bundler Gem::Version.create("1.10") => [BUNDLED].freeze, Gem::Version.create("1.12") => [RUBY].freeze, Gem::Version.create("1.13") => [PLUGIN].freeze, + Gem::Version.create("2.4.0") => [CHECKSUMS].freeze, }.freeze KNOWN_SECTIONS = SECTIONS_BY_VERSION_INTRODUCED.values.flatten!.freeze @@ -64,6 +66,7 @@ module Bundler @sources = [] @dependencies = {} @parse_method = nil + @checksums = [] @specs = {} if lockfile.match?(/<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|/) @@ -77,6 +80,8 @@ module Bundler parse_source(line) elsif line == DEPENDENCIES @parse_method = :parse_dependency + elsif line == CHECKSUMS + @parse_method = :parse_checksum elsif line == PLATFORMS @parse_method = :parse_platform elsif line == RUBY @@ -144,6 +149,7 @@ module Bundler (?:#{space}\(([^-]*) # Space, followed by version (?:-(.*))?\))? # Optional platform (!)? # Optional pinned marker + (?:#{space}(.*))? # Optional checksum $ # Line end /xo.freeze @@ -176,6 +182,21 @@ module Bundler @dependencies[dep.name] = dep end + def parse_checksum(line) + if line =~ NAME_VERSION + spaces = $1 + return unless spaces.size == 2 + name = $2 + version = $3 + platform = $4 + checksum = $6 + + version = Gem::Version.new(version) + platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY + @checksums << Bundler::Checksum.new(name, version, platform, checksum) + end + end + def parse_spec(line) return unless line =~ NAME_VERSION spaces = $1 diff --git a/spec/bundler/bundler/definition_spec.rb b/spec/bundler/bundler/definition_spec.rb index 59b958ae42..a5d244d3aa 100644 --- a/spec/bundler/bundler/definition_spec.rb +++ b/spec/bundler/bundler/definition_spec.rb @@ -77,6 +77,10 @@ RSpec.describe Bundler::Definition do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + #{checksum_for_repo_gem gem_repo1, "rack", "1.0.0"} + BUNDLED WITH #{Bundler::VERSION} G @@ -132,6 +136,10 @@ RSpec.describe Bundler::Definition do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + #{checksum_for_repo_gem gem_repo1, "rack", "1.0.0"} + BUNDLED WITH #{Bundler::VERSION} G @@ -159,6 +167,8 @@ RSpec.describe Bundler::Definition do DEPENDENCIES only_java + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} G @@ -185,6 +195,9 @@ RSpec.describe Bundler::Definition do DEPENDENCIES foo + CHECKSUMS + #{checksum_for_repo_gem gem_repo1, "foo", "1.0"} + BUNDLED WITH #{Bundler::VERSION} G diff --git a/spec/bundler/bundler/lockfile_parser_spec.rb b/spec/bundler/bundler/lockfile_parser_spec.rb index 30fbeac71a..0b8db36324 100644 --- a/spec/bundler/bundler/lockfile_parser_spec.rb +++ b/spec/bundler/bundler/lockfile_parser_spec.rb @@ -60,7 +60,7 @@ RSpec.describe Bundler::LockfileParser do it "returns the same as > 1.0" do expect(subject).to contain_exactly( - described_class::BUNDLED, described_class::RUBY, described_class::PLUGIN + described_class::BUNDLED, described_class::CHECKSUMS, described_class::RUBY, described_class::PLUGIN ) end end @@ -70,7 +70,7 @@ RSpec.describe Bundler::LockfileParser do it "returns the same as for the release version" do expect(subject).to contain_exactly( - described_class::RUBY, described_class::PLUGIN + described_class::CHECKSUMS, described_class::RUBY, described_class::PLUGIN ) end end diff --git a/spec/bundler/commands/check_spec.rb b/spec/bundler/commands/check_spec.rb index 99a858e9e9..7832a9d877 100644 --- a/spec/bundler/commands/check_spec.rb +++ b/spec/bundler/commands/check_spec.rb @@ -425,6 +425,10 @@ RSpec.describe "bundle check" do DEPENDENCIES depends_on_rack! + CHECKSUMS + #{checksum_for_repo_gem gem_repo4, "depends_on_rack", "1.0"} + #{checksum_for_repo_gem gem_repo4, "rack", "1.0"} + BUNDLED WITH #{Bundler::VERSION} L @@ -488,6 +492,11 @@ RSpec.describe "bundle check" do bundle-check-issue! dex-dispatch-engine! + CHECKSUMS + #{checksum_for_repo_gem gem_repo4, "awesome_print", "1.0"} + bundle-check-issue (9999) + #{checksum_for_repo_gem gem_repo2, "dex-dispatch-engine", "1.0"} + BUNDLED WITH #{Bundler::VERSION} L diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb index 92415bd9d5..d6ce92b6d5 100644 --- a/spec/bundler/commands/install_spec.rb +++ b/spec/bundler/commands/install_spec.rb @@ -543,6 +543,8 @@ RSpec.describe "bundle install with gem sources" do DEPENDENCIES + CHECKSUMS + RUBY VERSION #{Bundler::RubyVersion.system} @@ -567,6 +569,8 @@ RSpec.describe "bundle install with gem sources" do DEPENDENCIES + CHECKSUMS + RUBY VERSION #{Bundler::RubyVersion.system} @@ -888,16 +892,16 @@ RSpec.describe "bundle install with gem sources" do context "with missing platform specific gems in lockfile" do before do build_repo4 do - build_gem "racc", "1.5.2" + build_gem "racca", "1.5.2" build_gem "nokogiri", "1.12.4" do |s| s.platform = "x86_64-darwin" - s.add_runtime_dependency "racc", "~> 1.4" + s.add_runtime_dependency "racca", "~> 1.4" end build_gem "nokogiri", "1.12.4" do |s| s.platform = "x86_64-linux" - s.add_runtime_dependency "racc", "~> 1.4" + s.add_runtime_dependency "racca", "~> 1.4" end build_gem "crass", "1.0.6" @@ -916,6 +920,13 @@ RSpec.describe "bundle install with gem sources" do gem "loofah", "~> 2.12.0" G + checksums = construct_checksum_section do |c| + c.repo_gem gem_repo4, "crass", "1.0.6" + c.repo_gem gem_repo4, "loofah", "2.12.0" + c.repo_gem gem_repo4, "nokogiri", "1.12.4", "x86_64-darwin" + c.repo_gem gem_repo4, "racca", "1.5.2" + end + lockfile <<-L GEM remote: https://gem.repo4/ @@ -925,8 +936,8 @@ RSpec.describe "bundle install with gem sources" do crass (~> 1.0.2) nokogiri (>= 1.5.9) nokogiri (1.12.4-x86_64-darwin) - racc (~> 1.4) - racc (1.5.2) + racca (~> 1.4) + racca (1.5.2) PLATFORMS x86_64-darwin-20 @@ -935,6 +946,9 @@ RSpec.describe "bundle install with gem sources" do DEPENDENCIES loofah (~> 2.12.0) + CHECKSUMS + #{checksums} + RUBY VERSION #{Bundler::RubyVersion.system} @@ -950,6 +964,14 @@ RSpec.describe "bundle install with gem sources" do bundle "install", :artifice => "compact_index" end + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo4, "crass", "1.0.6" + c.repo_gem gem_repo4, "loofah", "2.12.0" + c.repo_gem gem_repo4, "nokogiri", "1.12.4", "x86_64-darwin" + c.repo_gem gem_repo4, "nokogiri", "1.12.4", "x86_64-linux" + c.repo_gem gem_repo4, "racca", "1.5.2" + end + expect(lockfile).to eq <<~L GEM remote: https://gem.repo4/ @@ -959,10 +981,10 @@ RSpec.describe "bundle install with gem sources" do crass (~> 1.0.2) nokogiri (>= 1.5.9) nokogiri (1.12.4-x86_64-darwin) - racc (~> 1.4) + racca (~> 1.4) nokogiri (1.12.4-x86_64-linux) - racc (~> 1.4) - racc (1.5.2) + racca (~> 1.4) + racca (1.5.2) PLATFORMS x86_64-darwin-20 @@ -971,6 +993,9 @@ RSpec.describe "bundle install with gem sources" do DEPENDENCIES loofah (~> 2.12.0) + CHECKSUMS + #{expected_checksums} + RUBY VERSION #{Bundler::RubyVersion.system} diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb index 7f2e24c086..ff387a5990 100644 --- a/spec/bundler/commands/lock_spec.rb +++ b/spec/bundler/commands/lock_spec.rb @@ -42,6 +42,8 @@ RSpec.describe "bundle lock" do rails weakling + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} L @@ -104,6 +106,8 @@ RSpec.describe "bundle lock" do DEPENDENCIES foo + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} L @@ -126,8 +130,58 @@ RSpec.describe "bundle lock" do bundle "install" bundle "lock --lockfile=lock" + expected_checksums = construct_checksum_section do |c| + c.repo_gem repo, "actionmailer", "2.3.2" + c.repo_gem repo, "actionpack", "2.3.2" + c.repo_gem repo, "activerecord", "2.3.2" + c.repo_gem repo, "activeresource", "2.3.2" + c.repo_gem repo, "activesupport", "2.3.2" + c.repo_gem repo, "foo", "1.0" + c.repo_gem repo, "rails", "2.3.2" + c.repo_gem repo, "rake", "13.0.1" + c.repo_gem repo, "weakling", "0.0.3" + end + + lockfile = strip_lockfile(<<-L) + GEM + remote: #{file_uri_for(repo)}/ + specs: + actionmailer (2.3.2) + activesupport (= 2.3.2) + actionpack (2.3.2) + activesupport (= 2.3.2) + activerecord (2.3.2) + activesupport (= 2.3.2) + activeresource (2.3.2) + activesupport (= 2.3.2) + activesupport (2.3.2) + foo (1.0) + rails (2.3.2) + actionmailer (= 2.3.2) + actionpack (= 2.3.2) + activerecord (= 2.3.2) + activeresource (= 2.3.2) + rake (= 13.0.1) + rake (13.0.1) + weakling (0.0.3) + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + foo + rails + weakling + + CHECKSUMS + #{expected_checksums} + + BUNDLED WITH + #{Bundler::VERSION} + L + expect(out).to match(/Writing lockfile to.+lock/) - expect(read_lockfile("lock")).to eq(@lockfile) + expect(read_lockfile("lock")).to eq(lockfile) end it "update specific gems using --update" do @@ -535,6 +589,8 @@ RSpec.describe "bundle lock" do gssapi mixlib-shellout + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} G @@ -564,6 +620,8 @@ RSpec.describe "bundle lock" do gssapi mixlib-shellout + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} G @@ -642,6 +700,8 @@ RSpec.describe "bundle lock" do DEPENDENCIES libv8 + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} G @@ -677,6 +737,10 @@ RSpec.describe "bundle lock" do DEPENDENCIES libv8 + CHECKSUMS + #{checksum_for_repo_gem gem_repo4, "libv8", "8.4.255.0", "x86_64-darwin-19"} + #{checksum_for_repo_gem gem_repo4, "libv8", "8.4.255.0", "x86_64-darwin-20"} + BUNDLED WITH #{Bundler::VERSION} G @@ -895,6 +959,8 @@ RSpec.describe "bundle lock" do DEPENDENCIES debug + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} L @@ -918,6 +984,8 @@ RSpec.describe "bundle lock" do DEPENDENCIES debug + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} L diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb index 84042709bf..eb578d4dff 100644 --- a/spec/bundler/commands/update_spec.rb +++ b/spec/bundler/commands/update_spec.rb @@ -290,6 +290,8 @@ RSpec.describe "bundle update" do countries country_select + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} L @@ -505,6 +507,11 @@ RSpec.describe "bundle update" do original_lockfile = lockfile + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo4, "activesupport", "6.0.4.1" + c.repo_gem gem_repo4, "tzinfo", "1.2.9" + end + expected_lockfile = <<~L GEM remote: #{file_uri_for(gem_repo4)}/ @@ -519,6 +526,9 @@ RSpec.describe "bundle update" do DEPENDENCIES activesupport (~> 6.0.0) + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} L @@ -535,7 +545,25 @@ RSpec.describe "bundle update" do lockfile original_lockfile bundle "lock --update" expect(the_bundle).to include_gems("activesupport 6.0.4.1", "tzinfo 1.2.9") - expect(lockfile).to eq(expected_lockfile) + expect(lockfile).to eq <<~L + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + activesupport (6.0.4.1) + tzinfo (~> 1.1) + tzinfo (1.2.9) + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + activesupport (~> 6.0.0) + + CHECKSUMS + + BUNDLED WITH + #{Bundler::VERSION} + L end end @@ -1128,6 +1156,8 @@ RSpec.describe "bundle update --ruby" do DEPENDENCIES + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} L @@ -1159,6 +1189,8 @@ RSpec.describe "bundle update --ruby" do DEPENDENCIES + CHECKSUMS + RUBY VERSION #{Bundler::RubyVersion.system} @@ -1199,6 +1231,8 @@ RSpec.describe "bundle update --ruby" do DEPENDENCIES + CHECKSUMS + RUBY VERSION ruby 2.1.4p222 @@ -1224,6 +1258,8 @@ RSpec.describe "bundle update --ruby" do DEPENDENCIES + CHECKSUMS + RUBY VERSION #{Bundler::RubyVersion.system} @@ -1246,6 +1282,10 @@ RSpec.describe "bundle update --bundler" do G lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, '\11.0.0\2') + excepted_checksum = checksum_for_repo_gem(gem_repo4, "rack", "1.0") + + FileUtils.rm_r gem_repo4 + bundle :update, :bundler => true, :artifice => "compact_index", :verbose => true expect(out).to include("Using bundler #{Bundler::VERSION}") @@ -1261,6 +1301,9 @@ RSpec.describe "bundle update --bundler" do DEPENDENCIES rack + CHECKSUMS + #{excepted_checksum} + BUNDLED WITH #{Bundler::VERSION} L @@ -1296,6 +1339,9 @@ RSpec.describe "bundle update --bundler" do DEPENDENCIES rack + CHECKSUMS + #{checksum_for_repo_gem(gem_repo4, "rack", "1.0")} + BUNDLED WITH #{Bundler::VERSION} L @@ -1399,6 +1445,9 @@ RSpec.describe "bundle update --bundler" do DEPENDENCIES rack + CHECKSUMS + #{checksum_for_repo_gem(gem_repo4, "rack", "1.0")} + BUNDLED WITH 2.3.0.dev L @@ -1438,6 +1487,9 @@ RSpec.describe "bundle update --bundler" do DEPENDENCIES rack + CHECKSUMS + #{checksum_for_repo_gem(gem_repo4, "rack", "1.0")} + BUNDLED WITH 2.3.9 L @@ -1628,6 +1680,8 @@ RSpec.describe "bundle update conservative" do shared_owner_a shared_owner_b + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} L @@ -1681,6 +1735,8 @@ RSpec.describe "bundle update conservative" do shared_owner_a shared_owner_b + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} L diff --git a/spec/bundler/install/gemfile/gemspec_spec.rb b/spec/bundler/install/gemfile/gemspec_spec.rb index bed1d7fe04..23f1a05c10 100644 --- a/spec/bundler/install/gemfile/gemspec_spec.rb +++ b/spec/bundler/install/gemfile/gemspec_spec.rb @@ -448,6 +448,12 @@ RSpec.describe "bundle install from an existing gemspec" do context "as a runtime dependency" do it "keeps all platform dependencies in the lockfile" do expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 RUBY" + + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "platform_specific", "1.0" + c.repo_gem gem_repo2, "platform_specific", "1.0", x64_mingw32 + end + expect(lockfile).to eq <<~L PATH remote: . @@ -470,6 +476,10 @@ RSpec.describe "bundle install from an existing gemspec" do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} L @@ -481,6 +491,12 @@ RSpec.describe "bundle install from an existing gemspec" do it "keeps all platform dependencies in the lockfile" do expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 RUBY" + + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "platform_specific", "1.0" + c.repo_gem gem_repo2, "platform_specific", "1.0", x64_mingw32 + end + expect(lockfile).to eq <<~L PATH remote: . @@ -503,6 +519,10 @@ RSpec.describe "bundle install from an existing gemspec" do foo! platform_specific + CHECKSUMS + foo (1.0) + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} L @@ -515,6 +535,13 @@ RSpec.describe "bundle install from an existing gemspec" do it "keeps all platform dependencies in the lockfile" do expect(the_bundle).to include_gems "foo 1.0", "indirect_platform_specific 1.0", "platform_specific 1.0 RUBY" + + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "indirect_platform_specific", "1.0" + c.repo_gem gem_repo2, "platform_specific", "1.0" + c.repo_gem gem_repo2, "platform_specific", "1.0", x64_mingw32 + end + expect(lockfile).to eq <<~L PATH remote: . @@ -539,6 +566,10 @@ RSpec.describe "bundle install from an existing gemspec" do foo! indirect_platform_specific + CHECKSUMS + foo (1.0) + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} L @@ -623,6 +654,11 @@ RSpec.describe "bundle install from an existing gemspec" do DEPENDENCIES chef! + CHECKSUMS + chef (17.1.17) + chef (17.1.17-universal-mingw32) + #{checksum_for_repo_gem gem_repo4, "win32-api", "1.5.3", "universal-mingw32"} + BUNDLED WITH #{Bundler::VERSION} L @@ -680,6 +716,10 @@ RSpec.describe "bundle install from an existing gemspec" do activeadmin! jruby-openssl + CHECKSUMS + activeadmin (2.9.0) + #{checksum_for_repo_gem gem_repo4, "railties", "6.1.4"} + BUNDLED WITH #{Bundler::VERSION} L diff --git a/spec/bundler/install/gemfile/install_if_spec.rb b/spec/bundler/install/gemfile/install_if_spec.rb index 3d2d15a698..441b309afe 100644 --- a/spec/bundler/install/gemfile/install_if_spec.rb +++ b/spec/bundler/install/gemfile/install_if_spec.rb @@ -37,6 +37,10 @@ RSpec.describe "bundle install with install_if conditionals" do rack thin + CHECKSUMS + #{checksum_for_repo_gem gem_repo1, "activesupport", "2.3.5"} + #{checksum_for_repo_gem gem_repo1, "rack", "1.0.0"} + BUNDLED WITH #{Bundler::VERSION} L diff --git a/spec/bundler/install/gemfile/path_spec.rb b/spec/bundler/install/gemfile/path_spec.rb index a5207036c3..086d6c3ed1 100644 --- a/spec/bundler/install/gemfile/path_spec.rb +++ b/spec/bundler/install/gemfile/path_spec.rb @@ -120,6 +120,10 @@ RSpec.describe "bundle install with explicit source paths" do aaa! demo! + CHECKSUMS + aaa (1.0) + demo (1.0) + BUNDLED WITH #{Bundler::VERSION} L @@ -359,6 +363,10 @@ RSpec.describe "bundle install with explicit source paths" do DEPENDENCIES foo! + CHECKSUMS + foo (0.1.0) + #{checksum_for_repo_gem gem_repo4, "graphql", "2.0.15"} + BUNDLED WITH #{Bundler::VERSION} L @@ -683,6 +691,10 @@ RSpec.describe "bundle install with explicit source paths" do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + #{checksum_for_repo_gem gem_repo1, "rack", "0.9.1"} + BUNDLED WITH #{Bundler::VERSION} G @@ -711,6 +723,10 @@ RSpec.describe "bundle install with explicit source paths" do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + #{checksum_for_repo_gem gem_repo1, "rack", "0.9.1"} + BUNDLED WITH #{Bundler::VERSION} G @@ -745,6 +761,10 @@ RSpec.describe "bundle install with explicit source paths" do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + #{checksum_for_repo_gem gem_repo1, "rack", "0.9.1"} + BUNDLED WITH #{Bundler::VERSION} G @@ -776,6 +796,11 @@ RSpec.describe "bundle install with explicit source paths" do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + #{checksum_for_repo_gem gem_repo1, "rack", "0.9.1"} + #{checksum_for_repo_gem gem_repo1, "rake", "13.0.1"} + BUNDLED WITH #{Bundler::VERSION} G diff --git a/spec/bundler/install/gemfile/platform_spec.rb b/spec/bundler/install/gemfile/platform_spec.rb index d28c7b781f..3992d11458 100644 --- a/spec/bundler/install/gemfile/platform_spec.rb +++ b/spec/bundler/install/gemfile/platform_spec.rb @@ -225,6 +225,8 @@ RSpec.describe "bundle install across platforms" do empyrean (= 0.1.0) pry + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} L @@ -257,6 +259,8 @@ RSpec.describe "bundle install across platforms" do empyrean (= 0.1.0) pry + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} L @@ -290,6 +294,8 @@ RSpec.describe "bundle install across platforms" do empyrean (= 0.1.0) pry + CHECKSUMS + BUNDLED WITH 1.16.1 L @@ -399,6 +405,9 @@ RSpec.describe "bundle install across platforms" do DEPENDENCIES platform_specific + CHECKSUMS + #{checksum_for_repo_gem(gem_repo1, "platform_specific", "1.0")} + BUNDLED WITH #{Bundler::VERSION} G @@ -568,6 +577,8 @@ RSpec.describe "bundle install with platform conditionals" do DEPENDENCIES rack + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} L diff --git a/spec/bundler/install/gemfile/sources_spec.rb b/spec/bundler/install/gemfile/sources_spec.rb index 8cb0476821..40c4bebdd3 100644 --- a/spec/bundler/install/gemfile/sources_spec.rb +++ b/spec/bundler/install/gemfile/sources_spec.rb @@ -284,6 +284,11 @@ RSpec.describe "bundle install with gems on multiple sources" do expect(err).to include("Warning: the gem 'rack' was found in multiple sources.") expect(err).to include("Installed from: https://gem.repo2") + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo3, "depends_on_rack", "1.0.1" + c.repo_gem gem_repo2, "rack", "1.0.0" + end + expect(lockfile).to eq <<~L GEM remote: https://gem.repo1/ @@ -303,6 +308,9 @@ RSpec.describe "bundle install with gems on multiple sources" do DEPENDENCIES depends_on_rack! + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} L @@ -698,6 +706,21 @@ RSpec.describe "bundle install with gems on multiple sources" do expect(the_bundle).to include_gems("concurrent-ruby 1.1.8") expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.9") + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "activesupport", "6.0.3.4" + c.repo_gem gem_repo2, "concurrent-ruby", "1.1.8" + c.repo_gem gem_repo2, "connection_pool", "2.2.3" + c.repo_gem gem_repo2, "i18n", "1.8.9" + c.repo_gem gem_repo2, "minitest", "5.14.3" + c.repo_gem gem_repo2, "rack", "2.2.3" + c.repo_gem gem_repo2, "redis", "4.2.5" + c.repo_gem gem_repo2, "sidekiq", "6.1.3" + c.repo_gem gem_repo3, "sidekiq-pro", "5.2.1" + c.repo_gem gem_repo2, "thread_safe", "0.3.6" + c.repo_gem gem_repo2, "tzinfo", "1.2.9" + c.repo_gem gem_repo2, "zeitwerk", "2.4.2" + end + expect(lockfile).to eq <<~L GEM remote: https://gem.repo2/ @@ -738,6 +761,9 @@ RSpec.describe "bundle install with gems on multiple sources" do activesupport sidekiq-pro! + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} L @@ -783,6 +809,20 @@ RSpec.describe "bundle install with gems on multiple sources" do expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8") expect(the_bundle).to include_gems("concurrent-ruby 1.1.9") + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "activesupport", "6.1.2.1" + c.repo_gem gem_repo2, "concurrent-ruby", "1.1.9" + c.repo_gem gem_repo2, "connection_pool", "2.2.3" + c.repo_gem gem_repo2, "i18n", "1.8.9" + c.repo_gem gem_repo2, "minitest", "5.14.3" + c.repo_gem gem_repo2, "rack", "2.2.3" + c.repo_gem gem_repo2, "redis", "4.2.5" + c.repo_gem gem_repo2, "sidekiq", "6.1.3" + c.repo_gem gem_repo3, "sidekiq-pro", "5.2.1" + c.repo_gem gem_repo2, "tzinfo", "2.0.4" + c.repo_gem gem_repo2, "zeitwerk", "2.4.2" + end + expect(lockfile).to eq <<~L GEM remote: https://gem.repo2/ @@ -822,6 +862,9 @@ RSpec.describe "bundle install with gems on multiple sources" do activesupport sidekiq-pro! + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} L @@ -838,6 +881,21 @@ RSpec.describe "bundle install with gems on multiple sources" do expect(the_bundle).to include_gems("concurrent-ruby 1.1.9") expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8") + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "activesupport", "6.0.3.4" + c.repo_gem gem_repo2, "concurrent-ruby", "1.1.9" + c.repo_gem gem_repo2, "connection_pool", "2.2.3" + c.repo_gem gem_repo2, "i18n", "1.8.9" + c.repo_gem gem_repo2, "minitest", "5.14.3" + c.repo_gem gem_repo2, "rack", "2.2.3" + c.repo_gem gem_repo2, "redis", "4.2.5" + c.repo_gem gem_repo2, "sidekiq", "6.1.3" + c.repo_gem gem_repo3, "sidekiq-pro", "5.2.1" + c.repo_gem gem_repo2, "thread_safe", "0.3.6" + c.repo_gem gem_repo2, "tzinfo", "1.2.9" + c.repo_gem gem_repo2, "zeitwerk", "2.4.2" + end + expect(lockfile).to eq <<~L GEM remote: https://gem.repo2/ @@ -878,6 +936,9 @@ RSpec.describe "bundle install with gems on multiple sources" do activesupport sidekiq-pro! + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} L @@ -945,6 +1006,12 @@ RSpec.describe "bundle install with gems on multiple sources" do end it "installs from the default source without any warnings or errors and generates a proper lockfile" do + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo3, "handsoap", "0.2.5.5" + c.repo_gem gem_repo2, "nokogiri", "1.11.1" + c.repo_gem gem_repo2, "racca", "1.5.2" + end + expected_lockfile = <<~L GEM remote: https://gem.repo2/ @@ -966,6 +1033,9 @@ RSpec.describe "bundle install with gems on multiple sources" do handsoap! nokogiri + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} L @@ -1489,6 +1559,8 @@ RSpec.describe "bundle install with gems on multiple sources" do DEPENDENCIES capybara (~> 2.5.0) mime-types (~> 3.0)! + + CHECKSUMS L end @@ -1514,6 +1586,8 @@ RSpec.describe "bundle install with gems on multiple sources" do capybara (~> 2.5.0) mime-types (~> 3.0)! + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} L @@ -1567,6 +1641,10 @@ RSpec.describe "bundle install with gems on multiple sources" do DEPENDENCIES ruport (= 1.7.0.3)! + CHECKSUMS + #{checksum_for_repo_gem gem_repo4, "pdf-writer", "1.1.8"} + #{checksum_for_repo_gem gem_repo2, "ruport", "1.7.0.3"} + BUNDLED WITH #{Bundler::VERSION} L @@ -1602,6 +1680,11 @@ RSpec.describe "bundle install with gems on multiple sources" do it "handles that fine" do bundle "install", :artifice => "compact_index_extra", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo4, "pdf-writer", "1.1.8" + c.repo_gem gem_repo2, "ruport", "1.7.0.3" + end + expect(lockfile).to eq <<~L GEM remote: https://localgemserver.test/ @@ -1620,6 +1703,9 @@ RSpec.describe "bundle install with gems on multiple sources" do DEPENDENCIES ruport (= 1.7.0.3)! + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} L @@ -1649,6 +1735,10 @@ RSpec.describe "bundle install with gems on multiple sources" do it "handles that fine" do bundle "install --verbose", :artifice => "endpoint", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo4, "pdf-writer", "1.1.8" + end + expect(lockfile).to eq <<~L GEM remote: https://localgemserver.test/ @@ -1661,6 +1751,9 @@ RSpec.describe "bundle install with gems on multiple sources" do DEPENDENCIES pdf-writer (= 1.1.8) + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} L diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb index 30bf50c48e..6938507dd5 100644 --- a/spec/bundler/install/gemfile/specific_platform_spec.rb +++ b/spec/bundler/install/gemfile/specific_platform_spec.rb @@ -101,6 +101,8 @@ RSpec.describe "bundle install with specific platforms" do DEPENDENCIES google-protobuf + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} L @@ -522,6 +524,13 @@ RSpec.describe "bundle install with specific platforms" do bundle "update" + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo4, "sorbet", "0.5.10160" + c.repo_gem gem_repo4, "sorbet-runtime", "0.5.10160" + c.repo_gem gem_repo4, "sorbet-static", "0.5.10160", Gem::Platform.local + c.repo_gem gem_repo4, "sorbet-static-and-runtime", "0.5.10160" + end + expect(lockfile).to eq <<~L GEM remote: #{file_uri_for(gem_repo4)}/ @@ -540,6 +549,9 @@ RSpec.describe "bundle install with specific platforms" do DEPENDENCIES sorbet-static-and-runtime + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} L @@ -662,6 +674,13 @@ RSpec.describe "bundle install with specific platforms" do bundle "update" + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo4, "sorbet", "0.5.10160" + c.repo_gem gem_repo4, "sorbet-runtime", "0.5.10160" + c.repo_gem gem_repo4, "sorbet-static", "0.5.10160", Gem::Platform.local + c.repo_gem gem_repo4, "sorbet-static-and-runtime", "0.5.10160" + end + expect(lockfile).to eq <<~L GEM remote: #{file_uri_for(gem_repo4)}/ @@ -680,6 +699,9 @@ RSpec.describe "bundle install with specific platforms" do DEPENDENCIES sorbet-static-and-runtime + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} L @@ -836,6 +858,8 @@ RSpec.describe "bundle install with specific platforms" do nokogiri tzinfo (~> 1.2) + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} L diff --git a/spec/bundler/install/gems/compact_index_spec.rb b/spec/bundler/install/gems/compact_index_spec.rb index 1d193a0f20..20e3d93175 100644 --- a/spec/bundler/install/gems/compact_index_spec.rb +++ b/spec/bundler/install/gems/compact_index_spec.rb @@ -949,6 +949,6 @@ Running `bundle update rails` should fix the problem. G gem_command "uninstall activemerchant" bundle "update rails", :artifice => "compact_index" - expect(lockfile.scan(/activemerchant \(/).size).to eq(1) + expect(lockfile.scan(/activemerchant \(/).size).to eq(2) # Once in the specs, and once in CHECKSUMS end end diff --git a/spec/bundler/install/gems/flex_spec.rb b/spec/bundler/install/gems/flex_spec.rb index ddb9480343..484ec1f839 100644 --- a/spec/bundler/install/gems/flex_spec.rb +++ b/spec/bundler/install/gems/flex_spec.rb @@ -283,6 +283,10 @@ RSpec.describe "bundle flex_install" do rack (= 0.9.1) rack-obama + CHECKSUMS + #{checksum_for_repo_gem gem_repo1, "rack", "0.9.1"} + #{checksum_for_repo_gem gem_repo1, "rack-obama", "1.0"} + BUNDLED WITH #{Bundler::VERSION} L @@ -324,6 +328,9 @@ RSpec.describe "bundle flex_install" do DEPENDENCIES rack + CHECKSUMS + #{checksum_for_repo_gem gem_repo1, "rack", "1.0.0"} + BUNDLED WITH #{Bundler::VERSION} L diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb index cf42b8a979..b9f928a0db 100644 --- a/spec/bundler/install/gems/resolving_spec.rb +++ b/spec/bundler/install/gems/resolving_spec.rb @@ -288,6 +288,9 @@ RSpec.describe "bundle install with install-time dependencies" do DEPENDENCIES parallel_tests + CHECKSUMS + #{checksum_for_repo_gem gem_repo2, "parallel_tests", "3.7.0"} + BUNDLED WITH #{Bundler::VERSION} L @@ -368,6 +371,10 @@ RSpec.describe "bundle install with install-time dependencies" do DEPENDENCIES rubocop + CHECKSUMS + #{checksum_for_repo_gem gem_repo2, "rubocop", "1.28.2"} + #{checksum_for_repo_gem gem_repo2, "rubocop-ast", "1.17.0"} + BUNDLED WITH #{Bundler::VERSION} L diff --git a/spec/bundler/install/yanked_spec.rb b/spec/bundler/install/yanked_spec.rb index dc054b50bb..930e3c4791 100644 --- a/spec/bundler/install/yanked_spec.rb +++ b/spec/bundler/install/yanked_spec.rb @@ -160,6 +160,8 @@ RSpec.context "when resolving a bundle that includes yanked gems, but unlocking bar foo + CHECKSUMS + BUNDLED WITH #{Bundler::VERSION} L diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb index 5a236dd5d2..0f0169062e 100644 --- a/spec/bundler/lock/lockfile_spec.rb +++ b/spec/bundler/lock/lockfile_spec.rb @@ -24,6 +24,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rack + CHECKSUMS + #{checksum_for_repo_gem(gem_repo2, "rack", "1.0.0")} + BUNDLED WITH #{Bundler::VERSION} G @@ -75,6 +78,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rack + CHECKSUMS + #{checksum_for_repo_gem(gem_repo2, "rack", "1.0.0")} + BUNDLED WITH #{Bundler::VERSION} G @@ -202,6 +208,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rack (> 0) + CHECKSUMS + #{checksum_for_repo_gem(gem_repo2, "rack", "1.0.0")} + BUNDLED WITH #{Bundler::VERSION} G @@ -249,6 +258,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rack + CHECKSUMS + #{checksum_for_repo_gem(gem_repo2, "rack", "1.0.0")} + BUNDLED WITH #{current_version} G @@ -261,6 +273,11 @@ RSpec.describe "the lockfile format" do gem "rack-obama" G + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "rack", "1.0.0" + c.repo_gem gem_repo2, "rack-obama", "1.0" + end + expect(lockfile).to eq <<~G GEM remote: #{file_uri_for(gem_repo2)}/ @@ -275,6 +292,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rack-obama + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} G @@ -287,6 +307,11 @@ RSpec.describe "the lockfile format" do gem "rack-obama", ">= 1.0" G + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "rack", "1.0.0" + c.repo_gem gem_repo2, "rack-obama", "1.0" + end + expect(lockfile).to eq <<~G GEM remote: #{file_uri_for(gem_repo2)}/ @@ -301,6 +326,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rack-obama (>= 1.0) + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} G @@ -321,6 +349,11 @@ RSpec.describe "the lockfile format" do end G + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "rack", "1.0.0" + c.repo_gem gem_repo2, "rack-obama", "1.0" + end + expect(lockfile).to eq <<~G GEM remote: #{file_uri_for(gem_repo1)}/ @@ -343,6 +376,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rack-obama (>= 1.0)! + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} G @@ -354,6 +390,11 @@ RSpec.describe "the lockfile format" do gem "net-sftp" G + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "net-sftp", "1.1.1" + c.repo_gem gem_repo2, "net-ssh", "1.0" + end + expect(lockfile).to eq <<~G GEM remote: #{file_uri_for(gem_repo2)}/ @@ -368,6 +409,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES net-sftp + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} G @@ -400,6 +444,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + BUNDLED WITH #{Bundler::VERSION} G @@ -471,6 +518,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + BUNDLED WITH #{Bundler::VERSION} G @@ -503,6 +553,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + BUNDLED WITH #{Bundler::VERSION} G @@ -535,6 +588,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + BUNDLED WITH #{Bundler::VERSION} G @@ -650,6 +706,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + BUNDLED WITH #{Bundler::VERSION} G @@ -683,6 +742,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + BUNDLED WITH #{Bundler::VERSION} G @@ -725,6 +787,11 @@ RSpec.describe "the lockfile format" do foo! rack + CHECKSUMS + bar (1.0) + foo (1.0) + #{checksum_for_repo_gem gem_repo2, "rack", "1.0.0"} + BUNDLED WITH #{Bundler::VERSION} G @@ -737,6 +804,10 @@ RSpec.describe "the lockfile format" do gem "rack", :source => "#{file_uri_for(gem_repo2)}/" G + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "rack", "1.0.0" + end + expect(lockfile).to eq <<~G GEM remote: #{file_uri_for(gem_repo2)}/ @@ -749,6 +820,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rack! + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} G @@ -763,6 +837,14 @@ RSpec.describe "the lockfile format" do gem "rack-obama" G + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "actionpack", "2.3.2" + c.repo_gem gem_repo2, "activesupport", "2.3.2" + c.repo_gem gem_repo2, "rack", "1.0.0" + c.repo_gem gem_repo2, "rack-obama", "1.0" + c.repo_gem gem_repo2, "thin", "1.0" + end + expect(lockfile).to eq <<~G GEM remote: #{file_uri_for(gem_repo2)}/ @@ -784,6 +866,9 @@ RSpec.describe "the lockfile format" do rack-obama thin + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} G @@ -796,6 +881,16 @@ RSpec.describe "the lockfile format" do gem "rails" G + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "actionmailer", "2.3.2" + c.repo_gem gem_repo2, "actionpack", "2.3.2" + c.repo_gem gem_repo2, "activerecord", "2.3.2" + c.repo_gem gem_repo2, "activeresource", "2.3.2" + c.repo_gem gem_repo2, "activesupport", "2.3.2" + c.repo_gem gem_repo2, "rails", "2.3.2" + c.repo_gem gem_repo2, "rake", "13.0.1" + end + expect(lockfile).to eq <<~G GEM remote: #{file_uri_for(gem_repo2)}/ @@ -823,6 +918,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rails + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} G @@ -844,6 +942,11 @@ RSpec.describe "the lockfile format" do gem 'double_deps' G + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "double_deps", "1.0" + c.repo_gem gem_repo2, "net-ssh", "1.0" + end + expect(lockfile).to eq <<~G GEM remote: #{file_uri_for(gem_repo2)}/ @@ -859,6 +962,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES double_deps + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} G @@ -871,6 +977,11 @@ RSpec.describe "the lockfile format" do gem "rack-obama", ">= 1.0", :require => "rack/obama" G + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "rack", "1.0.0" + c.repo_gem gem_repo2, "rack-obama", "1.0" + end + expect(lockfile).to eq <<~G GEM remote: #{file_uri_for(gem_repo2)}/ @@ -885,6 +996,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rack-obama (>= 1.0) + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} G @@ -897,6 +1011,11 @@ RSpec.describe "the lockfile format" do gem "rack-obama", ">= 1.0", :group => :test G + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "rack", "1.0.0" + c.repo_gem gem_repo2, "rack-obama", "1.0" + end + expect(lockfile).to eq <<~G GEM remote: #{file_uri_for(gem_repo2)}/ @@ -911,6 +1030,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rack-obama (>= 1.0) + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} G @@ -942,6 +1064,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + BUNDLED WITH #{Bundler::VERSION} G @@ -973,6 +1098,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + BUNDLED WITH #{Bundler::VERSION} G @@ -1004,6 +1132,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + BUNDLED WITH #{Bundler::VERSION} G @@ -1033,6 +1164,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES foo! + CHECKSUMS + foo (1.0) + BUNDLED WITH #{Bundler::VERSION} G @@ -1073,6 +1207,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rack + CHECKSUMS + #{checksum_for_repo_gem(gem_repo2, "rack", "1.0.0")} + BUNDLED WITH #{Bundler::VERSION} G @@ -1092,6 +1229,10 @@ RSpec.describe "the lockfile format" do gem "platform_specific" G + expected_checksums = construct_checksum_section do |c| + c.repo_gem gem_repo2, "platform_specific", "1.0", "universal-java-16" + end + expect(lockfile).to eq <<~G GEM remote: #{file_uri_for(gem_repo2)}/ @@ -1104,6 +1245,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES platform_specific + CHECKSUMS + #{expected_checksums} + BUNDLED WITH #{Bundler::VERSION} G @@ -1135,6 +1279,10 @@ RSpec.describe "the lockfile format" do activesupport rack + CHECKSUMS + #{checksum_for_repo_gem(gem_repo2, "activesupport", "2.3.5")} + #{checksum_for_repo_gem(gem_repo2, "rack", "1.0.0")} + BUNDLED WITH #{Bundler::VERSION} G @@ -1159,6 +1307,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rack + CHECKSUMS + #{checksum_for_repo_gem(gem_repo2, "rack", "1.0.0")} + BUNDLED WITH #{Bundler::VERSION} G @@ -1183,6 +1334,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rack (= 1.0) + CHECKSUMS + #{checksum_for_repo_gem(gem_repo2, "rack", "1.0.0")} + BUNDLED WITH #{Bundler::VERSION} G @@ -1207,6 +1361,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rack (= 1.0) + CHECKSUMS + #{checksum_for_repo_gem(gem_repo2, "rack", "1.0.0")} + BUNDLED WITH #{Bundler::VERSION} G @@ -1252,6 +1409,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rack (> 0.9, < 1.0) + CHECKSUMS + #{checksum_for_repo_gem(gem_repo2, "rack", "0.9.1")} + BUNDLED WITH #{Bundler::VERSION} G @@ -1276,6 +1436,9 @@ RSpec.describe "the lockfile format" do DEPENDENCIES rack (> 0.9, < 1.0) + CHECKSUMS + #{checksum_for_repo_gem(gem_repo2, "rack", "0.9.1")} + RUBY VERSION #{Bundler::RubyVersion.system} @@ -1473,6 +1636,10 @@ RSpec.describe "the lockfile format" do DEPENDENCIES minitest-bisect + CHECKSUMS + #{checksum_for_repo_gem gem_repo4, "minitest-bisect", "1.6.0"} + #{checksum_for_repo_gem gem_repo4, "path_expander", "1.1.1"} + BUNDLED WITH #{Bundler::VERSION} L diff --git a/spec/bundler/plugins/source/example_spec.rb b/spec/bundler/plugins/source/example_spec.rb index 9d153b6063..993a890b6c 100644 --- a/spec/bundler/plugins/source/example_spec.rb +++ b/spec/bundler/plugins/source/example_spec.rb @@ -87,6 +87,9 @@ RSpec.describe "real source plugins" do DEPENDENCIES a-path-gem! + CHECKSUMS + a-path-gem (1.0) + BUNDLED WITH #{Bundler::VERSION} G @@ -354,6 +357,9 @@ RSpec.describe "real source plugins" do DEPENDENCIES ma-gitp-gem! + CHECKSUMS + ma-gitp-gem (1.0) + BUNDLED WITH #{Bundler::VERSION} G diff --git a/spec/bundler/runtime/platform_spec.rb b/spec/bundler/runtime/platform_spec.rb index b31bc4abe8..d0af8b1c1c 100644 --- a/spec/bundler/runtime/platform_spec.rb +++ b/spec/bundler/runtime/platform_spec.rb @@ -61,16 +61,16 @@ RSpec.describe "Bundler.setup with multi platform stuff" do build_repo4 do build_gem "nokogiri", "1.11.1" do |s| s.add_dependency "mini_portile2", "~> 2.5.0" - s.add_dependency "racc", "~> 1.5.2" + s.add_dependency "racca", "~> 1.5.2" end build_gem "nokogiri", "1.11.1" do |s| s.platform = Bundler.local_platform - s.add_dependency "racc", "~> 1.4" + s.add_dependency "racca", "~> 1.4" end build_gem "mini_portile2", "2.5.0" - build_gem "racc", "1.5.2" + build_gem "racca", "1.5.2" end good_lockfile = <<~L @@ -80,10 +80,10 @@ RSpec.describe "Bundler.setup with multi platform stuff" do mini_portile2 (2.5.0) nokogiri (1.11.1) mini_portile2 (~> 2.5.0) - racc (~> 1.5.2) + racca (~> 1.5.2) nokogiri (1.11.1-#{Bundler.local_platform}) - racc (~> 1.4) - racc (1.5.2) + racca (~> 1.4) + racca (1.5.2) PLATFORMS #{lockfile_platforms("ruby")} @@ -91,6 +91,11 @@ RSpec.describe "Bundler.setup with multi platform stuff" do DEPENDENCIES nokogiri (~> 1.11) + CHECKSUMS + nokogiri (1.11.1) + #{checksum_for_repo_gem gem_repo4, "nokogiri", "1.11.1", Bundler.local_platform} + #{checksum_for_repo_gem gem_repo4, "racca", "1.5.2"} + BUNDLED WITH #{Bundler::VERSION} L diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb index d4234d684f..3abbea449b 100644 --- a/spec/bundler/runtime/setup_spec.rb +++ b/spec/bundler/runtime/setup_spec.rb @@ -1227,6 +1227,9 @@ end DEPENDENCIES rack + + CHECKSUMS + #{checksum_for_repo_gem gem_repo1, "rack", "1.0.0"} L if ruby_version diff --git a/spec/bundler/spec_helper.rb b/spec/bundler/spec_helper.rb index d3a92d84b2..3001dd279a 100644 --- a/spec/bundler/spec_helper.rb +++ b/spec/bundler/spec_helper.rb @@ -17,6 +17,7 @@ require "rspec/support/differ" require_relative "support/builders" require_relative "support/build_metadata" +require_relative "support/checksums" require_relative "support/filters" require_relative "support/helpers" require_relative "support/indexes" @@ -34,6 +35,7 @@ end RSpec.configure do |config| config.include Spec::Builders + config.include Spec::Checksums config.include Spec::Helpers config.include Spec::Indexes config.include Spec::Matchers diff --git a/spec/bundler/support/artifice/helpers/compact_index.rb b/spec/bundler/support/artifice/helpers/compact_index.rb index 4df47a9659..ef507ca12d 100644 --- a/spec/bundler/support/artifice/helpers/compact_index.rb +++ b/spec/bundler/support/artifice/helpers/compact_index.rb @@ -80,7 +80,7 @@ class CompactIndexAPI < Endpoint CompactIndex::Dependency.new(d.name, reqs) end checksum = begin - Digest(:SHA256).file("#{gem_repo}/gems/#{spec.original_name}.gem").base64digest + Digest(:SHA256).file("#{gem_repo}/gems/#{spec.original_name}.gem").hexdigest rescue StandardError nil end diff --git a/spec/bundler/support/checksums.rb b/spec/bundler/support/checksums.rb new file mode 100644 index 0000000000..3594b93518 --- /dev/null +++ b/spec/bundler/support/checksums.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Spec + module Checksums + class ChecksumsBuilder + def initialize + @checksums = [] + end + + def repo_gem(gem_repo, gem_name, gem_version, platform = nil) + gem_file = if platform + "#{gem_repo}/gems/#{gem_name}-#{gem_version}-#{platform}.gem" + else + "#{gem_repo}/gems/#{gem_name}-#{gem_version}.gem" + end + + checksum = sha256_checksum(gem_file) + @checksums << Bundler::Checksum.new(gem_name, gem_version, platform, checksum) + end + + def to_lock + @checksums.map(&:to_lock).join.strip + end + + private + + def sha256_checksum(file) + File.open(file) do |f| + digest = Bundler::SharedHelpers.digest(:SHA256).new + digest << f.read(16_384) until f.eof? + + "sha256-#{digest.hexdigest!}" + end + end + end + + def construct_checksum_section + checksums = ChecksumsBuilder.new + + yield checksums + + checksums.to_lock + end + + def checksum_for_repo_gem(gem_repo, gem_name, gem_version, platform = nil) + construct_checksum_section do |c| + c.repo_gem(gem_repo, gem_name, gem_version, platform) + end + end + end +end diff --git a/spec/bundler/update/git_spec.rb b/spec/bundler/update/git_spec.rb index 59e3d2f5fb..eeae4079ca 100644 --- a/spec/bundler/update/git_spec.rb +++ b/spec/bundler/update/git_spec.rb @@ -328,6 +328,10 @@ RSpec.describe "bundle update" do foo! rack + CHECKSUMS + foo (2.0) + #{checksum_for_repo_gem gem_repo2, "rack", "1.0.0"} + BUNDLED WITH #{Bundler::VERSION} G