From 55383ac1119bfc7908a7814c7b0680697f6a12a0 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 7 Jan 2025 15:17:39 -0300 Subject: [PATCH 1/4] feat: sign gems --- lib/rubygems/commands/compile_command.rb | 8 ++++++++ lib/rubygems/compiler.rb | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/lib/rubygems/commands/compile_command.rb b/lib/rubygems/commands/compile_command.rb index 06dfc38..66e1a29 100644 --- a/lib/rubygems/commands/compile_command.rb +++ b/lib/rubygems/commands/compile_command.rb @@ -54,6 +54,14 @@ def initialize end end + add_option "-s", "--sign [PRIVATE_KEY]", "Sign gems" do |private_key_file, options| + options[:sign_private_key_file] = File.expand_path(private_key_file) + end + + add_option "-c", "--cert [CERT]", "Certificate" do |cert_file, options| + options[:sign_cert_file] = File.expand_path(cert_file) + end + add_option "--build-number NUMBER", "Append build number to compiled Gem version" do |value, options| diff --git a/lib/rubygems/compiler.rb b/lib/rubygems/compiler.rb index a8c3b8b..a6d8fdc 100644 --- a/lib/rubygems/compiler.rb +++ b/lib/rubygems/compiler.rb @@ -68,6 +68,11 @@ def adjust_gemspec_files(gemspec, artifacts) gemspec.files.reject! { |f| !File.exist?("#{target_dir}/#{f}") } end + if @options[:sign_private_key_file] + gemspec.cert_chain = [@options[:sign_cert_file]] + gemspec.signing_key = @options[:sign_private_key_file] + end + # add discovered artifacts artifacts.each do |path| # path needs to be relative to target_dir From 5b838f41d53473c5564825e0f7e1afa088163647 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 9 Jan 2025 16:00:28 -0300 Subject: [PATCH 2/4] fix: raise errors correctly --- lib/rubygems/commands/compile_command.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rubygems/commands/compile_command.rb b/lib/rubygems/commands/compile_command.rb index 66e1a29..b2e74d1 100644 --- a/lib/rubygems/commands/compile_command.rb +++ b/lib/rubygems/commands/compile_command.rb @@ -36,7 +36,7 @@ def initialize mode = ABIs[value] unless mode valid = ABIs.keys.sort - raise OptionParser::InvalidArgument, "#{value} (#{valid.join ', '} are valid)" + raise Gem::OptionParser::InvalidArgument, "#{value} (#{valid.join ', '} are valid)" end options[:abi_lock] = mode @@ -68,7 +68,7 @@ def initialize begin options[:build_number] = Integer(value).abs rescue ArgumentError - raise OptionParser::InvalidArgument, "must be a number" + raise Gem::OptionParser::InvalidArgument, "must be a number" end end end From e0ea7c4fb67784f54149f37efe76415e867db272 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 9 Jan 2025 16:00:46 -0300 Subject: [PATCH 3/4] fix: files must exist --- lib/rubygems/commands/compile_command.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/rubygems/commands/compile_command.rb b/lib/rubygems/commands/compile_command.rb index b2e74d1..4f2ef26 100644 --- a/lib/rubygems/commands/compile_command.rb +++ b/lib/rubygems/commands/compile_command.rb @@ -55,11 +55,19 @@ def initialize end add_option "-s", "--sign [PRIVATE_KEY]", "Sign gems" do |private_key_file, options| - options[:sign_private_key_file] = File.expand_path(private_key_file) + options[:sign_private_key_file] = File.expand_path(private_key_file).tap do |f| + next if File.exist? f + + raise Gem::OptionParser::InvalidArgument, "#{private_key_file} must exist" + end end add_option "-c", "--cert [CERT]", "Certificate" do |cert_file, options| - options[:sign_cert_file] = File.expand_path(cert_file) + options[:sign_cert_file] = File.expand_path(cert_file).tap do |f| + next if File.exist? f + + raise Gem::OptionParser::InvalidArgument, "#{cert_file} must exist" + end end add_option "--build-number NUMBER", From dd68bfaea8c9b22db930a4785c88ff4534c197b6 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 9 Jan 2025 16:01:05 -0300 Subject: [PATCH 4/4] fix: both signing options need to be provided --- lib/rubygems/commands/compile_command.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/rubygems/commands/compile_command.rb b/lib/rubygems/commands/compile_command.rb index 4f2ef26..1d939cc 100644 --- a/lib/rubygems/commands/compile_command.rb +++ b/lib/rubygems/commands/compile_command.rb @@ -103,4 +103,12 @@ def execute compiler = Gem::Compiler.new(gemfile, options) compiler.compile end + + def handle_options(args) + super.tap do |f| + next if options.key?(:sign_cert_file) && options.key?(:sign_private_key_file) + + raise Gem::OptionParser::MissingArgument, "Both --cert and --sign options need to be provided" + end + end end