From ae308ae523a0af0e5566fff741395e48e5e877a2 Mon Sep 17 00:00:00 2001 From: Edouard CHIN Date: Wed, 9 Apr 2025 23:42:59 +0200 Subject: [PATCH] [rubygems/rubygems] Diagnose when OpenSSL can't be loaded. https://github.com/rubygems/rubygems/commit/e6aa8aabcd --- lib/bundler/cli/doctor/ssl.rb | 27 ++++++++++++++++++++++ libexec/ssl_check.rb | 12 ---------- spec/bundler/commands/ssl_spec.rb | 38 +++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 12 deletions(-) diff --git a/lib/bundler/cli/doctor/ssl.rb b/lib/bundler/cli/doctor/ssl.rb index ecc5cb00bb..4f002ee177 100644 --- a/lib/bundler/cli/doctor/ssl.rb +++ b/lib/bundler/cli/doctor/ssl.rb @@ -9,6 +9,9 @@ module Bundler end def run + return unless openssl_installed? + + output_ssl_environment end private @@ -28,5 +31,29 @@ module Bundler @verify_mode ||= mode.then {|mod| OpenSSL::SSL.const_get("verify_#{mod}".upcase) } end + + def openssl_installed? + require "openssl" + + true + rescue LoadError + Bundler.ui.warn(<<~MSG) + Oh no! Your Ruby doesn't have OpenSSL, so it can't connect to #{host}. + You'll need to recompile or reinstall Ruby with OpenSSL support and try again. + MSG + + false + end + + def output_ssl_environment + Bundler.ui.info(<<~MESSAGE) + Here's your OpenSSL environment: + + OpenSSL: #{OpenSSL::VERSION} + Compiled with: #{OpenSSL::OPENSSL_VERSION} + Loaded with: #{OpenSSL::OPENSSL_LIBRARY_VERSION} + MESSAGE + end + end end diff --git a/libexec/ssl_check.rb b/libexec/ssl_check.rb index de761e0ab3..e4bfcb66cb 100644 --- a/libexec/ssl_check.rb +++ b/libexec/ssl_check.rb @@ -4,14 +4,6 @@ require 'uri' require 'net/http' -begin - require 'openssl' -rescue LoadError - puts "Oh no! Your Ruby doesn't have OpenSSL, so it can't connect to #{host}.", - "You'll need to recompile or reinstall Ruby with OpenSSL support and try again." - exit 1 -end - begin # Some versions of Ruby need this require to do HTTPS require 'net/https' @@ -39,10 +31,6 @@ puts puts "Ruby: %s" % ruby_version puts "RubyGems: %s" % Gem::VERSION if defined?(Gem::VERSION) puts "Bundler: %s" % Bundler::VERSION if defined?(Bundler::VERSION) -puts "OpenSSL: %s" % OpenSSL::VERSION if defined?(OpenSSL::VERSION) -puts "Compiled with: %s" % OpenSSL::OPENSSL_VERSION -puts "Loaded with: %s" % OpenSSL::OPENSSL_LIBRARY_VERSION if defined?(OpenSSL::OPENSSL_LIBRARY_VERSION) -puts def show_ssl_certs puts "", "Below affect only Ruby net/http connections:" diff --git a/spec/bundler/commands/ssl_spec.rb b/spec/bundler/commands/ssl_spec.rb index 78afa39814..e8c32a24fd 100644 --- a/spec/bundler/commands/ssl_spec.rb +++ b/spec/bundler/commands/ssl_spec.rb @@ -5,4 +5,42 @@ require "bundler/cli/doctor" require "bundler/cli/doctor/ssl" RSpec.describe "bundle doctor ssl" do + before(:each) do + @previous_level = Bundler.ui.level + Bundler.ui.instance_variable_get(:@warning_history).clear + Bundler.ui.level = "info" + end + + after(:each) do + Bundler.ui.level = @previous_level + end + + context "when a diagnostic fails" do + it "prints the diagnostic when openssl can't be loaded" do + subject = Bundler::CLI::Doctor::SSL.new({}) + allow(subject).to receive(:require).with("openssl").and_raise(LoadError) + + expected_err = <<~MSG + Oh no! Your Ruby doesn't have OpenSSL, so it can't connect to rubygems.org. + You'll need to recompile or reinstall Ruby with OpenSSL support and try again. + MSG + + expect { subject.run }.to output("").to_stdout.and output(expected_err).to_stderr + end + end + + context "when no diagnostic fails" do + it "prints the SSL environment" do + expected_out = <<~MSG + Here's your OpenSSL environment: + + OpenSSL: #{OpenSSL::VERSION} + Compiled with: #{OpenSSL::OPENSSL_VERSION} + Loaded with: #{OpenSSL::OPENSSL_LIBRARY_VERSION} + MSG + + subject = Bundler::CLI::Doctor::SSL.new({}) + expect { subject.run }.to output(expected_out).to_stdout.and output("").to_stderr + end + end end