From 41e24aeb1a432c13ff484a055077d00d93668201 Mon Sep 17 00:00:00 2001 From: Misaki Shioi <31817032+shioimm@users.noreply.github.com> Date: Wed, 17 Dec 2025 22:06:53 +0900 Subject: [PATCH 1/6] Improve NEWS.md for Socket (#15610) --- NEWS.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 4734a93f4cf75d..6b18ae4c725ba5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -227,8 +227,9 @@ Note: We're only listing outstanding class updates. * When a user-specified timeout occurred in `TCPSocket.new`, either `Errno::ETIMEDOUT` or `IO::TimeoutError` could previously be raised depending on the situation. This behavior has been unified so that `IO::TimeoutError` is now consistently raised. - (Please note that, in `Socket.tcp`, there are still cases where `Errno::ETIMEDOUT` may - be raised in similar situations.) + (Please note that, in `Socket.tcp`, there are still cases where `Errno::ETIMEDOUT` + may be raised in similar situations, and that in both cases `Errno::ETIMEDOUT` may be + raised when the timeout occurs at the OS level.) * String From 56b67f1684bf1955cf69fc06701e2a710898bd9b Mon Sep 17 00:00:00 2001 From: Luke Gruber Date: Wed, 17 Dec 2025 12:17:30 -0500 Subject: [PATCH 2/6] ObjectSpace.{dump,dump_all,dump_shapes} needs vm barrier. (#15569) This allows these methods to be called from ractors. Add new exported function `rb_vm_lock_with_barrier()` that requires users to include "vm_sync.h" --- ext/objspace/objspace_dump.c | 56 +++++++++++++++++++++++++++++----- test/objspace/test_objspace.rb | 21 +++++++++++++ vm_sync.c | 11 +++++++ vm_sync.h | 4 +++ 4 files changed, 85 insertions(+), 7 deletions(-) diff --git a/ext/objspace/objspace_dump.c b/ext/objspace/objspace_dump.c index 30829d5ee10058..da64698346c495 100644 --- a/ext/objspace/objspace_dump.c +++ b/ext/objspace/objspace_dump.c @@ -29,7 +29,7 @@ #include "ruby/util.h" #include "ruby/io.h" #include "vm_callinfo.h" -#include "vm_core.h" +#include "vm_sync.h" RUBY_EXTERN const char ruby_hexdigits[]; @@ -771,15 +771,16 @@ dump_result(struct dump_config *dc) return dc->given_output; } -/* :nodoc: */ static VALUE -objspace_dump(VALUE os, VALUE obj, VALUE output) +dump_locked(void *args_p) { struct dump_config dc = {0,}; + VALUE obj = ((VALUE*)args_p)[0]; + VALUE output = ((VALUE*)args_p)[1]; + if (!RB_SPECIAL_CONST_P(obj)) { dc.cur_page_slot_size = rb_gc_obj_slot_size(obj); } - dump_output(&dc, output, Qnil, Qnil, Qnil); dump_object(obj, &dc); @@ -787,6 +788,16 @@ objspace_dump(VALUE os, VALUE obj, VALUE output) return dump_result(&dc); } +/* :nodoc: */ +static VALUE +objspace_dump(VALUE os, VALUE obj, VALUE output) +{ + VALUE args[2]; + args[0] = obj; + args[1] = output; + return rb_vm_lock_with_barrier(dump_locked, (void*)args); +} + static void shape_id_i(shape_id_t shape_id, void *data) { @@ -835,11 +846,15 @@ shape_id_i(shape_id_t shape_id, void *data) dump_append(dc, "}\n"); } -/* :nodoc: */ static VALUE -objspace_dump_all(VALUE os, VALUE output, VALUE full, VALUE since, VALUE shapes) +dump_all_locked(void *args_p) { struct dump_config dc = {0,}; + VALUE output = ((VALUE*)args_p)[0]; + VALUE full = ((VALUE*)args_p)[1]; + VALUE since = ((VALUE*)args_p)[2]; + VALUE shapes = ((VALUE*)args_p)[3]; + dump_output(&dc, output, full, since, shapes); if (!dc.partial_dump || dc.since == 0) { @@ -860,9 +875,23 @@ objspace_dump_all(VALUE os, VALUE output, VALUE full, VALUE since, VALUE shapes) /* :nodoc: */ static VALUE -objspace_dump_shapes(VALUE os, VALUE output, VALUE shapes) +objspace_dump_all(VALUE os, VALUE output, VALUE full, VALUE since, VALUE shapes) +{ + VALUE args[4]; + args[0] = output; + args[1] = full; + args[2] = since; + args[3] = shapes; + return rb_vm_lock_with_barrier(dump_all_locked, (void*)args); +} + +static VALUE +dump_shapes_locked(void *args_p) { struct dump_config dc = {0,}; + VALUE output = ((VALUE*)args_p)[0]; + VALUE shapes = ((VALUE*)args_p)[1]; + dump_output(&dc, output, Qfalse, Qnil, shapes); if (RTEST(shapes)) { @@ -871,6 +900,16 @@ objspace_dump_shapes(VALUE os, VALUE output, VALUE shapes) return dump_result(&dc); } +/* :nodoc: */ +static VALUE +objspace_dump_shapes(VALUE os, VALUE output, VALUE shapes) +{ + VALUE args[2]; + args[0] = output; + args[1] = shapes; + return rb_vm_lock_with_barrier(dump_shapes_locked, (void*)args); +} + void Init_objspace_dump(VALUE rb_mObjSpace) { @@ -878,6 +917,9 @@ Init_objspace_dump(VALUE rb_mObjSpace) #if 0 rb_mObjSpace = rb_define_module("ObjectSpace"); /* let rdoc know */ #endif +#ifdef HAVE_RB_EXT_RACTOR_SAFE + RB_EXT_RACTOR_SAFE(true); +#endif rb_define_module_function(rb_mObjSpace, "_dump", objspace_dump, 2); rb_define_module_function(rb_mObjSpace, "_dump_all", objspace_dump_all, 4); diff --git a/test/objspace/test_objspace.rb b/test/objspace/test_objspace.rb index ea3c6aa7192146..3d5b2a4d2ae559 100644 --- a/test/objspace/test_objspace.rb +++ b/test/objspace/test_objspace.rb @@ -827,6 +827,27 @@ def dump_my_heap_please end end + def test_dump_all_with_ractors + assert_ractor("#{<<-"begin;"}#{<<-'end;'}") + begin; + require "objspace" + require "tempfile" + require "json" + rs = 4.times.map do + Ractor.new do + Tempfile.create do |f| + ObjectSpace.dump_all(output: f) + f.close + File.readlines(f.path).each do |line| + JSON.parse(line) + end + end + end + end + rs.each(&:join) + end; + end + def test_dump_uninitialized_file assert_in_out_err(%[-robjspace], <<-RUBY) do |(output), (error)| puts ObjectSpace.dump(File.allocate) diff --git a/vm_sync.c b/vm_sync.c index 6d93720701bad9..aca83dde5a73aa 100644 --- a/vm_sync.c +++ b/vm_sync.c @@ -297,3 +297,14 @@ rb_ec_vm_lock_rec_release(const rb_execution_context_t *ec, VM_ASSERT(recorded_lock_rec == rb_ec_vm_lock_rec(ec)); } + +VALUE +rb_vm_lock_with_barrier(VALUE (*func)(void *args), void *args) +{ + VALUE result = 0; + RB_VM_LOCKING() { + rb_vm_barrier(); + result = func(args); + } + return result; +} diff --git a/vm_sync.h b/vm_sync.h index 15dfff4d0b9fe1..314a2238a96581 100644 --- a/vm_sync.h +++ b/vm_sync.h @@ -28,6 +28,10 @@ void rb_vm_lock_leave_body_nb(unsigned int *lev APPEND_LOCATION_ARGS); void rb_vm_lock_leave_body(unsigned int *lev APPEND_LOCATION_ARGS); void rb_vm_barrier(void); +RUBY_SYMBOL_EXPORT_BEGIN +VALUE rb_vm_lock_with_barrier(VALUE (*func)(void *args), void *args); +RUBY_SYMBOL_EXPORT_END + #if RUBY_DEBUG // GET_VM() #include "vm_core.h" From 7e13fbc0ed013d03444158cda7e800e9c0eb4ddf Mon Sep 17 00:00:00 2001 From: tomoya ishida Date: Thu, 18 Dec 2025 03:04:49 +0900 Subject: [PATCH 3/6] Update bundled bigdecimal and rbs (#15611) * Bundle rbs-3.10.0.pre.1 * Update rbs gem entry with commit hash Updated rbs entry to include commit hash. * Fix rbs entry in bundled_gems * Update rbs gem to version 3.10.0.pre.2 Updated rbs gem version from 3.10.0.pre.1 to 3.10.0.pre.2. * Update bundled bigdecimal to v4.0.1 --------- Co-authored-by: Soutaro Matsumoto --- NEWS.md | 2 +- gems/bundled_gems | 4 +- .../library/bigdecimal/BigDecimal_spec.rb | 40 +----------- spec/ruby/library/bigdecimal/divmod_spec.rb | 61 +++++++++++++------ spec/ruby/library/bigdecimal/precs_spec.rb | 55 ----------------- tool/rbs_skip_tests | 53 +--------------- 6 files changed, 51 insertions(+), 164 deletions(-) delete mode 100644 spec/ruby/library/bigdecimal/precs_spec.rb diff --git a/NEWS.md b/NEWS.md index 6b18ae4c725ba5..a485c70ec53e3c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -337,7 +337,7 @@ The following bundled gems are updated. * typeprof 0.31.0 * debug 1.11.0 * base64 0.3.0 -* bigdecimal 3.3.1 +* bigdecimal 4.0.1 * drb 2.2.3 * syslog 0.3.0 * csv 3.3.5 diff --git a/gems/bundled_gems b/gems/bundled_gems index d71137d3e11fab..f393f19f1cd3d8 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -18,14 +18,14 @@ net-pop 0.1.2 https://github.com/ruby/net-pop net-smtp 0.5.1 https://github.com/ruby/net-smtp matrix 0.4.3 https://github.com/ruby/matrix prime 0.1.4 https://github.com/ruby/prime -rbs 3.9.5 https://github.com/ruby/rbs 22451ecbe262326176eb3915b64366712930685c # waiting for https://github.com/ruby/rbs/pull/2706 +rbs 3.10.0.pre.2 https://github.com/ruby/rbs typeprof 0.31.0 https://github.com/ruby/typeprof debug 1.11.0 https://github.com/ruby/debug racc 1.8.1 https://github.com/ruby/racc mutex_m 0.3.0 https://github.com/ruby/mutex_m getoptlong 0.2.1 https://github.com/ruby/getoptlong base64 0.3.0 https://github.com/ruby/base64 -bigdecimal 3.3.1 https://github.com/ruby/bigdecimal +bigdecimal 4.0.1 https://github.com/ruby/bigdecimal observer 0.1.2 https://github.com/ruby/observer abbrev 0.1.2 https://github.com/ruby/abbrev resolv-replace 0.1.1 https://github.com/ruby/resolv-replace diff --git a/spec/ruby/library/bigdecimal/BigDecimal_spec.rb b/spec/ruby/library/bigdecimal/BigDecimal_spec.rb index 01772bf9af7d8e..8596356abdb444 100644 --- a/spec/ruby/library/bigdecimal/BigDecimal_spec.rb +++ b/spec/ruby/library/bigdecimal/BigDecimal_spec.rb @@ -31,16 +31,12 @@ end it "accepts significant digits >= given precision" do - suppress_warning do - BigDecimal("3.1415923", 10).precs[1].should >= 10 - end + BigDecimal("3.1415923", 10).should == BigDecimal("3.1415923") end it "determines precision from initial value" do pi_string = "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593014782083152134043" - suppress_warning { - BigDecimal(pi_string).precs[1] - }.should >= pi_string.size-1 + BigDecimal(pi_string).precision.should == pi_string.size-1 end it "ignores leading and trailing whitespace" do @@ -208,14 +204,6 @@ def to_s; "cheese"; end Float(@b).to_s.should == "166.66666666666666" end - it "has the expected precision on the LHS" do - suppress_warning { @a.precs[0] }.should == 18 - end - - it "has the expected maximum precision on the LHS" do - suppress_warning { @a.precs[1] }.should == 27 - end - it "produces the expected result when done via Float" do (Float(@a) - Float(@b)).to_s.should == "-6.666596163995564e-10" end @@ -226,34 +214,10 @@ def to_s; "cheese"; end # Check underlying methods work as we understand - it "BigDecimal precision is the number of digits rounded up to a multiple of nine" do - 1.upto(100) do |n| - b = BigDecimal('4' * n) - precs, _ = suppress_warning { b.precs } - (precs >= 9).should be_true - (precs >= n).should be_true - (precs % 9).should == 0 - end - suppress_warning { BigDecimal('NaN').precs[0] }.should == 9 - end - - it "BigDecimal maximum precision is nine more than precision except for abnormals" do - 1.upto(100) do |n| - b = BigDecimal('4' * n) - precs, max = suppress_warning { b.precs } - max.should == precs + 9 - end - suppress_warning { BigDecimal('NaN').precs[1] }.should == 9 - end - it "BigDecimal(Rational, 18) produces the result we expect" do BigDecimal(@b, 18).to_s.should == "0.166666666666666667e3" end - it "BigDecimal(Rational, BigDecimal.precs[0]) produces the result we expect" do - BigDecimal(@b, suppress_warning { @a.precs[0] }).to_s.should == "0.166666666666666667e3" - end - # Check the top-level expression works as we expect it "produces a BigDecimal" do diff --git a/spec/ruby/library/bigdecimal/divmod_spec.rb b/spec/ruby/library/bigdecimal/divmod_spec.rb index c519783d145a00..85c014bb8c0c37 100644 --- a/spec/ruby/library/bigdecimal/divmod_spec.rb +++ b/spec/ruby/library/bigdecimal/divmod_spec.rb @@ -33,14 +33,16 @@ class BigDecimal end end - it_behaves_like :bigdecimal_modulo, :mod_part_of_divmod + version_is BigDecimal::VERSION, ""..."4.0.0" do + it_behaves_like :bigdecimal_modulo, :mod_part_of_divmod + end it "raises ZeroDivisionError if other is zero" do bd5667 = BigDecimal("5667.19") - + zero = BigDecimal("0") -> { bd5667.mod_part_of_divmod(0) }.should raise_error(ZeroDivisionError) -> { bd5667.mod_part_of_divmod(BigDecimal("0")) }.should raise_error(ZeroDivisionError) - -> { @zero.mod_part_of_divmod(@zero) }.should raise_error(ZeroDivisionError) + -> { zero.mod_part_of_divmod(zero) }.should raise_error(ZeroDivisionError) end end @@ -73,14 +75,25 @@ class BigDecimal @zeroes = [@zero, @zero_pos, @zero_neg] end - it "divides value, returns an array" do - res = @a.divmod(5) - res.kind_of?(Array).should == true + version_is BigDecimal::VERSION, ""..."4.0.0" do + it "divides value, returns [BigDecimal, BigDecimal]" do + res = @a.divmod(5) + res.kind_of?(Array).should == true + DivmodSpecs.check_both_bigdecimal(res) + end + end + + version_is BigDecimal::VERSION, "4.0.0" do + it "divides value, returns [Integer, BigDecimal]" do + res = @a.divmod(5) + res.kind_of?(Array).should == true + res[0].kind_of?(Integer).should == true + res[1].kind_of?(BigDecimal).should == true + end end it "array contains quotient and modulus as BigDecimal" do res = @a.divmod(5) - DivmodSpecs.check_both_bigdecimal(res) res[0].should == BigDecimal('0.8E1') res[1].should == BigDecimal('2.00000000000000000001') @@ -123,17 +136,27 @@ class BigDecimal values_and_zeroes.each do |val1| values.each do |val2| res = val1.divmod(val2) - DivmodSpecs.check_both_bigdecimal(res) res[0].should == ((val1/val2).floor) res[1].should == (val1 - res[0] * val2) end end end - it "returns an array of two NaNs if NaN is involved" do - (@special_vals + @regular_vals + @zeroes).each do |val| - DivmodSpecs.check_both_nan(val.divmod(@nan)) - DivmodSpecs.check_both_nan(@nan.divmod(val)) + version_is BigDecimal::VERSION, "4.0.0" do + it "raise FloatDomainError error if NaN is involved" do + (@special_vals + @regular_vals + @zeroes).each do |val| + -> { val.divmod(@nan) }.should raise_error(FloatDomainError) + -> { @nan.divmod(val) }.should raise_error(FloatDomainError) + end + end + end + + version_is BigDecimal::VERSION, ""..."4.0.0" do + it "returns an array of two NaNs if NaN is involved" do + (@special_vals + @regular_vals + @zeroes).each do |val| + DivmodSpecs.check_both_nan(val.divmod(@nan)) + DivmodSpecs.check_both_nan(@nan.divmod(val)) + end end end @@ -145,12 +168,14 @@ class BigDecimal end end - it "returns an array of Infinity and NaN if the dividend is Infinity" do - @regular_vals.each do |val| - array = @infinity.divmod(val) - array.length.should == 2 - array[0].infinite?.should == (val > 0 ? 1 : -1) - array[1].should.nan? + version_is BigDecimal::VERSION, ""..."4.0.0" do + it "returns an array of Infinity and NaN if the dividend is Infinity" do + @regular_vals.each do |val| + array = @infinity.divmod(val) + array.length.should == 2 + array[0].infinite?.should == (val > 0 ? 1 : -1) + array[1].should.nan? + end end end diff --git a/spec/ruby/library/bigdecimal/precs_spec.rb b/spec/ruby/library/bigdecimal/precs_spec.rb deleted file mode 100644 index 5fda8d30879a56..00000000000000 --- a/spec/ruby/library/bigdecimal/precs_spec.rb +++ /dev/null @@ -1,55 +0,0 @@ -require_relative '../../spec_helper' -require 'bigdecimal' - -describe "BigDecimal#precs" do - before :each do - @infinity = BigDecimal("Infinity") - @infinity_neg = BigDecimal("-Infinity") - @nan = BigDecimal("NaN") - @zero = BigDecimal("0") - @zero_neg = BigDecimal("-0") - - @arr = [BigDecimal("2E40001"), BigDecimal("3E-20001"),\ - @infinity, @infinity_neg, @nan, @zero, @zero_neg] - @precision = BigDecimal::BASE.to_s.length - 1 - end - - it "returns array of two values" do - suppress_warning do - @arr.each do |x| - x.precs.kind_of?(Array).should == true - x.precs.size.should == 2 - end - end - end - - it "returns Integers as array values" do - suppress_warning do - @arr.each do |x| - x.precs[0].kind_of?(Integer).should == true - x.precs[1].kind_of?(Integer).should == true - end - end - end - - it "returns the current value of significant digits as the first value" do - suppress_warning do - BigDecimal("3.14159").precs[0].should >= 6 - BigDecimal('1').precs[0].should == BigDecimal('1' + '0' * 100).precs[0] - [@infinity, @infinity_neg, @nan, @zero, @zero_neg].each do |value| - value.precs[0].should <= @precision - end - end - end - - it "returns the maximum number of significant digits as the second value" do - suppress_warning do - BigDecimal("3.14159").precs[1].should >= 6 - BigDecimal('1').precs[1].should >= 1 - BigDecimal('1' + '0' * 100).precs[1].should >= 101 - [@infinity, @infinity_neg, @nan, @zero, @zero_neg].each do |value| - value.precs[1].should >= 1 - end - end - end -end diff --git a/tool/rbs_skip_tests b/tool/rbs_skip_tests index 4a5307a03ee4bb..05ffb4da2771a5 100644 --- a/tool/rbs_skip_tests +++ b/tool/rbs_skip_tests @@ -46,53 +46,6 @@ test_new(RegexpSingletonTest) ## Failed tests caused by unreleased version of Ruby -# https://github.com/ruby/openssl/pull/774 -test_params(OpenSSLDHTest) - -# RBS isn't compatible with RDoc 6.13 -RDocPluginParserTest - -# https://github.com/ruby/json/pull/773 -test_load(JSONInstanceTest) -test_load(JSONSingletonTest) - -# https://github.com/ruby/json/pull/775 -test_fast_unparse(JSONInstanceTest) -test_pretty_unparse(JSONInstanceTest) -test_restore(JSONInstanceTest) -test_unparse(JSONInstanceTest) -test_fast_unparse(JSONSingletonTest) -test_pretty_unparse(JSONSingletonTest) -test_restore(JSONSingletonTest) -test_unparse(JSONSingletonTest) - -# https://github.com/ruby/json/pull/779 -test_iconv(JSONSingletonTest) - -# https://github.com/ruby/json/pull/774 -test_recurse_proc(JSONInstanceTest) -test_recurse_proc(JSONSingletonTest) - -test_deep_const_get(JSONSingletonTest) - -CGITest CGI is retired -CGISingletonTest CGI is retired - -RactorSingletonTest Ractor API was changed https://bugs.ruby-lang.org/issues/21262 -RactorInstanceTest Ractor API was changed https://bugs.ruby-lang.org/issues/21262 - -# https://github.com/ruby/fileutils/pull/139 -# https://github.com/ruby/actions/actions/runs/16425309325/job/46414287784 -test_ln_sr(FileUtilsSingletonTest) - -# https://github.com/ruby/ruby/pull/14303 -# NoMethodError: undefined method 'respond_to?' for an instance of RBS::UnitTest::Convertibles::ToStr -test_join(PathnameInstanceTest) -test_plus(PathnameInstanceTest) -test_relative_path_from(PathnameInstanceTest) -test_slash(PathnameInstanceTest) -test_Pathname(PathnameKernelTest) -test_initialize(PathnameSingletonTest) - -# [Feature #20925] `size` of Enumerator created by `produce` returns `nil` instead of `Float::INFINITY`, unless `size:` is specified. -test_produce(EnumeratorSingletonTest) +# BigDecimal v4.0.0 changed behavior +test_divmod(BigDecimalTest) +test_precs(BigDecimalTest) From a9526ab50ca693755cd841da1c73855448453dfb Mon Sep 17 00:00:00 2001 From: git Date: Wed, 17 Dec 2025 18:05:21 +0000 Subject: [PATCH 4/6] Update bundled gems list as of 2025-12-17 --- NEWS.md | 6 +++--- gems/bundled_gems | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/NEWS.md b/NEWS.md index a485c70ec53e3c..70ef9c31eab2dc 100644 --- a/NEWS.md +++ b/NEWS.md @@ -271,7 +271,7 @@ The following bundled gems are promoted from default gems. * logger 1.7.0 * rdoc 6.17.0 * win32ole 1.9.2 -* irb 1.15.3 +* irb 1.16.0 * reline 0.6.3 * readline 0.0.4 * fiddle 1.1.8 @@ -329,11 +329,11 @@ The following bundled gems are updated. * test-unit 3.7.3 * rexml 3.4.4 * net-ftp 0.3.9 -* net-imap 0.5.12 +* net-imap 0.6.1 * net-smtp 0.5.1 * matrix 0.4.3 * prime 0.1.4 -* rbs 3.9.5 +* rbs 3.10.0.pre.2 * typeprof 0.31.0 * debug 1.11.0 * base64 0.3.0 diff --git a/gems/bundled_gems b/gems/bundled_gems index f393f19f1cd3d8..559b7126db1bfe 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -13,7 +13,7 @@ test-unit 3.7.3 https://github.com/test-unit/test-unit rexml 3.4.4 https://github.com/ruby/rexml rss 0.3.1 https://github.com/ruby/rss net-ftp 0.3.9 https://github.com/ruby/net-ftp -net-imap 0.5.12 https://github.com/ruby/net-imap +net-imap 0.6.1 https://github.com/ruby/net-imap net-pop 0.1.2 https://github.com/ruby/net-pop net-smtp 0.5.1 https://github.com/ruby/net-smtp matrix 0.4.3 https://github.com/ruby/matrix @@ -41,7 +41,7 @@ benchmark 0.5.0 https://github.com/ruby/benchmark logger 1.7.0 https://github.com/ruby/logger rdoc 6.17.0 https://github.com/ruby/rdoc win32ole 1.9.2 https://github.com/ruby/win32ole -irb 1.15.3 https://github.com/ruby/irb +irb 1.16.0 https://github.com/ruby/irb reline 0.6.3 https://github.com/ruby/reline readline 0.0.4 https://github.com/ruby/readline fiddle 1.1.8 https://github.com/ruby/fiddle From dc2a62e14c4691808f04ea0cb2de30c681e87923 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Wed, 17 Dec 2025 10:18:40 -0800 Subject: [PATCH 5/6] test_commit_email.rb: Ensure #teardown doesn't fail if test is omitted. Follow up c4e090def134f9b109991b74c027648564963763 --- tool/test/test_commit_email.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tool/test/test_commit_email.rb b/tool/test/test_commit_email.rb index c7031f6c6ef818..db441584fdaefe 100644 --- a/tool/test/test_commit_email.rb +++ b/tool/test/test_commit_email.rb @@ -36,9 +36,14 @@ def setup end def teardown - File.unlink(@sendmail) - Dir.rmdir(File.dirname(@sendmail)) - FileUtils.rm_rf(@ruby) + # Clean up temporary files if #setup was not omitted + if @sendmail + File.unlink(@sendmail) + Dir.rmdir(File.dirname(@sendmail)) + end + if @ruby + FileUtils.rm_rf(@ruby) + end end def test_sendmail_encoding From f7120860b0a76fd776ef4bf040e42a46c8aeff63 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Wed, 17 Dec 2025 10:44:28 -0800 Subject: [PATCH 6/6] test_sync_default_gems.rb: Omit if git is v2.43 or older --- tool/test/test_sync_default_gems.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tool/test/test_sync_default_gems.rb b/tool/test/test_sync_default_gems.rb index 4a2688850be12a..f9ab0aae4def92 100755 --- a/tool/test/test_sync_default_gems.rb +++ b/tool/test/test_sync_default_gems.rb @@ -2,6 +2,7 @@ require 'test/unit' require 'stringio' require 'tmpdir' +require 'rubygems/version' require_relative '../sync_default_gems' module Test_SyncDefaultGems @@ -319,9 +320,13 @@ def test_delete_after_conflict end def test_squash_merge - if RUBY_PLATFORM =~ /s390x/ - omit("git 2.43.0 bug on s390x ubuntu 24.04: BUG: log-tree.c:1058: did a remerge diff without remerge_objdir?!?") - end + # This test is known to fail with git 2.43.0, which is used by Ubuntu 24.04. + # We don't know which exact version fixed it, but we know git 2.52.0 works. + stdout, status = Open3.capture2('git', '--version', err: File::NULL) + omit 'git version check failed' unless status.success? + git_version = stdout.rstrip.delete_prefix('git version ') + omit "git #{git_version} is too old" if Gem::Version.new(git_version) < Gem::Version.new('2.44.0') + # 2---. <- branch # / \ # 1---3---3'<- merge commit with conflict resolution