diff --git a/.github/workflows/rubygems.yml b/.github/workflows/rubygems.yml index c7419c954fb8..19c1273d4ebe 100644 --- a/.github/workflows/rubygems.yml +++ b/.github/workflows/rubygems.yml @@ -60,6 +60,10 @@ jobs: - ruby: { name: no symlinks, value: 4.0.5 } os: { name: Windows, value: windows-2025 } symlink: off + + - ruby: { name: head (RUBY_BOX=1), value: head } + os: { name: Ubuntu, value: ubuntu-24.04 } + ruby_box: true env: RUBYGEMS_USE_PSYCH: ${{ matrix.use_psych || 'false' }} @@ -79,7 +83,10 @@ jobs: run: bin/rake setup - name: Run Test run: bin/rake test - if: matrix.ruby.name != 'truffleruby' && matrix.ruby.name != 'jruby' && matrix.symlink != 'off' + if: matrix.ruby.name != 'truffleruby' && matrix.ruby.name != 'jruby' && matrix.symlink != 'off' && !matrix.ruby_box + - name: Run Test (RUBY_BOX=1) + run: RUBY_BOX=1 bin/rake test + if: matrix.ruby_box - name: Run Test isolatedly run: bin/rake test:isolated if: matrix.ruby.name == '3.4' && matrix.os.name != 'Windows' diff --git a/lib/bundler/gem_helper.rb b/lib/bundler/gem_helper.rb index e3af1b957f35..ea02e7e7712b 100644 --- a/lib/bundler/gem_helper.rb +++ b/lib/bundler/gem_helper.rb @@ -216,7 +216,7 @@ def sh_with_status(cmd, &block) Bundler.ui.debug(cmd) SharedHelpers.chdir(base) do outbuf = IO.popen(cmd, err: [:child, :out], &:read) - status = $? + status = Process.last_status block&.call(outbuf) if status.success? [outbuf, status] end diff --git a/lib/rubygems/ext/builder.rb b/lib/rubygems/ext/builder.rb index b7e80d6b06bb..691bc2825da0 100644 --- a/lib/rubygems/ext/builder.rb +++ b/lib/rubygems/ext/builder.rb @@ -101,7 +101,9 @@ def self.run(command, results, command_name = nil, dir = Dir.pwd, env = {}) require "open3" # Set $SOURCE_DATE_EPOCH for the subprocess. - # Under Ruby::Box mkmf makes RbConfig.expand recurse until SystemStackError. + # Under Ruby::Box defined?($gvar) does not see assignments made inside the + # box, so mkmf have_devel? never memoizes and recurses until SystemStackError + # (https://bugs.ruby-lang.org/issues/22283). # Drop $RUBY_BOX last so no caller can restore it. build_env = { "SOURCE_DATE_EPOCH" => Gem.source_date_epoch_string }.merge(env).merge("RUBY_BOX" => nil) # A single-element command would be parsed as a shell command line, diff --git a/lib/rubygems/source/git.rb b/lib/rubygems/source/git.rb index baf2f9dd4c09..0ceb67b382f5 100644 --- a/lib/rubygems/source/git.rb +++ b/lib/rubygems/source/git.rb @@ -188,9 +188,11 @@ def rev_parse # :nodoc: hash = Gem::Util.popen(git_command, "rev-parse", @reference).strip end + # Process.last_status instead of $?, which Ruby::Box leaves uninitialized + # (https://bugs.ruby-lang.org/issues/22280) raise Gem::Exception, "unable to find reference #{@reference} in #{@repository}" unless - $?.success? + Process.last_status.success? hash end diff --git a/spec/bundler/shared_helpers_spec.rb b/spec/bundler/shared_helpers_spec.rb index 1619b0a14a59..232da4143a24 100644 --- a/spec/bundler/shared_helpers_spec.rb +++ b/spec/bundler/shared_helpers_spec.rb @@ -387,7 +387,11 @@ before do ENV["RUBYOPT"] = "-r#{install_path}/bundler/setup" - allow(File).to receive(:expand_path).and_return("#{install_path}/bundler/setup") + # Only fake the resolution of bundler/setup itself. A blanket stub + # breaks unrelated RubyGems path lookups triggered lazily inside the + # example, see #set_rubyopt. + allow(File).to receive(:expand_path).and_call_original + allow(File).to receive(:expand_path).with("setup", anything).and_return("#{install_path}/bundler/setup") allow(Gem).to receive(:bin_path).and_return("#{install_path}/bundler/setup") end @@ -403,7 +407,8 @@ let(:install_path) { "/opt/ruby with space/lib" } before do - allow(File).to receive(:expand_path).and_return("#{install_path}/bundler/setup") + allow(File).to receive(:expand_path).and_call_original + allow(File).to receive(:expand_path).with("setup", anything).and_return("#{install_path}/bundler/setup") allow(Gem).to receive(:bin_path).and_return("#{install_path}/bundler/setup") end diff --git a/spec/commands/install_spec.rb b/spec/commands/install_spec.rb index d4b88902e21e..b5e4a9aa76c7 100644 --- a/spec/commands/install_spec.rb +++ b/spec/commands/install_spec.rb @@ -2065,6 +2065,10 @@ def gem_make_out end it "preserves bundled native extensions when BUNDLE_CLEAN removes another gem" do + # The command-line/RUBYOPT -r bypasses gem activation under RUBY_BOX=1 + # (https://bugs.ruby-lang.org/issues/22295) + skip "-r cannot activate gems under Ruby::Box" if defined?(Ruby::Box) && Ruby::Box.enabled? + build_repo4 do build_gem "native_child", "1.0", &:add_c_extension build_gem "native_parent", "1.0" do |s| diff --git a/spec/support/command_execution.rb b/spec/support/command_execution.rb index e2915b996d9d..14da54dca4da 100644 --- a/spec/support/command_execution.rb +++ b/spec/support/command_execution.rb @@ -2,6 +2,13 @@ module Spec class CommandExecution + # Under RUBY_BOX, every spawned ruby prints an experimental warning to + # stderr, breaking specs that assert clean stderr. + RUBY_BOX_WARNING = Regexp.union( + /^[^\n]*: warning: Ruby::Box is experimental, and the behavior may change in the future!\n?/, + %r{^See https://docs\.ruby-lang\.org/\S+ for known issues, etc\.\n?} + ) + def initialize(command, timeout:) @command = command @timeout = timeout @@ -72,7 +79,13 @@ def failure? attr_reader :failure_reason def normalize(string) - string.dup.force_encoding(Encoding::UTF_8).scrub.strip.gsub("\r\n", "\n") + string = string.dup.force_encoding(Encoding::UTF_8).scrub.gsub("\r\n", "\n") + string = string.gsub(RUBY_BOX_WARNING, "") if ruby_box_enabled? + string.strip + end + + def ruby_box_enabled? + defined?(Ruby::Box) && Ruby::Box.enabled? end end end diff --git a/test/rubygems/helper.rb b/test/rubygems/helper.rb index 09b7f427ebbf..c478bb86d8ba 100644 --- a/test/rubygems/helper.rb +++ b/test/rubygems/helper.rb @@ -404,6 +404,10 @@ def setup ENV["BUNDLE_COOLDOWN"] = nil ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"] = "true" + # Child ruby processes inherit RUBY_BOX and print an experimental + # warning on startup, breaking assertions on subprocess stderr. + ENV["RUBYOPT"] = [ENV["RUBYOPT"], "-W:no-experimental"].compact.join(" ") if ruby_box_enabled? + @current_dir = Dir.pwd @fetcher = nil @@ -1440,6 +1444,32 @@ def ruby_repo? !ENV["GEM_COMMAND"].nil? end + ## + # Is this test running under Ruby::Box (RUBY_BOX=1)? + + def ruby_box_enabled? + defined?(Ruby::Box) && Ruby::Box.enabled? + end + + ## + # Ruby::Box gives each box detached copies of the stdio globals, so + # reassigning $stdout/$stderr cannot capture output written by Kernel#warn, + # Kernel#puts or subprocesses. Pends until the ruby-core fix for + # https://bugs.ruby-lang.org/issues/21867 lands. + + def pend_for_ruby_box_stdio_capture + pend "Ruby::Box breaks $stdout/$stderr capture (https://bugs.ruby-lang.org/issues/21867)" if ruby_box_enabled? + end + + ## + # Under Ruby::Box, Marshal in the main box cannot resolve Gem:: (and other + # boxed) constants. Pends until the ruby-core fix for + # https://bugs.ruby-lang.org/issues/22090 lands. + + def pend_for_ruby_box_marshal + pend "Marshal cannot resolve boxed constants under Ruby::Box (https://bugs.ruby-lang.org/issues/22090)" if ruby_box_enabled? + end + ## # Returns the make command for the current platform. For versions of Ruby # built on MS Windows with VC++ or Borland it will return 'nmake'. On all diff --git a/test/rubygems/test_deprecate.rb b/test/rubygems/test_deprecate.rb index bb6a0b5ceaaf..5700d356e756 100644 --- a/test/rubygems/test_deprecate.rb +++ b/test/rubygems/test_deprecate.rb @@ -132,6 +132,7 @@ def test_deprecated_method_calls_the_old_method end def test_deprecated_method_outputs_a_warning + pend_for_ruby_box_stdio_capture out, err = capture_output do thing = Thing.new thing.foo @@ -165,6 +166,7 @@ def execute end def test_deprecated_method_outputs_a_warning_old_way + pend_for_ruby_box_stdio_capture out, err = capture_output do thing = OtherThing.new thing.foo @@ -180,6 +182,7 @@ def test_deprecated_method_outputs_a_warning_old_way end def test_deprecated_method_when_class_overrides_format + pend_for_ruby_box_stdio_capture out, err = capture_output do thing = ThingWithFormat.new thing.foo diff --git a/test/rubygems/test_exit.rb b/test/rubygems/test_exit.rb index 396837edadfa..c339c39a67af 100644 --- a/test/rubygems/test_exit.rb +++ b/test/rubygems/test_exit.rb @@ -6,7 +6,8 @@ class TestGemExit < Gem::TestCase def test_exit system(*ruby_with_rubygems_in_load_path, "-e", "raise Gem::SystemExitException.new(2)") - assert_equal 2, $?.exitstatus + # Process.last_status instead of $?, which Ruby::Box leaves uninitialized + assert_equal 2, Process.last_status.exitstatus end def test_status diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index 88b461a2a0a7..36067549c863 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb @@ -1297,6 +1297,7 @@ def test_self_try_activate_missing_prerelease end def test_self_try_activate_missing_extensions + pend_for_ruby_box_stdio_capture spec = util_spec "ext", "1" do |s| s.extensions = %w[ext/extconf.rb] s.installed_by_version = v("2.2") @@ -1352,6 +1353,7 @@ def test_setting_paths_does_not_mutate_parameter_object end def test_deprecated_paths= + pend_for_ruby_box_stdio_capture stdout, stderr = capture_output do Gem.paths = { "GEM_HOME" => Gem.paths.home, "GEM_PATH" => [Gem.paths.home, "foo"] } diff --git a/test/rubygems/test_gem_commands_build_command.rb b/test/rubygems/test_gem_commands_build_command.rb index 771eb07dbc9c..5bbb7c3b3e35 100644 --- a/test/rubygems/test_gem_commands_build_command.rb +++ b/test/rubygems/test_gem_commands_build_command.rb @@ -383,6 +383,7 @@ def test_execute_strict_with_warnings end def test_execute_bad_spec + pend_for_ruby_box_stdio_capture @gem.date = "2010-11-08" gemspec_file = File.join(@tempdir, @gem.spec_name) diff --git a/test/rubygems/test_gem_commands_open_command.rb b/test/rubygems/test_gem_commands_open_command.rb index 3a774a9343c0..c30117a58ecc 100644 --- a/test/rubygems/test_gem_commands_open_command.rb +++ b/test/rubygems/test_gem_commands_open_command.rb @@ -21,6 +21,7 @@ def gem(name, version = "1.0") end def test_execute + pend_for_ruby_box_stdio_capture omit "JRuby on Windows spawns the editor with a different cwd" if Gem.win_platform? && Gem.java_platform? @cmd.options[:args] = %w[foo] diff --git a/test/rubygems/test_gem_commands_specification_command.rb b/test/rubygems/test_gem_commands_specification_command.rb index 454d6ea1c6f7..ee96eaa892a5 100644 --- a/test/rubygems/test_gem_commands_specification_command.rb +++ b/test/rubygems/test_gem_commands_specification_command.rb @@ -137,6 +137,7 @@ def test_execute_file end def test_execute_marshal + pend_for_ruby_box_marshal foo = util_spec "foo", "2" install_specs foo diff --git a/test/rubygems/test_gem_config_file.rb b/test/rubygems/test_gem_config_file.rb index 2c33192a4b3a..7120c49e327a 100644 --- a/test/rubygems/test_gem_config_file.rb +++ b/test/rubygems/test_gem_config_file.rb @@ -314,6 +314,7 @@ def test_handle_arguments_backtrace end def test_handle_arguments_debug + pend_for_ruby_box_stdio_capture assert_equal false, $DEBUG args = %w[--debug] diff --git a/test/rubygems/test_gem_dependency_installer.rb b/test/rubygems/test_gem_dependency_installer.rb index 95d455ad5f3d..bf496c189ca1 100644 --- a/test/rubygems/test_gem_dependency_installer.rb +++ b/test/rubygems/test_gem_dependency_installer.rb @@ -1126,6 +1126,7 @@ def test_install_version_default end def test_install_legacy_spec_with_nil_required_ruby_version + pend_for_ruby_box_marshal path = File.expand_path "data/null-required-ruby-version.gemspec.rz", __dir__ spec = Marshal.load Gem.read_binary(path) def spec.validate(*args); end @@ -1151,6 +1152,7 @@ def spec.validate(*args); end end def test_install_legacy_spec_with_nil_required_rubygems_version + pend_for_ruby_box_marshal path = File.expand_path "data/null-required-rubygems-version.gemspec.rz", __dir__ spec = Marshal.load Gem.read_binary(path) def spec.validate(*args); end diff --git a/test/rubygems/test_gem_doctor.rb b/test/rubygems/test_gem_doctor.rb index 1554e7af128d..da625000ff90 100644 --- a/test/rubygems/test_gem_doctor.rb +++ b/test/rubygems/test_gem_doctor.rb @@ -240,6 +240,7 @@ def test_doctor_preserves_valid_abi_scoped_gemspec end def test_doctor_removes_corrupt_abi_scoped_gemspec + pend_for_ruby_box_stdio_capture install_specs util_spec "regular_gem" spec = util_ca_spec "ca_gem", "1", "aabbccdd", @@ -286,6 +287,7 @@ def test_doctor_preserves_other_abi_dir end def test_doctor_does_not_recurse_into_abi_symlink + pend_for_ruby_box_stdio_capture pend "symlinks not supported" unless symlink_supported? install_specs util_spec "regular_gem" diff --git a/test/rubygems/test_gem_ext_builder.rb b/test/rubygems/test_gem_ext_builder.rb index 6b4eed2cf211..f5ad791ec1c9 100644 --- a/test/rubygems/test_gem_ext_builder.rb +++ b/test/rubygems/test_gem_ext_builder.rb @@ -700,7 +700,7 @@ def self.expand(val, config = CONFIG); val; end system(Gem.ruby, "-rmkmf", "-e", "exit MakeMakefile::RbConfig::CONFIG['host_os'] == 'fake_os'", "--", "--target-rbconfig=#{fake_rbconfig}") end - unless $?.success? + unless Process.last_status.success? assert_include(stderr, "uninitialized constant MakeMakefile::RbConfig") pend "This version of mkmf does not support --target-rbconfig" end diff --git a/test/rubygems/test_gem_ext_cargo_builder.rb b/test/rubygems/test_gem_ext_cargo_builder.rb index b970e442c250..bf442125f275 100644 --- a/test/rubygems/test_gem_ext_cargo_builder.rb +++ b/test/rubygems/test_gem_ext_cargo_builder.rb @@ -111,7 +111,9 @@ def test_full_integration Open3.capture2e(*gem, "build", "rust_ruby_example.gemspec", "--output", built_gem) Open3.capture2e(*gem, "install", "--verbose", "--local", built_gem, *ARGV) - stdout_and_stderr_str, status = Open3.capture2e(env_for_subprocess, *ruby_with_rubygems_in_load_path, "-rrust_ruby_example", "-e", "puts 'Result: ' + RustRubyExample.reverse('hello world')") + # Require inside -e because -r bypasses gem activation under RUBY_BOX=1 + # (https://bugs.ruby-lang.org/issues/22295) + stdout_and_stderr_str, status = Open3.capture2e(env_for_subprocess, *ruby_with_rubygems_in_load_path, "-e", "require 'rust_ruby_example'; puts 'Result: ' + RustRubyExample.reverse('hello world')") assert status.success?, stdout_and_stderr_str assert_match "Result: #{"hello world".reverse}", stdout_and_stderr_str end @@ -134,7 +136,7 @@ def test_custom_name Open3.capture2e(*gem, "install", "--verbose", "--local", built_gem, *ARGV) end - stdout_and_stderr_str, status = Open3.capture2e(env_for_subprocess, *ruby_with_rubygems_in_load_path, "-rcustom_name", "-e", "puts 'Result: ' + CustomName.say_hello") + stdout_and_stderr_str, status = Open3.capture2e(env_for_subprocess, *ruby_with_rubygems_in_load_path, "-e", "require 'custom_name'; puts 'Result: ' + CustomName.say_hello") assert status.success?, stdout_and_stderr_str assert_match "Result: Hello world!", stdout_and_stderr_str @@ -199,7 +201,7 @@ def skip_unsupported_platforms! pend "jruby not supported" if Gem.java_platform? pend "truffleruby not supported (yet)" if RUBY_ENGINE == "truffleruby" system(@rust_envs, "cargo", "-V", out: IO::NULL, err: [:child, :out]) - pend "cargo not present" unless $?.success? + pend "cargo not present" unless Process.last_status.success? pend "ruby.h is not provided by ruby repo" if ruby_repo? pend "rust toolchain of mingw is broken" if mingw_windows? end diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb index b0935693d1c7..4e83b3a69b46 100644 --- a/test/rubygems/test_gem_package.rb +++ b/test/rubygems/test_gem_package.rb @@ -1538,6 +1538,7 @@ def test_verify_corrupt end def test_verify_corrupt_tar_metadata_entry + pend_for_ruby_box_stdio_capture gem = tar_file_header("metadata.gz", "", 0, 999, Time.now) File.open "corrupt.gem", "wb" do |io| @@ -1574,6 +1575,7 @@ def test_verify_corrupt_tar_checksums_entry end def test_verify_corrupt_tar_data_entry + pend_for_ruby_box_stdio_capture gem = tar_file_header("data.tar.gz", "", 0, 100, Time.now) File.open "corrupt.gem", "wb" do |io| diff --git a/test/rubygems/test_gem_package_tar_header_ractor.rb b/test/rubygems/test_gem_package_tar_header_ractor.rb index 57140648052e..d2fc0f69b1e9 100644 --- a/test/rubygems/test_gem_package_tar_header_ractor.rb +++ b/test/rubygems/test_gem_package_tar_header_ractor.rb @@ -8,6 +8,11 @@ end class TestGemPackageTarHeaderRactor < Gem::Package::TarTestCase + def setup + super + pend "Ruby::Box ignores $VERBOSE=, so assert_ractor cannot keep the Ractor experimental warning out of the child stderr (https://bugs.ruby-lang.org/issues/22282)" if ruby_box_enabled? + end + SETUP = <<~RUBY header = { name: "x", diff --git a/test/rubygems/test_gem_request_set.rb b/test/rubygems/test_gem_request_set.rb index 8c8be04fb9f9..60ff8724aef4 100644 --- a/test/rubygems/test_gem_request_set.rb +++ b/test/rubygems/test_gem_request_set.rb @@ -71,6 +71,7 @@ def test_install_from_gemdeps end def test_install_from_gemdeps_explain + pend_for_ruby_box_stdio_capture spec_fetcher do |fetcher| fetcher.gem "a", 2 end @@ -94,6 +95,7 @@ def test_install_from_gemdeps_explain end def test_install_from_gemdeps_explain_verbose + pend_for_ruby_box_stdio_capture spec_fetcher do |fetcher| fetcher.gem "a", 2 end diff --git a/test/rubygems/test_gem_request_set_gem_dependency_api.rb b/test/rubygems/test_gem_request_set_gem_dependency_api.rb index 4b5eaa38eda8..d8f4e7f6e92b 100644 --- a/test/rubygems/test_gem_request_set_gem_dependency_api.rb +++ b/test/rubygems/test_gem_request_set_gem_dependency_api.rb @@ -78,6 +78,7 @@ def test_gem end def test_gem_duplicate + pend_for_ruby_box_stdio_capture @gda.gem "a" _, err = capture_output do @@ -128,6 +129,7 @@ def test_gem_bitbucket_expand_path end def test_gem_git_branch + pend_for_ruby_box_stdio_capture _, err = capture_output do @gda.gem "a", git: "git/a", branch: "other", tag: "v1" end @@ -149,6 +151,7 @@ def test_gem_git_gist end def test_gem_git_ref + pend_for_ruby_box_stdio_capture _, err = capture_output do @gda.gem "a", git: "git/a", ref: "abcd123", branch: "other" end diff --git a/test/rubygems/test_gem_requirement.rb b/test/rubygems/test_gem_requirement.rb index 00634dc7f43f..bd3988b32300 100644 --- a/test/rubygems/test_gem_requirement.rb +++ b/test/rubygems/test_gem_requirement.rb @@ -431,6 +431,7 @@ def self.exploit(arg) end def test_marshal_load_attack + pend_for_ruby_box_marshal wa = Gem::Net::WriteAdapter.allocate wa.instance_variable_set(:@socket, self.class) wa.instance_variable_set(:@method_id, :exploit) diff --git a/test/rubygems/test_gem_safe_marshal.rb b/test/rubygems/test_gem_safe_marshal.rb index c34d8570c6ec..9a7007eebea3 100644 --- a/test/rubygems/test_gem_safe_marshal.rb +++ b/test/rubygems/test_gem_safe_marshal.rb @@ -317,10 +317,12 @@ def test_array_subclass end def test_frozen_object + pend_for_ruby_box_marshal assert_safe_load_as Gem::Version.new("1.abc").freeze end def test_date + pend_for_ruby_box_marshal assert_safe_load_as Date.new(1994, 12, 9) end @@ -404,6 +406,7 @@ def test_gem_spec_unmarshall_license end def test_gem_spec_unmarshall_required_ruby_rubygems_version + pend_for_ruby_box_marshal spec = Gem::Specification.new do |s| s.name = "hi" s.version = "1.2.3" @@ -535,7 +538,12 @@ def test_date_user_defined_rejected def assert_safe_load_marshal(dumped, additional_methods: [], permitted_ivars: nil, equality: true, marshal_dump_equality: true, inspect: true, to_s: true) - loaded = Marshal.load(dumped) + loaded = begin + Marshal.load(dumped) + rescue ArgumentError => e + pend_for_ruby_box_marshal if e.message.include?("undefined class/module") + raise + end safe_loaded = assert_nothing_raised("dumped: #{dumped.b.inspect} loaded: #{loaded.inspect}") do if permitted_ivars diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb index dc32a6290786..fb6df06b9c70 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -710,6 +710,7 @@ def test_self_attribute_names end def test_self__load_future + pend_for_ruby_box_marshal spec = Gem::Specification.new spec.name = "a" spec.version = "1" @@ -1064,6 +1065,7 @@ def test_self_stubs_returns_only_specified_named_specs end def test_handles_private_null_type + pend_for_ruby_box_marshal yaml_defined = Object.const_defined?("YAML") path = File.expand_path "data/pry-0.4.7.gemspec.rz", __dir__ @@ -1076,6 +1078,7 @@ def test_handles_private_null_type end def test_handles_dependencies_with_syck_requirements_bug + pend_for_ruby_box_marshal yaml_defined = Object.const_defined?("YAML") path = File.expand_path "data/excon-0.7.7.gemspec.rz", __dir__ @@ -1281,6 +1284,7 @@ def test_set_version_to_nil_after_setting_version end def test__dump + pend_for_ruby_box_marshal @a2.platform = Gem::Platform.local @a2.instance_variable_set :@original_platform, "old_platform" @@ -1576,6 +1580,7 @@ def test_contains_requirable_file_eh end def test_contains_requirable_file_eh_extension + pend_for_ruby_box_stdio_capture ext_spec _, err = capture_output do @@ -3386,6 +3391,7 @@ def test_validate_files end def test_unresolved_specs + pend_for_ruby_box_stdio_capture specification = Gem::Specification.clone set_orig specification @@ -3412,6 +3418,7 @@ def test_unresolved_specs end def test_unresolved_specs_with_versions + pend_for_ruby_box_stdio_capture specification = Gem::Specification.clone set_orig specification @@ -3444,6 +3451,7 @@ def test_unresolved_specs_with_versions end def test_unresolved_specs_with_duplicated_versions + pend_for_ruby_box_stdio_capture specification = Gem::Specification.clone set_orig specification @@ -3497,6 +3505,7 @@ def test_unresolved_specs_with_unrestricted_deps_on_default_gems end def test_duplicate_runtime_dependency + pend_for_ruby_box_stdio_capture expected = "WARNING: duplicated b dependency [\"~> 3.0\", \"~> 3.0\"]\n" out, err = capture_output do @a1.add_dependency "b", "~> 3.0", "~> 3.0" @@ -3995,6 +4004,7 @@ def test_version_change_reset_cache_file end def test__load_fixes_Date_objects + pend_for_ruby_box_marshal spec = util_spec "a", 1 spec.instance_variable_set :@date, Date.today diff --git a/test/rubygems/test_gem_stub_specification.rb b/test/rubygems/test_gem_stub_specification.rb index 1aa3b6532436..66bdd3d3fbbb 100644 --- a/test/rubygems/test_gem_stub_specification.rb +++ b/test/rubygems/test_gem_stub_specification.rb @@ -94,6 +94,7 @@ def test_contains_requirable_file_eh end def test_contains_requirable_file_eh_extension + pend_for_ruby_box_stdio_capture stub_with_extension do |stub| _, err = capture_output do if RUBY_ENGINE == "jruby" diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb index db86a3090565..ef1bb2e465a2 100644 --- a/test/rubygems/test_require.rb +++ b/test/rubygems/test_require.rb @@ -484,7 +484,7 @@ def test_realworld_default_gem puts Gem.loaded_specs["json"] RUBY output = Gem::Util.popen(*ruby_with_rubygems_in_load_path, "-e", cmd).strip - assert $?.success? + assert Process.last_status.success? refute_empty output end @@ -508,7 +508,7 @@ def test_realworld_upgraded_default_gem assert_equal "999.99.9", output.lines[0].chomp # Make sure only files from the newer json gem are loaded, and no files from the default json gem assert_equal ["#{@gemhome}/gems/json-999.99.9/lib/json.rb"], output.lines.grep(%r{/gems/json-}).map(&:chomp) - assert $?.success? + assert Process.last_status.success? end def test_default_gem_and_normal_gem @@ -718,6 +718,7 @@ def test_require_bundler ["", "Kernel."].each do |prefix| define_method "test_no_kernel_require_in_#{prefix.tr(".", "_")}warn_with_uplevel" do + pend_for_ruby_box_stdio_capture Dir.mktmpdir("warn_test") do |dir| File.write(dir + "/sub.rb", "#{prefix}warn 'uplevel', 'test', uplevel: 1\n") File.write(dir + "/main.rb", "require 'sub'\n") @@ -733,6 +734,7 @@ def test_require_bundler end define_method "test_no_other_behavioral_changes_with_#{prefix.tr(".", "_")}warn" do + pend_for_ruby_box_stdio_capture Dir.mktmpdir("warn_test") do |dir| File.write(dir + "/main.rb", "#{prefix}warn({x:1}, {y:2}, [])\n") _, err = capture_subprocess_io do @@ -748,6 +750,7 @@ def test_require_bundler end def test_no_crash_when_overriding_warn_with_warning_module + pend_for_ruby_box_stdio_capture Dir.mktmpdir("warn_test") do |dir| File.write(dir + "/main.rb", "module Warning; def warn(str); super; end; end; warn 'Foo Bar'") _, err = capture_subprocess_io do @@ -762,6 +765,7 @@ def test_no_crash_when_overriding_warn_with_warning_module end def test_expected_backtrace_location_when_inheriting_from_basic_object_and_including_kernel + pend_for_ruby_box_stdio_capture Dir.mktmpdir("warn_test") do |dir| File.write(dir + "/main.rb", "\nrequire 'sub'\n") File.write(dir + "/sub.rb", <<-'RUBY') diff --git a/test/rubygems/test_rubygems.rb b/test/rubygems/test_rubygems.rb index 6566b5981e69..02393c57fcae 100644 --- a/test/rubygems/test_rubygems.rb +++ b/test/rubygems/test_rubygems.rb @@ -5,7 +5,7 @@ class GemTest < Gem::TestCase def test_rubygems_normal_behaviour _ = Gem::Util.popen(*ruby_with_rubygems_in_load_path, "-e", "'require \"rubygems\"'", { err: [:child, :out] }).strip - assert $?.success? + assert Process.last_status.success? end def test_operating_system_other_exceptions @@ -17,7 +17,7 @@ def test_operating_system_other_exceptions RUBY output = Gem::Util.popen(*ruby_with_rubygems_and_fake_operating_system_in_load_path(path), "-e", "'require \"rubygems\"'", { err: [:child, :out] }).strip - assert !$?.success? + assert !Process.last_status.success? assert_match(/undefined local variable or method [`']intentionally_not_implemented_method'/, output) assert_includes output, "Loading the #{operating_system_rb_at(path)} file caused an error. " \ "This file is owned by your OS, not by rubygems upstream. " \ diff --git a/tool/release.rb b/tool/release.rb index 7585136b6c4f..2324b2d0f95f 100644 --- a/tool/release.rb +++ b/tool/release.rb @@ -442,7 +442,7 @@ def add_commit_authors!(pulls) ids = batch.flat_map {|pull| ["-F", "ids[]=#{pull.node_id}"] } json = IO.popen(["gh", "api", "graphql", "-f", "query=#{COMMIT_AUTHORS_QUERY}", *ids], &:read) - raise "Failed to list the commits of #{batch.map(&:number).join(", ")}" unless $?.success? + raise "Failed to list the commits of #{batch.map(&:number).join(", ")}" unless Process.last_status.success? credit_commit_authors(batch, JSON.parse(json).dig("data", "nodes")) end @@ -501,7 +501,7 @@ def git_quietly(*args) def pull_requests_merged_into(base, from, to) commits = git_quietly("rev-list", "#{from}..#{to}") - raise "Failed to list the commits in #{from}..#{to}" unless $?.success? + raise "Failed to list the commits in #{from}..#{to}" unless Process.last_status.success? reachable = Set.new(commits.split("\n")) @@ -511,12 +511,12 @@ def pull_requests_merged_into(base, from, to) # The date bound is deliberately loose. It bounds the query, not the result. def merged_pull_requests(base, since_ref) committed_at = git_quietly("log", "-1", "--format=%cI", since_ref).strip - raise "Failed to resolve #{since_ref}" unless $?.success? + raise "Failed to resolve #{since_ref}" unless Process.last_status.success? since = (Time.iso8601(committed_at) - 86_400).utc.strftime("%Y-%m-%d") json = `gh pr list --repo ruby/rubygems --state merged --base #{base} --search 'merged:>=#{since}' --limit #{MERGED_PULL_REQUEST_LIMIT} --json number,id,title,labels,mergeCommit,mergedAt,author,url` - raise "Failed to list pull requests merged into #{base} since #{since}" unless $?.success? + raise "Failed to list pull requests merged into #{base} since #{since}" unless Process.last_status.success? pull_requests_from(json, "#{base} since #{since}") end