From 82e796b1ebf5845e60713dbfdab963b6aa23041c Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Fri, 20 Feb 2026 23:49:51 +0100 Subject: [PATCH 1/6] Revert "[Bug #19831] Remove duplicate library warning" This reverts commit d256629bf9e194838d1837be74dcc0b8ff0bcfd6. --- configure.ac | 3 --- template/Makefile.in | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index c426931b396f21..05e2e9aca26ddf 100644 --- a/configure.ac +++ b/configure.ac @@ -4342,9 +4342,6 @@ AS_IF([test -n "${LIBS}"], [ MAINFLAGS=`echo " $MAINLIBS " | sed "s|$libspat"'||;s/^ *//;s/ *$//'` ]) LIBRUBYARG_STATIC="${LIBRUBYARG_STATIC} \$(MAINLIBS)" -AS_IF([test "$enable_shared" = yes], [ - LIBRUBYARG_SHARED="${LIBRUBYARG_SHARED} \$(MAINLIBS)" -]) CPPFLAGS="$CPPFLAGS "'$(DEFS) ${cppflags}' AS_IF([test -n "${cflags+set}"], [ cflagspat=`eval echo '"'"${cflags}"'"' | sed 's/[[][|.*]]/\\&/g;s/^ */ /;s/^ *$/ /'` diff --git a/template/Makefile.in b/template/Makefile.in index e8b6eef6090e81..8e93efc310cd97 100644 --- a/template/Makefile.in +++ b/template/Makefile.in @@ -314,7 +314,7 @@ miniruby$(EXEEXT): $(PROGRAM): @$(RM) $@ $(ECHO) linking $@ - $(Q) $(PURIFY) $(CC) $(EXE_LDFLAGS) $(XLDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(EXTLIBS) $(OUTFLAG)$@ + $(Q) $(PURIFY) $(CC) $(EXE_LDFLAGS) $(XLDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(MAINLIBS) $(EXTLIBS) $(OUTFLAG)$@ $(Q) $(POSTLINK) $(PROGRAM): @XRUBY_LIBPATHENV_WRAPPER@ From 623f33d92f4a3b0d5d69bd36e0277fc7ecdf730b Mon Sep 17 00:00:00 2001 From: Matt Valentine-House Date: Fri, 20 Feb 2026 20:28:40 +0000 Subject: [PATCH 2/6] Relax test_thrashing_for_young_objects to fix CI flake This test has been failing intermittently on multiple CI platforms (Debian 13, RHEL 9/10, Ubuntu aarch64) with heap_allocated_pages growing from 100 to 130, or major_gc_count incrementing by 1. Failing run: https://rubyci.s3.amazonaws.com/ubuntu/ruby-master/log/20260220T001003Z.fail.html.gz The test uses assert_separately, so test ordering is not a factor. In failing runs sweep_slots (27,386) lands within ~1,200 of min_free_slots (28,652) after warmup. I've been unable to reliably replicate this. However, when looking at the failures messages all failing runs total_freed_pages is 0: pages are not being freed and reallocated in a cycle. This is distinct from [Bug #18929] where pages cycled between allocation and the tomb heap. Since total_freed_pages == 0 already guards against the thrashing from [Bug #18929], relax heap_allocated_pages to assert_in_epsilon (50% tolerance) and drop major_gc_count which follows from the same marginal threshold. --- test/ruby/test_gc.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb index 09bface652d50b..60f04f8e10cf11 100644 --- a/test/ruby/test_gc.rb +++ b/test/ruby/test_gc.rb @@ -659,10 +659,8 @@ def test_thrashing_for_young_objects debug_msg = "before_stats: #{before_stats}\nbefore_stat_heap: #{before_stat_heap}\nafter_stats: #{after_stats}\nafter_stat_heap: #{after_stat_heap}" # Should not be thrashing in page creation - assert_equal before_stats[:heap_allocated_pages], after_stats[:heap_allocated_pages], debug_msg + assert_in_epsilon before_stats[:heap_allocated_pages], after_stats[:heap_allocated_pages], 0.5, debug_msg assert_equal 0, after_stats[:total_freed_pages], debug_msg - # Only young objects, so should not trigger major GC - assert_equal before_stats[:major_gc_count], after_stats[:major_gc_count], debug_msg RUBY end From 769b8de476f10d5552cf7c7c10a3d42f7d8d20bc Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 20 Feb 2026 02:36:16 +0900 Subject: [PATCH 3/6] colorize: Support background color --- tool/lib/colorize.rb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tool/lib/colorize.rb b/tool/lib/colorize.rb index 056b27c7bf6dad..7376fc7a1ab13b 100644 --- a/tool/lib/colorize.rb +++ b/tool/lib/colorize.rb @@ -32,6 +32,12 @@ def initialize(color = nil, opts = ((_, color = color, nil)[0] if Hash === color "bold"=>"1", "faint"=>"2", "underline"=>"4", "reverse"=>"7", "bright_black"=>"90", "bright_red"=>"91", "bright_green"=>"92", "bright_yellow"=>"93", "bright_blue"=>"94", "bright_magenta"=>"95", "bright_cyan"=>"96", "bright_white"=>"97", + "bg_black"=>"40", "bg_red"=>"41", "bg_green"=>"42", "bg_yellow"=>"43", + "bg_blue"=>"44", "bg_magenta"=>"45", "bg_cyan"=>"46", "bg_white"=>"47", + "bg_bright_black"=>"100", "bg_bright_red"=>"101", + "bg_bright_green"=>"102", "bg_bright_yellow"=>"103", + "bg_bright_blue"=>"104", "bg_bright_magenta"=>"105", + "bg_bright_cyan"=>"106", "bg_bright_white"=>"107", # abstract decorations "pass"=>"green", "fail"=>"red;bold", "skip"=>"yellow;bold", @@ -70,7 +76,7 @@ def resolve_color(color = @color, seen = {}, colors = nil) def reset_color(colors) resets = [] - colors.scan(/\G;*\K(?:[34]8;5;\d+|2(?:;\d+){3}|\d+)/) do |c| + colors.scan(/\G;*\K(?:[34]8;(?:5;\d+|2(?:;\d+){3})|\d+)/) do |c| case c when '1', '2' resets << '22' @@ -78,9 +84,9 @@ def reset_color(colors) resets << '24' when '7' resets << '27' - when /\A3\d\z/ + when /\A[39]\d(?:;|\z)/ resets << '39' - when /\A4\d\z/ + when /\A(?:4|10)\d(?:;|\z)/ resets << '49' end end From 2794351c9f1c2b6b65dac1bb6c978971c064b383 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 20 Feb 2026 02:38:45 +0900 Subject: [PATCH 4/6] colorize: Refactor #initialize Use keyword arguments and extract repeated regexps as constant. --- tool/lib/colorize.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tool/lib/colorize.rb b/tool/lib/colorize.rb index 7376fc7a1ab13b..770a040b167ca8 100644 --- a/tool/lib/colorize.rb +++ b/tool/lib/colorize.rb @@ -4,16 +4,16 @@ class Colorize # call-seq: # Colorize.new(colorize = nil) # Colorize.new(color: color, colors_file: colors_file) - def initialize(color = nil, opts = ((_, color = color, nil)[0] if Hash === color)) + def initialize(_color = nil, color: _color, colors_file: nil) @colors = nil - @color = opts && opts[:color] || color + @color = color if color or (color == nil && coloring?) - if (%w[smso so].any? {|attr| /\A\e\[.*m\z/ =~ IO.popen("tput #{attr}", "r", :err => IO::NULL, &:read)} rescue nil) + if (%w[smso so].any? {|attr| /\A\e\[.*m\z/ =~ IO.popen("tput #{attr}", "r", err: IO::NULL, &:read)} rescue nil) @beg = "\e[" - colors = (colors = ENV['TEST_COLORS']) ? Hash[colors.scan(/(\w+)=([^:\n]*)/)] : {} - if opts and colors_file = opts[:colors_file] + colors = (colors = ENV['TEST_COLORS']) ? Hash[colors.scan(COLORS_PATTERN)] : {} + if colors_file begin - File.read(colors_file).scan(/(\w+)=([^:\n]*)/) do |n, c| + File.read(colors_file).scan(COLORS_PATTERN) do |n, c| colors[n] ||= c end rescue Errno::ENOENT @@ -25,6 +25,8 @@ def initialize(color = nil, opts = ((_, color = color, nil)[0] if Hash === color self end + COLORS_PATTERN = /(\w+)=([^:\n]*)/ + DEFAULTS = { # color names "black"=>"30", "red"=>"31", "green"=>"32", "yellow"=>"33", From 1fb58853c899883b5ceb115080671b3c446e64d2 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 20 Feb 2026 10:29:55 +0900 Subject: [PATCH 5/6] colorize: Make internal methods/constants private --- tool/lib/colorize.rb | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tool/lib/colorize.rb b/tool/lib/colorize.rb index 770a040b167ca8..d97e0c901dcff6 100644 --- a/tool/lib/colorize.rb +++ b/tool/lib/colorize.rb @@ -26,6 +26,7 @@ def initialize(_color = nil, color: _color, colors_file: nil) end COLORS_PATTERN = /(\w+)=([^:\n]*)/ + private_constant :COLORS_PATTERN DEFAULTS = { # color names @@ -44,11 +45,8 @@ def initialize(_color = nil, color: _color, colors_file: nil) # abstract decorations "pass"=>"green", "fail"=>"red;bold", "skip"=>"yellow;bold", "note"=>"bright_yellow", "notice"=>"bright_yellow", "info"=>"bright_magenta", - } - - def coloring? - STDOUT.tty? && (!(nc = ENV['NO_COLOR']) || nc.empty?) - end + }.freeze + private_constant :DEFAULTS # colorize.decorate(str, name = color_name) def decorate(str, name = @color) @@ -59,6 +57,18 @@ def decorate(str, name = @color) end end + DEFAULTS.each_key do |name| + define_method(name) {|str| + decorate(str, name) + } + end + + private + + def coloring? + STDOUT.tty? && (!(nc = ENV['NO_COLOR']) || nc.empty?) + end + def resolve_color(color = @color, seen = {}, colors = nil) return unless @colors color.to_s.gsub(/\b[a-z][\w ]+/) do |n| @@ -94,12 +104,6 @@ def reset_color(colors) end "#{@beg}#{resets.reverse.join(';')}m" end - - DEFAULTS.each_key do |name| - define_method(name) {|str| - decorate(str, name) - } - end end if $0 == __FILE__ From a0d9b69cd3342b38b02a55a652cff9bd272953fd Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 20 Feb 2026 10:30:33 +0900 Subject: [PATCH 6/6] colorize: [DOC] Add documents --- tool/lib/colorize.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tool/lib/colorize.rb b/tool/lib/colorize.rb index d97e0c901dcff6..89da90e075756b 100644 --- a/tool/lib/colorize.rb +++ b/tool/lib/colorize.rb @@ -1,9 +1,13 @@ # frozen-string-literal: true +# Decorate TTY output using ANSI Select Graphic Rendition control +# sequences. class Colorize # call-seq: # Colorize.new(colorize = nil) # Colorize.new(color: color, colors_file: colors_file) + # + # Creates and load color settings. def initialize(_color = nil, color: _color, colors_file: nil) @colors = nil @color = color