From c8fb4f308bc24c75c2713129a0972ffcd8742b3f Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 1 Nov 2023 23:45:48 +0900 Subject: [PATCH] [rubygems/rubygems] Skip nil-value keys to make metadata reproducible Nil-value keys in a mapping end with a space or not depending on libyaml versions, and result metadata are different per platforms. This commit makes to skip such keys to make metadata reproducible accross platforms. https://github.com/rubygems/rubygems/commit/74b4db8d30 --- lib/rubygems/psych_tree.rb | 4 ++++ lib/rubygems/specification.rb | 3 ++- test/rubygems/test_gem_specification.rb | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/rubygems/psych_tree.rb b/lib/rubygems/psych_tree.rb index 2d478c94d9..7d17fc29cf 100644 --- a/lib/rubygems/psych_tree.rb +++ b/lib/rubygems/psych_tree.rb @@ -14,6 +14,10 @@ module Gem @emitter.scalar str, nil, nil, false, true, quote end + def visit_Hash(o) + super(o.dup.delete_if {|_, v| v.nil? }) + end + # Noop this out so there are no anchors def register(target, obj) end diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index 61ea3fcfdc..29139cf725 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -1890,7 +1890,8 @@ class Gem::Specification < Gem::BasicSpecification attributes = @@attributes.map(&:to_s) - %w[name version platform] attributes.each do |name| - coder.add name, instance_variable_get("@#{name}") + value = instance_variable_get("@#{name}") + coder.add name, value unless value.nil? end end diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb index 977e8b2965..9aa88fd5a3 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -2517,6 +2517,26 @@ end assert_match(/^platform: ruby$/, @a1.to_yaml) end + def test_to_yaml_no_autorequire + yaml_str = @a1.to_yaml + + refute_match(/^autorequire:/, yaml_str) + end + + def test_to_yaml_no_signing_key + @a1.signing_key = nil + yaml_str = @a1.to_yaml + + refute_match(/^signing_key:/, yaml_str) + end + + def test_to_yaml_no_post_install_message + @a1.post_install_message = nil + yaml_str = @a1.to_yaml + + refute_match(/^post_install_message:/, yaml_str) + end + def test_validate util_setup_validate