From 90cccf2b819a7bbe547c45940d7e077a9d9595ea Mon Sep 17 00:00:00 2001 From: Peter Boling Date: Thu, 27 Oct 2022 16:22:53 +0700 Subject: [PATCH 1/4] feat: rake build:checksum task creates SHA256 checksum in addition to SHA512 - Until now Rubygems.org has publicly displayed SHA256 checksum for published gems, but has only created the SHA512 checksum for the package via rake build:checksum task - This will allow more gem authors to easily verify integrity of published gems with an existing Rubygems.org feature --- bundler/lib/bundler/gem_helper.rb | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/bundler/lib/bundler/gem_helper.rb b/bundler/lib/bundler/gem_helper.rb index 0bbd2d9b75be..3030bb0f9536 100644 --- a/bundler/lib/bundler/gem_helper.rb +++ b/bundler/lib/bundler/gem_helper.rb @@ -2,9 +2,14 @@ require_relative "../bundler" require "shellwords" +require "digest/sha2" module Bundler class GemHelper + CHECKSUMS = { + "sha256" => ::Digest::SHA256, + "sha512" => ::Digest::SHA512, + }.freeze include Rake::DSL if defined? Rake::DSL class << self @@ -47,9 +52,9 @@ def install built_gem_path = build_gem end - desc "Generate SHA512 checksum if #{name}-#{version}.gem into the checksums directory." + desc "Build #{name}-#{version}.gem into pkg directory, then generate SHA256 & SHA512 checksums in checksums directory." task "build:checksum" => "build" do - build_checksum(built_gem_path) + build_checksums(built_gem_path) end desc "Build and install #{name}-#{version}.gem into system gems." @@ -102,19 +107,24 @@ def install_gem(built_gem_path = nil, local = false) Bundler.ui.confirm "#{name} (#{version}) installed." end - def build_checksum(built_gem_path = nil) + def build_checksums(built_gem_path = nil) built_gem_path ||= build_gem + CHECKSUMS.each do |extension, type| + write_checksum(built_gem_path, extension, type) + end + end + + protected + + def write_checksum(built_gem_path, extension, type) SharedHelpers.filesystem_access(File.join(base, "checksums")) {|p| FileUtils.mkdir_p(p) } - file_name = "#{File.basename(built_gem_path)}.sha512" - require "digest/sha2" - checksum = ::Digest::SHA512.file(built_gem_path).hexdigest + file_name = "#{File.basename(built_gem_path)}.#{extension}" + checksum = type.file(built_gem_path).hexdigest target = File.join(base, "checksums", file_name) File.write(target, checksum + "\n") Bundler.ui.confirm "#{name} #{version} checksum written to checksums/#{file_name}." end - protected - def rubygem_push(path) cmd = [*gem_command, "push", path] cmd << "--key" << gem_key if gem_key From 5c9b0ef08a7be233341acc2f5d8803a011a8e648 Mon Sep 17 00:00:00 2001 From: Peter Boling Date: Thu, 27 Oct 2022 16:24:03 +0700 Subject: [PATCH 2/4] feat: normalize lockfiles previously inconsistent platform discrepancies are normalized to include the following for all: x86_64-darwin-19 x86_64-darwin-20 x86_64-darwin-21 --- bundler/tool/bundler/release_gems.rb.lock | 2 ++ bundler/tool/bundler/rubocop23_gems.rb.lock | 1 + bundler/tool/bundler/rubocop24_gems.rb.lock | 1 + bundler/tool/bundler/standard23_gems.rb.lock | 1 + bundler/tool/bundler/standard24_gems.rb.lock | 1 + 5 files changed, 6 insertions(+) diff --git a/bundler/tool/bundler/release_gems.rb.lock b/bundler/tool/bundler/release_gems.rb.lock index b9d9e21e22db..0170bc700073 100644 --- a/bundler/tool/bundler/release_gems.rb.lock +++ b/bundler/tool/bundler/release_gems.rb.lock @@ -59,7 +59,9 @@ PLATFORMS arm64-darwin-21 universal-java-11 universal-java-18 + x86_64-darwin-19 x86_64-darwin-20 + x86_64-darwin-21 x86_64-linux DEPENDENCIES diff --git a/bundler/tool/bundler/rubocop23_gems.rb.lock b/bundler/tool/bundler/rubocop23_gems.rb.lock index 83ed3bd09535..fef006a56d1a 100644 --- a/bundler/tool/bundler/rubocop23_gems.rb.lock +++ b/bundler/tool/bundler/rubocop23_gems.rb.lock @@ -49,6 +49,7 @@ PLATFORMS universal-java-18 x86_64-darwin-19 x86_64-darwin-20 + x86_64-darwin-21 x86_64-linux DEPENDENCIES diff --git a/bundler/tool/bundler/rubocop24_gems.rb.lock b/bundler/tool/bundler/rubocop24_gems.rb.lock index 9b68c13a55bb..3b021dcaa84f 100644 --- a/bundler/tool/bundler/rubocop24_gems.rb.lock +++ b/bundler/tool/bundler/rubocop24_gems.rb.lock @@ -51,6 +51,7 @@ PLATFORMS universal-java-18 x86_64-darwin-19 x86_64-darwin-20 + x86_64-darwin-21 x86_64-linux DEPENDENCIES diff --git a/bundler/tool/bundler/standard23_gems.rb.lock b/bundler/tool/bundler/standard23_gems.rb.lock index b185f2496a8c..897f85918691 100644 --- a/bundler/tool/bundler/standard23_gems.rb.lock +++ b/bundler/tool/bundler/standard23_gems.rb.lock @@ -54,6 +54,7 @@ PLATFORMS universal-java-18 x86_64-darwin-19 x86_64-darwin-20 + x86_64-darwin-21 x86_64-linux DEPENDENCIES diff --git a/bundler/tool/bundler/standard24_gems.rb.lock b/bundler/tool/bundler/standard24_gems.rb.lock index 6482708b9340..81eced0d2b19 100644 --- a/bundler/tool/bundler/standard24_gems.rb.lock +++ b/bundler/tool/bundler/standard24_gems.rb.lock @@ -57,6 +57,7 @@ PLATFORMS universal-java-18 x86_64-darwin-19 x86_64-darwin-20 + x86_64-darwin-21 x86_64-linux DEPENDENCIES From 1c707ccef2a872eda6bf6bf63e483249e62fbe07 Mon Sep 17 00:00:00 2001 From: Peter Boling Date: Thu, 27 Oct 2022 18:12:28 +0700 Subject: [PATCH 3/4] test: Update build_checksums spec --- bundler/spec/bundler/gem_helper_spec.rb | 87 +++++++++++++------------ 1 file changed, 45 insertions(+), 42 deletions(-) diff --git a/bundler/spec/bundler/gem_helper_spec.rb b/bundler/spec/bundler/gem_helper_spec.rb index 7d955007ab93..4d1ecdb78357 100644 --- a/bundler/spec/bundler/gem_helper_spec.rb +++ b/bundler/spec/bundler/gem_helper_spec.rb @@ -62,20 +62,15 @@ def mock_build_message(name, version) mock_confirm_message message end - def mock_checksum_message(name, version) - message = "#{name} #{version} checksum written to checksums/#{name}-#{version}.gem.sha512." + def mock_checksum_message(name, version, extension) + message = "#{name} #{version} checksum written to checksums/#{name}-#{version}.gem.#{extension}." mock_confirm_message message end - def sha512_hexdigest(path) - Digest::SHA512.file(path).hexdigest - end - subject! { Bundler::GemHelper.new(app_path) } let(:app_version) { "0.1.0" } let(:app_gem_dir) { app_path.join("pkg") } let(:app_gem_path) { app_gem_dir.join("#{app_name}-#{app_version}.gem") } - let(:app_sha_path) { app_path.join("checksums", "#{app_name}-#{app_version}.gem.sha512") } let(:app_gemspec_content) { File.read(app_gemspec_path) } before(:each) do @@ -173,44 +168,52 @@ def sha512_hexdigest(path) end end - describe "#build_checksum" do - it "calculates SHA512 of the content" do - FileUtils.mkdir_p(app_gem_dir) - File.write(app_gem_path, "") - mock_checksum_message app_name, app_version - subject.build_checksum(app_gem_path) - expect(File.read(app_sha_path).chomp).to eql(Digest::SHA512.hexdigest("")) - end - - context "when build was successful" do - it "creates .sha512 file" do - mock_build_message app_name, app_version - mock_checksum_message app_name, app_version - subject.build_checksum - expect(app_sha_path).to exist - expect(File.read(app_sha_path).chomp).to eql(sha512_hexdigest(app_gem_path)) + describe "#build_checksums" do + %w[SHA256 SHA512].each do |sha_bits| + let(:digest) { Object.const_get("Digest::#{sha_bits}") } + let(:hex_digest) { digest.file(app_gem_path).hexdigest } + let(:app_sha_path) { app_path.join("checksums", "#{app_name}-#{app_version}.gem.#{sha_bits.downcase}") } + + it "calculates #{sha_bits} of the content" do + FileUtils.mkdir_p(app_gem_dir) + File.write(app_gem_path, "") + subject.build_checksums(app_gem_path) + expect(File.read(app_sha_path).chomp).to eql(digest.hexdigest("")) end - end - context "when building in the current working directory" do - it "creates a .sha512 file" do - mock_build_message app_name, app_version - mock_checksum_message app_name, app_version - Dir.chdir app_path do - Bundler::GemHelper.new.build_checksum + + context "with messages" do + before do + mock_build_message app_name, app_version + %w[sha256 sha512].each do |extension| + mock_checksum_message app_name, app_version, extension + end end - expect(app_sha_path).to exist - expect(File.read(app_sha_path).chomp).to eql(sha512_hexdigest(app_gem_path)) - end - end - context "when building in a location relative to the current working directory" do - it "creates a .sha512 file" do - mock_build_message app_name, app_version - mock_checksum_message app_name, app_version - Dir.chdir File.dirname(app_path) do - Bundler::GemHelper.new(File.basename(app_path)).build_checksum + + context "when build was successful" do + it "creates .#{sha_bits} file" do + subject.build_checksums + expect(app_sha_path).to exist + expect(File.read(app_sha_path).chomp).to eql(hex_digest) + end + end + context "when building in the current working directory" do + it "creates a .#{sha_bits} file" do + Dir.chdir app_path do + Bundler::GemHelper.new.build_checksums + end + expect(app_sha_path).to exist + expect(File.read(app_sha_path).chomp).to eql(hex_digest) + end + end + context "when building in a location relative to the current working directory" do + it "creates a .#{sha_bits} file" do + Dir.chdir File.dirname(app_path) do + Bundler::GemHelper.new(File.basename(app_path)).build_checksums + end + expect(app_sha_path).to exist + expect(File.read(app_sha_path).chomp).to eql(hex_digest) + end end - expect(app_sha_path).to exist - expect(File.read(app_sha_path).chomp).to eql(sha512_hexdigest(app_gem_path)) end end end From dec198599c07f815438e2c6cf51b53b80475ddd0 Mon Sep 17 00:00:00 2001 From: Peter Boling Date: Fri, 4 Nov 2022 11:16:47 +0700 Subject: [PATCH 4/4] return to lazy load of digest/sha2 - address code review feedback --- bundler/lib/bundler/gem_helper.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bundler/lib/bundler/gem_helper.rb b/bundler/lib/bundler/gem_helper.rb index 3030bb0f9536..180a654aac09 100644 --- a/bundler/lib/bundler/gem_helper.rb +++ b/bundler/lib/bundler/gem_helper.rb @@ -2,13 +2,12 @@ require_relative "../bundler" require "shellwords" -require "digest/sha2" module Bundler class GemHelper CHECKSUMS = { - "sha256" => ::Digest::SHA256, - "sha512" => ::Digest::SHA512, + "sha256" => "::Digest::SHA256", + "sha512" => "::Digest::SHA512", }.freeze include Rake::DSL if defined? Rake::DSL @@ -109,8 +108,9 @@ def install_gem(built_gem_path = nil, local = false) def build_checksums(built_gem_path = nil) built_gem_path ||= build_gem - CHECKSUMS.each do |extension, type| - write_checksum(built_gem_path, extension, type) + require "digest/sha2" + CHECKSUMS.each do |extension, digest_klass| + write_checksum(built_gem_path, extension, Object.const_get(digest_klass)) end end