From 8915627234d05724f143f08271eaa09c32f4be62 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Thu, 8 Dec 2022 16:21:25 +1300 Subject: [PATCH 01/83] Drop RDoc development dependency to avoid CI failures. (#82) --- logger.gemspec | 1 - 1 file changed, 1 deletion(-) diff --git a/logger.gemspec b/logger.gemspec index ccd4e70..d12db62 100644 --- a/logger.gemspec +++ b/logger.gemspec @@ -23,5 +23,4 @@ Gem::Specification.new do |spec| spec.add_development_dependency "bundler", ">= 0" spec.add_development_dependency "rake", ">= 12.3.3" spec.add_development_dependency "test-unit" - spec.add_development_dependency "rdoc" end From b41d7c699c19b37ddfb3c0dd4b695e0271cb7c02 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Thu, 8 Dec 2022 16:28:13 +1300 Subject: [PATCH 02/83] Only assign to `@filename` if the path is valid. (#81) --- lib/logger/log_device.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/logger/log_device.rb b/lib/logger/log_device.rb index 8683328..84277a2 100644 --- a/lib/logger/log_device.rb +++ b/lib/logger/log_device.rb @@ -79,8 +79,10 @@ def reopen(log = nil) def set_dev(log) if log.respond_to?(:write) and log.respond_to?(:close) @dev = log - if log.respond_to?(:path) - @filename = log.path + if log.respond_to?(:path) and path = log.path + if File.exist?(path) + @filename = path + end end else @dev = open_logfile(log) From 4116759ef23955b5c1bdc3c6cc322fa22572d58e Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Thu, 8 Dec 2022 12:31:30 +0900 Subject: [PATCH 03/83] Another performance improvement on the Formatter by using Kernel#sprintf over String#% (#75) * Prefer Kernel#sprintf over String#% for formatting Strings --- lib/logger/formatter.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/logger/formatter.rb b/lib/logger/formatter.rb index 34e07bc..c634dbf 100644 --- a/lib/logger/formatter.rb +++ b/lib/logger/formatter.rb @@ -3,7 +3,7 @@ class Logger # Default formatter for log messages. class Formatter - Format = "%s, [%s #%d] %5s -- %s: %s\n" + Format = "%.1s, [%s #%d] %5s -- %s: %s\n" DatetimeFormat = "%Y-%m-%dT%H:%M:%S.%6N" attr_accessor :datetime_format @@ -13,8 +13,7 @@ def initialize end def call(severity, time, progname, msg) - Format % [severity[0, 1], format_datetime(time), Process.pid, severity, progname, - msg2str(msg)] + sprintf(Format, severity, format_datetime(time), Process.pid, severity, progname, msg2str(msg)) end private From 4e8d9e27fd3b8f916cd3b370b97359f67e02c4bb Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 16 Dec 2022 15:34:16 +0900 Subject: [PATCH 04/83] Bump version to 1.5.3 --- lib/logger/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logger/version.rb b/lib/logger/version.rb index 57735f8..f85c72e 100644 --- a/lib/logger/version.rb +++ b/lib/logger/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Logger - VERSION = "1.5.2" + VERSION = "1.5.3" end From 7d97525f941bf9cfcf1d6da115c0e6ac82d0d740 Mon Sep 17 00:00:00 2001 From: Peter Goldstein Date: Wed, 28 Dec 2022 23:17:53 -0500 Subject: [PATCH 05/83] Adds Ruby 3.2 to the CI matrix. --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1efa052..2f63e7c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: name: build (${{ matrix.ruby }} / ${{ matrix.os }}) strategy: matrix: - ruby: [ 3.1, '3.0', 2.7, 2.6, 2.5, head ] + ruby: [ 3.2, 3.1, '3.0', 2.7, 2.6, 2.5, head ] os: [ ubuntu-latest, macos-latest ] runs-on: ${{ matrix.os }} steps: From 7aabb0b4aaabea3e3a226092bdf92b60bf1c9d60 Mon Sep 17 00:00:00 2001 From: Mike Perham Date: Thu, 9 Feb 2023 17:08:33 -0800 Subject: [PATCH 06/83] Add Logger#with_level{...} for block-scoped log level. (#85) * Update lib/logger/severity.rb --- CHANGELOG.md | 4 ++++ lib/logger.rb | 39 +++++++++++++++++++----------------- lib/logger/severity.rb | 19 ++++++++++++++++++ test/logger/test_severity.rb | 32 +++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c02ceaa..8960ad3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# HEAD + +* Support fiber-local log levels using `Logger#with_level` [#84](https://github.com/ruby/logger/issue/84) + # 1.4.2 * Document that shift_age of 0 disables log file rotation [#43](https://github.com/ruby/logger/pull/43) (thanks to jeremyevans) diff --git a/lib/logger.rb b/lib/logger.rb index cafebc5..4940999 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -10,6 +10,7 @@ # # A simple system for logging messages. See Logger for more documentation. +require 'fiber' require 'monitor' require 'rbconfig' @@ -380,7 +381,9 @@ class Logger include Severity # Logging severity threshold (e.g. Logger::INFO). - attr_reader :level + def level + @level_override[Fiber.current] || @level + end # Sets the log level; returns +severity+. # See {Log Level}[rdoc-ref:Logger@Log+Level]. @@ -395,24 +398,23 @@ class Logger # Logger#sev_threshold= is an alias for Logger#level=. # def level=(severity) - if severity.is_a?(Integer) - @level = severity - else - case severity.to_s.downcase - when 'debug' - @level = DEBUG - when 'info' - @level = INFO - when 'warn' - @level = WARN - when 'error' - @level = ERROR - when 'fatal' - @level = FATAL - when 'unknown' - @level = UNKNOWN + @level = Severity.coerce(severity) + end + + # Adjust the log level during the block execution for the current Fiber only + # + # logger.with_level(:debug) do + # logger.debug { "Hello" } + # end + def with_level(severity) + prev, @level_override[Fiber.current] = level, Severity.coerce(severity) + begin + yield + ensure + if prev + @level_override[Fiber.current] = prev else - raise ArgumentError, "invalid log level: #{severity}" + @level_override.delete(Fiber.current) end end end @@ -583,6 +585,7 @@ def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG, self.datetime_format = datetime_format self.formatter = formatter @logdev = nil + @level_override = {} if logdev && logdev != File::NULL @logdev = LogDevice.new(logdev, shift_age: shift_age, shift_size: shift_size, diff --git a/lib/logger/severity.rb b/lib/logger/severity.rb index b38afb7..e96fb0d 100644 --- a/lib/logger/severity.rb +++ b/lib/logger/severity.rb @@ -15,5 +15,24 @@ module Severity FATAL = 4 # An unknown message that should always be logged. UNKNOWN = 5 + + LEVELS = { + "debug" => DEBUG, + "info" => INFO, + "warn" => WARN, + "error" => ERROR, + "fatal" => FATAL, + "unknown" => UNKNOWN, + } + private_constant :LEVELS + + def self.coerce(severity) + if severity.is_a?(Integer) + severity + else + key = severity.to_s.downcase + LEVELS[key] || raise(ArgumentError, "invalid log level: #{severity}") + end + end end end diff --git a/test/logger/test_severity.rb b/test/logger/test_severity.rb index dad6347..e1069c8 100644 --- a/test/logger/test_severity.rb +++ b/test/logger/test_severity.rb @@ -3,6 +3,8 @@ require 'logger' class TestLoggerSeverity < Test::Unit::TestCase + include Logger::Severity + def test_enum logger_levels = Logger.constants levels = ["WARN", "UNKNOWN", "INFO", "FATAL", "DEBUG", "ERROR"] @@ -23,4 +25,34 @@ def test_level_assignment assert(logger.level) == Logger::Severity.const_get(level) end end + + def test_thread_local_level + logger = Logger.new(nil) + logger.level = INFO # default level + other = Logger.new(nil) + other.level = ERROR # default level + + assert_equal(other.level, ERROR) + logger.with_level(:WARN) do + assert_equal(other.level, ERROR) + assert_equal(logger.level, WARN) + + logger.with_level(DEBUG) do # verify reentrancy + assert_equal(logger.level, DEBUG) + + Thread.new do + assert_equal(logger.level, INFO) + logger.with_level(:WARN) do + assert_equal(other.level, ERROR) + assert_equal(logger.level, WARN) + end + assert_equal(logger.level, INFO) + end.join + + assert_equal(logger.level, DEBUG) + end + assert_equal(logger.level, WARN) + end + assert_equal(logger.level, INFO) + end end From e98a6493414fd76d5234496c97af51dce929b3de Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Sat, 18 Feb 2023 13:49:12 +0900 Subject: [PATCH 07/83] Use ruby/actions/.github/workflows/ruby_versions.yml@master --- .github/workflows/test.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2f63e7c..d47a0bf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,11 +3,18 @@ name: test on: [push, pull_request] jobs: + ruby-versions: + uses: ruby/actions/.github/workflows/ruby_versions.yml@master + with: + engine: cruby + min_version: 2.5 + test: + needs: ruby-versions name: build (${{ matrix.ruby }} / ${{ matrix.os }}) strategy: matrix: - ruby: [ 3.2, 3.1, '3.0', 2.7, 2.6, 2.5, head ] + ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }} os: [ ubuntu-latest, macos-latest ] runs-on: ${{ matrix.os }} steps: From 5ac1b2a335a1c784f13cfa45cb10739e6f9cad6c Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Sat, 18 Feb 2023 13:50:20 +0900 Subject: [PATCH 08/83] Try to test with JRuby and TruffleRuby --- .github/workflows/test.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d47a0bf..6d6d88b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,6 @@ jobs: ruby-versions: uses: ruby/actions/.github/workflows/ruby_versions.yml@master with: - engine: cruby min_version: 2.5 test: @@ -16,6 +15,10 @@ jobs: matrix: ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }} os: [ ubuntu-latest, macos-latest ] + exclude: + - { os: windows-latest, ruby: truffleruby } + - { os: windows-latest, ruby: truffleruby-head } + - { os: macos-latest, ruby: truffleruby } runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 From 2399cc02e1a10eab5b7c81d23e83ea7be875d002 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Sat, 18 Feb 2023 13:56:28 +0900 Subject: [PATCH 09/83] Ignore truffleruby-head --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6d6d88b..bed0af5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,8 +17,8 @@ jobs: os: [ ubuntu-latest, macos-latest ] exclude: - { os: windows-latest, ruby: truffleruby } - - { os: windows-latest, ruby: truffleruby-head } - { os: macos-latest, ruby: truffleruby } + - { ruby: truffleruby-head } runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 From 35d7cf220269bd6312523531e67246249ad0d5e6 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Sat, 18 Feb 2023 14:00:52 +0900 Subject: [PATCH 10/83] TruffleRuby is not working now --- .github/workflows/test.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bed0af5..8c07f86 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,6 +6,7 @@ jobs: ruby-versions: uses: ruby/actions/.github/workflows/ruby_versions.yml@master with: + engine: cruby-jruby min_version: 2.5 test: @@ -15,10 +16,6 @@ jobs: matrix: ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }} os: [ ubuntu-latest, macos-latest ] - exclude: - - { os: windows-latest, ruby: truffleruby } - - { os: macos-latest, ruby: truffleruby } - - { ruby: truffleruby-head } runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 From b02849bc106c7888d8a2a201be24c265ea174cfa Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Sat, 18 Feb 2023 14:03:34 +0900 Subject: [PATCH 11/83] JRuby is also not working now --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8c07f86..d47a0bf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,7 @@ jobs: ruby-versions: uses: ruby/actions/.github/workflows/ruby_versions.yml@master with: - engine: cruby-jruby + engine: cruby min_version: 2.5 test: From 644906e33199258731e4d107750a1ed46a80ea98 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Sat, 18 Feb 2023 14:03:49 +0900 Subject: [PATCH 12/83] Try with Windows --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d47a0bf..1fcf765 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }} - os: [ ubuntu-latest, macos-latest ] + os: [ ubuntu-latest, macos-latest, windows-latest ] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 From c3628ff48656e634dfecff26702fad01033d5053 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 24 Mar 2023 13:00:58 +0900 Subject: [PATCH 13/83] Update test libraries from https://github.com/ruby/ruby/commit/b4e438d8aabaf4bba2b27f374c787543fae07c58 --- test/lib/core_assertions.rb | 150 +++++++++++++++++++++--------------- test/lib/envutil.rb | 25 ++++-- 2 files changed, 108 insertions(+), 67 deletions(-) diff --git a/test/lib/core_assertions.rb b/test/lib/core_assertions.rb index df6ca00..1fdc0a3 100644 --- a/test/lib/core_assertions.rb +++ b/test/lib/core_assertions.rb @@ -3,6 +3,10 @@ module Test module Unit module Assertions + def assert_raises(*exp, &b) + raise NoMethodError, "use assert_raise", caller + end + def _assertions= n # :nodoc: @_assertions = n end @@ -16,9 +20,16 @@ def _assertions # :nodoc: def message msg = nil, ending = nil, &default proc { - msg = msg.call.chomp(".") if Proc === msg - custom_message = "#{msg}.\n" unless msg.nil? or msg.to_s.empty? - "#{custom_message}#{default.call}#{ending || "."}" + ending ||= (ending_pattern = /(? e - bt = e.backtrace - as = e.instance_of?(Test::Unit::AssertionFailedError) - if as - ans = /\A#{Regexp.quote(__FILE__)}:#{line}:in /o - bt.reject! {|ln| ans =~ ln} - end - if ((args.empty? && !as) || - args.any? {|a| a.instance_of?(Module) ? e.is_a?(a) : e.class == a }) - msg = message(msg) { - "Exception raised:\n<#{mu_pp(e)}>\n" + - "Backtrace:\n" + - e.backtrace.map{|frame| " #{frame}"}.join("\n") - } - raise Test::Unit::AssertionFailedError, msg.call, bt - else - raise - end + rescue *(args.empty? ? Exception : args) => e + msg = message(msg) { + "Exception raised:\n<#{mu_pp(e)}>\n""Backtrace:\n" << + Test.filter_backtrace(e.backtrace).map{|frame| " #{frame}"}.join("\n") + } + raise Test::Unit::AssertionFailedError, msg.call, e.backtrace end end @@ -244,13 +244,17 @@ def assert_ruby_status(args, test_stdin="", message=nil, **opt) ABORT_SIGNALS = Signal.list.values_at(*%w"ILL ABRT BUS SEGV TERM") - def separated_runner(out = nil) + def separated_runner(token, out = nil) include(*Test::Unit::TestCase.ancestors.select {|c| !c.is_a?(Class) }) out = out ? IO.new(out, 'w') : STDOUT at_exit { - out.puts [Marshal.dump($!)].pack('m'), "assertions=#{self._assertions}" + out.puts "#{token}", [Marshal.dump($!)].pack('m'), "#{token}", "#{token}assertions=#{self._assertions}" } - Test::Unit::Runner.class_variable_set(:@@stop_auto_run, true) if defined?(Test::Unit::Runner) + if defined?(Test::Unit::Runner) + Test::Unit::Runner.class_variable_set(:@@stop_auto_run, true) + elsif defined?(Test::Unit::AutoRunner) + Test::Unit::AutoRunner.need_auto_run = false + end end def assert_separately(args, file = nil, line = nil, src, ignore_stderr: nil, **opt) @@ -266,16 +270,18 @@ def assert_separately(args, file = nil, line = nil, src, ignore_stderr: nil, **o res_p, res_c = IO.pipe opt[:ios] = [res_c] end + token_dump, token_re = new_test_token src = <\n\K.*\n(?=#{token_re}<\/error>$)/m].unpack1("m")) rescue => marshal_error ignore_stderr = nil res = nil @@ -463,7 +469,7 @@ def assert_raise_with_message(exception, expected, msg = nil, &block) ex end - MINI_DIR = File.join(File.dirname(File.expand_path(__FILE__)), "minitest") #:nodoc: + TEST_DIR = File.join(__dir__, "test/unit") #:nodoc: # :call-seq: # assert(test, [failure_message]) @@ -483,7 +489,7 @@ def assert(test, *msgs) when nil msgs.shift else - bt = caller.reject { |s| s.start_with?(MINI_DIR) } + bt = caller.reject { |s| s.start_with?(TEST_DIR) } raise ArgumentError, "assertion message must be String or Proc, but #{msg.class} was given.", bt end unless msgs.empty? super @@ -506,7 +512,7 @@ def assert_respond_to(obj, (meth, *priv), msg = nil) return assert obj.respond_to?(meth, *priv), msg end #get rid of overcounting - if caller_locations(1, 1)[0].path.start_with?(MINI_DIR) + if caller_locations(1, 1)[0].path.start_with?(TEST_DIR) return if obj.respond_to?(meth) end super(obj, meth, msg) @@ -529,17 +535,17 @@ def assert_not_respond_to(obj, (meth, *priv), msg = nil) return assert !obj.respond_to?(meth, *priv), msg end #get rid of overcounting - if caller_locations(1, 1)[0].path.start_with?(MINI_DIR) + if caller_locations(1, 1)[0].path.start_with?(TEST_DIR) return unless obj.respond_to?(meth) end refute_respond_to(obj, meth, msg) end - # pattern_list is an array which contains regexp and :*. + # pattern_list is an array which contains regexp, string and :*. # :* means any sequence. # # pattern_list is anchored. - # Use [:*, regexp, :*] for non-anchored match. + # Use [:*, regexp/string, :*] for non-anchored match. def assert_pattern_list(pattern_list, actual, message=nil) rest = actual anchored = true @@ -548,11 +554,13 @@ def assert_pattern_list(pattern_list, actual, message=nil) anchored = false else if anchored - match = /\A#{pattern}/.match(rest) + match = rest.rindex(pattern, 0) else - match = pattern.match(rest) + match = rest.index(pattern) end - unless match + if match + post_match = $~ ? $~.post_match : rest[match+pattern.size..-1] + else msg = message(msg) { expect_msg = "Expected #{mu_pp pattern}\n" if /\n[^\n]/ =~ rest @@ -569,7 +577,7 @@ def assert_pattern_list(pattern_list, actual, message=nil) } assert false, msg end - rest = match.post_match + rest = post_match anchored = true end } @@ -596,14 +604,14 @@ def assert_warn(*args) def assert_deprecated_warning(mesg = /deprecated/) assert_warning(mesg) do - Warning[:deprecated] = true + Warning[:deprecated] = true if Warning.respond_to?(:[]=) yield end end def assert_deprecated_warn(mesg = /deprecated/) assert_warn(mesg) do - Warning[:deprecated] = true + Warning[:deprecated] = true if Warning.respond_to?(:[]=) yield end end @@ -641,7 +649,7 @@ def initialize def for(key) @count += 1 - yield + yield key rescue Exception => e @failures[key] = [@count, e] end @@ -695,7 +703,7 @@ def assert_join_threads(threads, message = nil) msg = "exceptions on #{errs.length} threads:\n" + errs.map {|t, err| "#{t.inspect}:\n" + - RUBY_VERSION >= "2.5.0" ? err.full_message(highlight: false, order: :top) : err.message + (err.respond_to?(:full_message) ? err.full_message(highlight: false, order: :top) : err.message) }.join("\n---\n") if message msg = "#{message}\n#{msg}" @@ -730,21 +738,36 @@ def assert_all_assertions_foreach(msg = nil, *keys, &block) end alias all_assertions_foreach assert_all_assertions_foreach - def message(msg = nil, *args, &default) # :nodoc: - if Proc === msg - super(nil, *args) do - ary = [msg.call, (default.call if default)].compact.reject(&:empty?) - if 1 < ary.length - ary[0...-1] = ary[0...-1].map {|str| str.sub(/(?(n) {n}) + first = seq.first + *arg = pre.call(first) + times = (0..(rehearsal || (2 * first))).map do + st = Process.clock_gettime(Process::CLOCK_MONOTONIC) + yield(*arg) + t = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - st) + assert_operator 0, :<=, t + t.nonzero? + end + times.compact! + tmin, tmax = times.minmax + tmax *= tmax / tmin + tmax = 10**Math.log10(tmax).ceil + + seq.each do |i| + next if i == first + t = tmax * i.fdiv(first) + *arg = pre.call(i) + message = "[#{i}]: in #{t}s" + Timeout.timeout(t, Timeout::Error, message) do + st = Process.clock_gettime(Process::CLOCK_MONOTONIC) + yield(*arg) + assert_operator (Process.clock_gettime(Process::CLOCK_MONOTONIC) - st), :<=, t, message end - else - super end end @@ -763,6 +786,11 @@ def diff(exp, act) end q.output end + + def new_test_token + token = "\e[7;1m#{$$.to_s}:#{Time.now.strftime('%s.%L')}:#{rand(0x10000).to_s(16)}:\e[m" + return token.dump, Regexp.quote(token) + end end end end diff --git a/test/lib/envutil.rb b/test/lib/envutil.rb index 0391b90..728ca70 100644 --- a/test/lib/envutil.rb +++ b/test/lib/envutil.rb @@ -152,7 +152,12 @@ def invoke_ruby(args, stdin_data = "", capture_stdout = false, capture_stderr = if RUBYLIB and lib = child_env["RUBYLIB"] child_env["RUBYLIB"] = [lib, RUBYLIB].join(File::PATH_SEPARATOR) end - child_env['ASAN_OPTIONS'] = ENV['ASAN_OPTIONS'] if ENV['ASAN_OPTIONS'] + + # remain env + %w(ASAN_OPTIONS RUBY_ON_BUG).each{|name| + child_env[name] = ENV[name] if ENV[name] + } + args = [args] if args.kind_of?(String) pid = spawn(child_env, *precommand, rubybin, *args, opt) in_c.close @@ -292,16 +297,24 @@ def self.diagnostic_reports(signame, pid, now) cmd = @ruby_install_name if "ruby-runner#{RbConfig::CONFIG["EXEEXT"]}" == cmd path = DIAGNOSTIC_REPORTS_PATH timeformat = DIAGNOSTIC_REPORTS_TIMEFORMAT - pat = "#{path}/#{cmd}_#{now.strftime(timeformat)}[-_]*.crash" + pat = "#{path}/#{cmd}_#{now.strftime(timeformat)}[-_]*.{crash,ips}" first = true 30.times do first ? (first = false) : sleep(0.1) Dir.glob(pat) do |name| log = File.read(name) rescue next - if /\AProcess:\s+#{cmd} \[#{pid}\]$/ =~ log - File.unlink(name) - File.unlink("#{path}/.#{File.basename(name)}.plist") rescue nil - return log + case name + when /\.crash\z/ + if /\AProcess:\s+#{cmd} \[#{pid}\]$/ =~ log + File.unlink(name) + File.unlink("#{path}/.#{File.basename(name)}.plist") rescue nil + return log + end + when /\.ips\z/ + if /^ *"pid" *: *#{pid},/ =~ log + File.unlink(name) + return log + end end end end From 9fe8b610b975a2f42853150e205d99911f0557ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 06:58:52 +0000 Subject: [PATCH 14/83] Bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1fcf765..6288bcd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,7 +18,7 @@ jobs: os: [ ubuntu-latest, macos-latest, windows-latest ] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: From 8c135bce9ad22925de36357ce5b295ea3107f4e0 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Thu, 21 Sep 2023 21:12:22 +0100 Subject: [PATCH 15/83] [DOC] Fix broken link --- lib/logger.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/logger.rb b/lib/logger.rb index 4940999..4be5c33 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -265,8 +265,7 @@ # logger.error! # => 3 # logger.fatal! # => 4 # -# You can retrieve the log level with method -# {level}[Logger.html#attribute-i-level]: +# You can retrieve the log level with method #level. # # logger.level = Logger::ERROR # logger.level # => 3 From 7b51af263f46fae8f6641505d44b5dbf5756f7b8 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 20 Oct 2023 11:22:44 +0900 Subject: [PATCH 16/83] Use Gemfile instead of Gem::Specification#add_development_dependency --- Gemfile | 6 ++++++ logger.gemspec | 4 ---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index d2fceab..e89f8fd 100644 --- a/Gemfile +++ b/Gemfile @@ -3,3 +3,9 @@ source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } gemspec + +group :development do + gem "bundler" + gem "rake" + gem "test-unit" +end diff --git a/logger.gemspec b/logger.gemspec index d12db62..72a0cf3 100644 --- a/logger.gemspec +++ b/logger.gemspec @@ -19,8 +19,4 @@ Gem::Specification.new do |spec| spec.require_paths = ["lib"] spec.required_ruby_version = ">= 2.3.0" - - spec.add_development_dependency "bundler", ">= 0" - spec.add_development_dependency "rake", ">= 12.3.3" - spec.add_development_dependency "test-unit" end From a32c9ee0fb6a6ccdeaf1288bae4e64621eb63e57 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 20 Oct 2023 11:22:52 +0900 Subject: [PATCH 17/83] Removed unused alias --- Gemfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Gemfile b/Gemfile index e89f8fd..3dc2883 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,5 @@ source "https://rubygems.org" -git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } - gemspec group :development do From 07d67f067433e4f7658c905d2fc1daae95ac42cc Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 20 Oct 2023 11:23:12 +0900 Subject: [PATCH 18/83] Use test-unit-ruby-core gem --- Gemfile | 1 + Rakefile | 7 - test/lib/core_assertions.rb | 796 ------------------------------------ test/lib/envutil.rb | 380 ----------------- test/lib/find_executable.rb | 22 - test/lib/helper.rb | 2 +- 6 files changed, 2 insertions(+), 1206 deletions(-) delete mode 100644 test/lib/core_assertions.rb delete mode 100644 test/lib/envutil.rb delete mode 100644 test/lib/find_executable.rb diff --git a/Gemfile b/Gemfile index 3dc2883..ba909e8 100644 --- a/Gemfile +++ b/Gemfile @@ -6,4 +6,5 @@ group :development do gem "bundler" gem "rake" gem "test-unit" + gem "test-unit-ruby-core" end diff --git a/Rakefile b/Rakefile index 24b1b37..35dd06e 100644 --- a/Rakefile +++ b/Rakefile @@ -27,11 +27,4 @@ task "gh-pages" => :rdoc do FileUtils.cp_r Dir.glob("/tmp/html/*"), "." end -task :sync_tool do - require 'fileutils' - FileUtils.cp "../ruby/tool/lib/core_assertions.rb", "./test/lib" - FileUtils.cp "../ruby/tool/lib/envutil.rb", "./test/lib" - FileUtils.cp "../ruby/tool/lib/find_executable.rb", "./test/lib" -end - task :default => :test diff --git a/test/lib/core_assertions.rb b/test/lib/core_assertions.rb deleted file mode 100644 index 1fdc0a3..0000000 --- a/test/lib/core_assertions.rb +++ /dev/null @@ -1,796 +0,0 @@ -# frozen_string_literal: true - -module Test - module Unit - module Assertions - def assert_raises(*exp, &b) - raise NoMethodError, "use assert_raise", caller - end - - def _assertions= n # :nodoc: - @_assertions = n - end - - def _assertions # :nodoc: - @_assertions ||= 0 - end - - ## - # Returns a proc that will output +msg+ along with the default message. - - def message msg = nil, ending = nil, &default - proc { - ending ||= (ending_pattern = /(? 0 and b > 0 - assert_operator(a.fdiv(b), :<, limit, message(message) {"#{n}: #{b} => #{a}"}) - end - rescue LoadError - pend - end - - # :call-seq: - # assert_nothing_raised( *args, &block ) - # - #If any exceptions are given as arguments, the assertion will - #fail if one of those exceptions are raised. Otherwise, the test fails - #if any exceptions are raised. - # - #The final argument may be a failure message. - # - # assert_nothing_raised RuntimeError do - # raise Exception #Assertion passes, Exception is not a RuntimeError - # end - # - # assert_nothing_raised do - # raise Exception #Assertion fails - # end - def assert_nothing_raised(*args) - self._assertions += 1 - if Module === args.last - msg = nil - else - msg = args.pop - end - begin - yield - rescue Test::Unit::PendedError, *(Test::Unit::AssertionFailedError if args.empty?) - raise - rescue *(args.empty? ? Exception : args) => e - msg = message(msg) { - "Exception raised:\n<#{mu_pp(e)}>\n""Backtrace:\n" << - Test.filter_backtrace(e.backtrace).map{|frame| " #{frame}"}.join("\n") - } - raise Test::Unit::AssertionFailedError, msg.call, e.backtrace - end - end - - def prepare_syntax_check(code, fname = nil, mesg = nil, verbose: nil) - fname ||= caller_locations(2, 1)[0] - mesg ||= fname.to_s - verbose, $VERBOSE = $VERBOSE, verbose - case - when Array === fname - fname, line = *fname - when defined?(fname.path) && defined?(fname.lineno) - fname, line = fname.path, fname.lineno - else - line = 1 - end - yield(code, fname, line, message(mesg) { - if code.end_with?("\n") - "```\n#{code}```\n" - else - "```\n#{code}\n```\n""no-newline" - end - }) - ensure - $VERBOSE = verbose - end - - def assert_valid_syntax(code, *args, **opt) - prepare_syntax_check(code, *args, **opt) do |src, fname, line, mesg| - yield if defined?(yield) - assert_nothing_raised(SyntaxError, mesg) do - assert_equal(:ok, syntax_check(src, fname, line), mesg) - end - end - end - - def assert_normal_exit(testsrc, message = '', child_env: nil, **opt) - assert_valid_syntax(testsrc, caller_locations(1, 1)[0]) - if child_env - child_env = [child_env] - else - child_env = [] - end - out, _, status = EnvUtil.invoke_ruby(child_env + %W'-W0', testsrc, true, :merge_to_stdout, **opt) - assert !status.signaled?, FailDesc[status, message, out] - end - - def assert_ruby_status(args, test_stdin="", message=nil, **opt) - out, _, status = EnvUtil.invoke_ruby(args, test_stdin, true, :merge_to_stdout, **opt) - desc = FailDesc[status, message, out] - assert(!status.signaled?, desc) - message ||= "ruby exit status is not success:" - assert(status.success?, desc) - end - - ABORT_SIGNALS = Signal.list.values_at(*%w"ILL ABRT BUS SEGV TERM") - - def separated_runner(token, out = nil) - include(*Test::Unit::TestCase.ancestors.select {|c| !c.is_a?(Class) }) - out = out ? IO.new(out, 'w') : STDOUT - at_exit { - out.puts "#{token}", [Marshal.dump($!)].pack('m'), "#{token}", "#{token}assertions=#{self._assertions}" - } - if defined?(Test::Unit::Runner) - Test::Unit::Runner.class_variable_set(:@@stop_auto_run, true) - elsif defined?(Test::Unit::AutoRunner) - Test::Unit::AutoRunner.need_auto_run = false - end - end - - def assert_separately(args, file = nil, line = nil, src, ignore_stderr: nil, **opt) - unless file and line - loc, = caller_locations(1,1) - file ||= loc.path - line ||= loc.lineno - end - capture_stdout = true - unless /mswin|mingw/ =~ RbConfig::CONFIG['host_os'] - capture_stdout = false - opt[:out] = Test::Unit::Runner.output if defined?(Test::Unit::Runner) - res_p, res_c = IO.pipe - opt[:ios] = [res_c] - end - token_dump, token_re = new_test_token - src = <\n\K.*\n(?=#{token_re}<\/error>$)/m].unpack1("m")) - rescue => marshal_error - ignore_stderr = nil - res = nil - end - if res and !(SystemExit === res) - if bt = res.backtrace - bt.each do |l| - l.sub!(/\A-:(\d+)/){"#{file}:#{line + $1.to_i}"} - end - bt.concat(caller) - else - res.set_backtrace(caller) - end - raise res - end - - # really is it succeed? - unless ignore_stderr - # the body of assert_separately must not output anything to detect error - assert(stderr.empty?, FailDesc[status, "assert_separately failed with error message", stderr]) - end - assert(status.success?, FailDesc[status, "assert_separately failed", stderr]) - raise marshal_error if marshal_error - end - - # Run Ractor-related test without influencing the main test suite - def assert_ractor(src, args: [], require: nil, require_relative: nil, file: nil, line: nil, ignore_stderr: nil, **opt) - return unless defined?(Ractor) - - require = "require #{require.inspect}" if require - if require_relative - dir = File.dirname(caller_locations[0,1][0].absolute_path) - full_path = File.expand_path(require_relative, dir) - require = "#{require}; require #{full_path.inspect}" - end - - assert_separately(args, file, line, <<~RUBY, ignore_stderr: ignore_stderr, **opt) - #{require} - previous_verbose = $VERBOSE - $VERBOSE = nil - Ractor.new {} # trigger initial warning - $VERBOSE = previous_verbose - #{src} - RUBY - end - - # :call-seq: - # assert_throw( tag, failure_message = nil, &block ) - # - #Fails unless the given block throws +tag+, returns the caught - #value otherwise. - # - #An optional failure message may be provided as the final argument. - # - # tag = Object.new - # assert_throw(tag, "#{tag} was not thrown!") do - # throw tag - # end - def assert_throw(tag, msg = nil) - ret = catch(tag) do - begin - yield(tag) - rescue UncaughtThrowError => e - thrown = e.tag - end - msg = message(msg) { - "Expected #{mu_pp(tag)} to have been thrown"\ - "#{%Q[, not #{thrown}] if thrown}" - } - assert(false, msg) - end - assert(true) - ret - end - - # :call-seq: - # assert_raise( *args, &block ) - # - #Tests if the given block raises an exception. Acceptable exception - #types may be given as optional arguments. If the last argument is a - #String, it will be used as the error message. - # - # assert_raise do #Fails, no Exceptions are raised - # end - # - # assert_raise NameError do - # puts x #Raises NameError, so assertion succeeds - # end - def assert_raise(*exp, &b) - case exp.last - when String, Proc - msg = exp.pop - end - - begin - yield - rescue Test::Unit::PendedError => e - return e if exp.include? Test::Unit::PendedError - raise e - rescue Exception => e - expected = exp.any? { |ex| - if ex.instance_of? Module then - e.kind_of? ex - else - e.instance_of? ex - end - } - - assert expected, proc { - flunk(message(msg) {"#{mu_pp(exp)} exception expected, not #{mu_pp(e)}"}) - } - - return e - ensure - unless e - exp = exp.first if exp.size == 1 - - flunk(message(msg) {"#{mu_pp(exp)} expected but nothing was raised"}) - end - end - end - - # :call-seq: - # assert_raise_with_message(exception, expected, msg = nil, &block) - # - #Tests if the given block raises an exception with the expected - #message. - # - # assert_raise_with_message(RuntimeError, "foo") do - # nil #Fails, no Exceptions are raised - # end - # - # assert_raise_with_message(RuntimeError, "foo") do - # raise ArgumentError, "foo" #Fails, different Exception is raised - # end - # - # assert_raise_with_message(RuntimeError, "foo") do - # raise "bar" #Fails, RuntimeError is raised but the message differs - # end - # - # assert_raise_with_message(RuntimeError, "foo") do - # raise "foo" #Raises RuntimeError with the message, so assertion succeeds - # end - def assert_raise_with_message(exception, expected, msg = nil, &block) - case expected - when String - assert = :assert_equal - when Regexp - assert = :assert_match - else - raise TypeError, "Expected #{expected.inspect} to be a kind of String or Regexp, not #{expected.class}" - end - - ex = m = nil - EnvUtil.with_default_internal(expected.encoding) do - ex = assert_raise(exception, msg || proc {"Exception(#{exception}) with message matches to #{expected.inspect}"}) do - yield - end - m = ex.message - end - msg = message(msg, "") {"Expected Exception(#{exception}) was raised, but the message doesn't match"} - - if assert == :assert_equal - assert_equal(expected, m, msg) - else - msg = message(msg) { "Expected #{mu_pp expected} to match #{mu_pp m}" } - assert expected =~ m, msg - block.binding.eval("proc{|_|$~=_}").call($~) - end - ex - end - - TEST_DIR = File.join(__dir__, "test/unit") #:nodoc: - - # :call-seq: - # assert(test, [failure_message]) - # - #Tests if +test+ is true. - # - #+msg+ may be a String or a Proc. If +msg+ is a String, it will be used - #as the failure message. Otherwise, the result of calling +msg+ will be - #used as the message if the assertion fails. - # - #If no +msg+ is given, a default message will be used. - # - # assert(false, "This was expected to be true") - def assert(test, *msgs) - case msg = msgs.first - when String, Proc - when nil - msgs.shift - else - bt = caller.reject { |s| s.start_with?(TEST_DIR) } - raise ArgumentError, "assertion message must be String or Proc, but #{msg.class} was given.", bt - end unless msgs.empty? - super - end - - # :call-seq: - # assert_respond_to( object, method, failure_message = nil ) - # - #Tests if the given Object responds to +method+. - # - #An optional failure message may be provided as the final argument. - # - # assert_respond_to("hello", :reverse) #Succeeds - # assert_respond_to("hello", :does_not_exist) #Fails - def assert_respond_to(obj, (meth, *priv), msg = nil) - unless priv.empty? - msg = message(msg) { - "Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}#{" privately" if priv[0]}" - } - return assert obj.respond_to?(meth, *priv), msg - end - #get rid of overcounting - if caller_locations(1, 1)[0].path.start_with?(TEST_DIR) - return if obj.respond_to?(meth) - end - super(obj, meth, msg) - end - - # :call-seq: - # assert_not_respond_to( object, method, failure_message = nil ) - # - #Tests if the given Object does not respond to +method+. - # - #An optional failure message may be provided as the final argument. - # - # assert_not_respond_to("hello", :reverse) #Fails - # assert_not_respond_to("hello", :does_not_exist) #Succeeds - def assert_not_respond_to(obj, (meth, *priv), msg = nil) - unless priv.empty? - msg = message(msg) { - "Expected #{mu_pp(obj)} (#{obj.class}) to not respond to ##{meth}#{" privately" if priv[0]}" - } - return assert !obj.respond_to?(meth, *priv), msg - end - #get rid of overcounting - if caller_locations(1, 1)[0].path.start_with?(TEST_DIR) - return unless obj.respond_to?(meth) - end - refute_respond_to(obj, meth, msg) - end - - # pattern_list is an array which contains regexp, string and :*. - # :* means any sequence. - # - # pattern_list is anchored. - # Use [:*, regexp/string, :*] for non-anchored match. - def assert_pattern_list(pattern_list, actual, message=nil) - rest = actual - anchored = true - pattern_list.each_with_index {|pattern, i| - if pattern == :* - anchored = false - else - if anchored - match = rest.rindex(pattern, 0) - else - match = rest.index(pattern) - end - if match - post_match = $~ ? $~.post_match : rest[match+pattern.size..-1] - else - msg = message(msg) { - expect_msg = "Expected #{mu_pp pattern}\n" - if /\n[^\n]/ =~ rest - actual_mesg = +"to match\n" - rest.scan(/.*\n+/) { - actual_mesg << ' ' << $&.inspect << "+\n" - } - actual_mesg.sub!(/\+\n\z/, '') - else - actual_mesg = "to match " + mu_pp(rest) - end - actual_mesg << "\nafter #{i} patterns with #{actual.length - rest.length} characters" - expect_msg + actual_mesg - } - assert false, msg - end - rest = post_match - anchored = true - end - } - if anchored - assert_equal("", rest) - end - end - - def assert_warning(pat, msg = nil) - result = nil - stderr = EnvUtil.with_default_internal(pat.encoding) { - EnvUtil.verbose_warning { - result = yield - } - } - msg = message(msg) {diff pat, stderr} - assert(pat === stderr, msg) - result - end - - def assert_warn(*args) - assert_warning(*args) {$VERBOSE = false; yield} - end - - def assert_deprecated_warning(mesg = /deprecated/) - assert_warning(mesg) do - Warning[:deprecated] = true if Warning.respond_to?(:[]=) - yield - end - end - - def assert_deprecated_warn(mesg = /deprecated/) - assert_warn(mesg) do - Warning[:deprecated] = true if Warning.respond_to?(:[]=) - yield - end - end - - class << (AssertFile = Struct.new(:failure_message).new) - include Assertions - include CoreAssertions - def assert_file_predicate(predicate, *args) - if /\Anot_/ =~ predicate - predicate = $' - neg = " not" - end - result = File.__send__(predicate, *args) - result = !result if neg - mesg = "Expected file ".dup << args.shift.inspect - mesg << "#{neg} to be #{predicate}" - mesg << mu_pp(args).sub(/\A\[(.*)\]\z/m, '(\1)') unless args.empty? - mesg << " #{failure_message}" if failure_message - assert(result, mesg) - end - alias method_missing assert_file_predicate - - def for(message) - clone.tap {|a| a.failure_message = message} - end - end - - class AllFailures - attr_reader :failures - - def initialize - @count = 0 - @failures = {} - end - - def for(key) - @count += 1 - yield key - rescue Exception => e - @failures[key] = [@count, e] - end - - def foreach(*keys) - keys.each do |key| - @count += 1 - begin - yield key - rescue Exception => e - @failures[key] = [@count, e] - end - end - end - - def message - i = 0 - total = @count.to_s - fmt = "%#{total.size}d" - @failures.map {|k, (n, v)| - v = v.message - "\n#{i+=1}. [#{fmt%n}/#{total}] Assertion for #{k.inspect}\n#{v.b.gsub(/^/, ' | ').force_encoding(v.encoding)}" - }.join("\n") - end - - def pass? - @failures.empty? - end - end - - # threads should respond to shift method. - # Array can be used. - def assert_join_threads(threads, message = nil) - errs = [] - values = [] - while th = threads.shift - begin - values << th.value - rescue Exception - errs << [th, $!] - th = nil - end - end - values - ensure - if th&.alive? - th.raise(Timeout::Error.new) - th.join rescue errs << [th, $!] - end - if !errs.empty? - msg = "exceptions on #{errs.length} threads:\n" + - errs.map {|t, err| - "#{t.inspect}:\n" + - (err.respond_to?(:full_message) ? err.full_message(highlight: false, order: :top) : err.message) - }.join("\n---\n") - if message - msg = "#{message}\n#{msg}" - end - raise Test::Unit::AssertionFailedError, msg - end - end - - def assert_all?(obj, m = nil, &blk) - failed = [] - obj.each do |*a, &b| - unless blk.call(*a, &b) - failed << (a.size > 1 ? a : a[0]) - end - end - assert(failed.empty?, message(m) {failed.pretty_inspect}) - end - - def assert_all_assertions(msg = nil) - all = AllFailures.new - yield all - ensure - assert(all.pass?, message(msg) {all.message.chomp(".")}) - end - alias all_assertions assert_all_assertions - - def assert_all_assertions_foreach(msg = nil, *keys, &block) - all = AllFailures.new - all.foreach(*keys, &block) - ensure - assert(all.pass?, message(msg) {all.message.chomp(".")}) - end - alias all_assertions_foreach assert_all_assertions_foreach - - # Expect +seq+ to respond to +first+ and +each+ methods, e.g., - # Array, Range, Enumerator::ArithmeticSequence and other - # Enumerable-s, and each elements should be size factors. - # - # :yield: each elements of +seq+. - def assert_linear_performance(seq, rehearsal: nil, pre: ->(n) {n}) - first = seq.first - *arg = pre.call(first) - times = (0..(rehearsal || (2 * first))).map do - st = Process.clock_gettime(Process::CLOCK_MONOTONIC) - yield(*arg) - t = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - st) - assert_operator 0, :<=, t - t.nonzero? - end - times.compact! - tmin, tmax = times.minmax - tmax *= tmax / tmin - tmax = 10**Math.log10(tmax).ceil - - seq.each do |i| - next if i == first - t = tmax * i.fdiv(first) - *arg = pre.call(i) - message = "[#{i}]: in #{t}s" - Timeout.timeout(t, Timeout::Error, message) do - st = Process.clock_gettime(Process::CLOCK_MONOTONIC) - yield(*arg) - assert_operator (Process.clock_gettime(Process::CLOCK_MONOTONIC) - st), :<=, t, message - end - end - end - - def diff(exp, act) - require 'pp' - q = PP.new(+"") - q.guard_inspect_key do - q.group(2, "expected: ") do - q.pp exp - end - q.text q.newline - q.group(2, "actual: ") do - q.pp act - end - q.flush - end - q.output - end - - def new_test_token - token = "\e[7;1m#{$$.to_s}:#{Time.now.strftime('%s.%L')}:#{rand(0x10000).to_s(16)}:\e[m" - return token.dump, Regexp.quote(token) - end - end - end -end diff --git a/test/lib/envutil.rb b/test/lib/envutil.rb deleted file mode 100644 index 728ca70..0000000 --- a/test/lib/envutil.rb +++ /dev/null @@ -1,380 +0,0 @@ -# -*- coding: us-ascii -*- -# frozen_string_literal: true -require "open3" -require "timeout" -require_relative "find_executable" -begin - require 'rbconfig' -rescue LoadError -end -begin - require "rbconfig/sizeof" -rescue LoadError -end - -module EnvUtil - def rubybin - if ruby = ENV["RUBY"] - return ruby - end - ruby = "ruby" - exeext = RbConfig::CONFIG["EXEEXT"] - rubyexe = (ruby + exeext if exeext and !exeext.empty?) - 3.times do - if File.exist? ruby and File.executable? ruby and !File.directory? ruby - return File.expand_path(ruby) - end - if rubyexe and File.exist? rubyexe and File.executable? rubyexe - return File.expand_path(rubyexe) - end - ruby = File.join("..", ruby) - end - if defined?(RbConfig.ruby) - RbConfig.ruby - else - "ruby" - end - end - module_function :rubybin - - LANG_ENVS = %w"LANG LC_ALL LC_CTYPE" - - DEFAULT_SIGNALS = Signal.list - DEFAULT_SIGNALS.delete("TERM") if /mswin|mingw/ =~ RUBY_PLATFORM - - RUBYLIB = ENV["RUBYLIB"] - - class << self - attr_accessor :timeout_scale - attr_reader :original_internal_encoding, :original_external_encoding, - :original_verbose, :original_warning - - def capture_global_values - @original_internal_encoding = Encoding.default_internal - @original_external_encoding = Encoding.default_external - @original_verbose = $VERBOSE - @original_warning = defined?(Warning.[]) ? %i[deprecated experimental].to_h {|i| [i, Warning[i]]} : nil - end - end - - def apply_timeout_scale(t) - if scale = EnvUtil.timeout_scale - t * scale - else - t - end - end - module_function :apply_timeout_scale - - def timeout(sec, klass = nil, message = nil, &blk) - return yield(sec) if sec == nil or sec.zero? - sec = apply_timeout_scale(sec) - Timeout.timeout(sec, klass, message, &blk) - end - module_function :timeout - - def terminate(pid, signal = :TERM, pgroup = nil, reprieve = 1) - reprieve = apply_timeout_scale(reprieve) if reprieve - - signals = Array(signal).select do |sig| - DEFAULT_SIGNALS[sig.to_s] or - DEFAULT_SIGNALS[Signal.signame(sig)] rescue false - end - signals |= [:ABRT, :KILL] - case pgroup - when 0, true - pgroup = -pid - when nil, false - pgroup = pid - end - - lldb = true if /darwin/ =~ RUBY_PLATFORM - - while signal = signals.shift - - if lldb and [:ABRT, :KILL].include?(signal) - lldb = false - # sudo -n: --non-interactive - # lldb -p: attach - # -o: run command - system(*%W[sudo -n lldb -p #{pid} --batch -o bt\ all -o call\ rb_vmdebug_stack_dump_all_threads() -o quit]) - true - end - - begin - Process.kill signal, pgroup - rescue Errno::EINVAL - next - rescue Errno::ESRCH - break - end - if signals.empty? or !reprieve - Process.wait(pid) - else - begin - Timeout.timeout(reprieve) {Process.wait(pid)} - rescue Timeout::Error - else - break - end - end - end - $? - end - module_function :terminate - - def invoke_ruby(args, stdin_data = "", capture_stdout = false, capture_stderr = false, - encoding: nil, timeout: 10, reprieve: 1, timeout_error: Timeout::Error, - stdout_filter: nil, stderr_filter: nil, ios: nil, - signal: :TERM, - rubybin: EnvUtil.rubybin, precommand: nil, - **opt) - timeout = apply_timeout_scale(timeout) - - in_c, in_p = IO.pipe - out_p, out_c = IO.pipe if capture_stdout - err_p, err_c = IO.pipe if capture_stderr && capture_stderr != :merge_to_stdout - opt[:in] = in_c - opt[:out] = out_c if capture_stdout - opt[:err] = capture_stderr == :merge_to_stdout ? out_c : err_c if capture_stderr - if encoding - out_p.set_encoding(encoding) if out_p - err_p.set_encoding(encoding) if err_p - end - ios.each {|i, o = i|opt[i] = o} if ios - - c = "C" - child_env = {} - LANG_ENVS.each {|lc| child_env[lc] = c} - if Array === args and Hash === args.first - child_env.update(args.shift) - end - if RUBYLIB and lib = child_env["RUBYLIB"] - child_env["RUBYLIB"] = [lib, RUBYLIB].join(File::PATH_SEPARATOR) - end - - # remain env - %w(ASAN_OPTIONS RUBY_ON_BUG).each{|name| - child_env[name] = ENV[name] if ENV[name] - } - - args = [args] if args.kind_of?(String) - pid = spawn(child_env, *precommand, rubybin, *args, opt) - in_c.close - out_c&.close - out_c = nil - err_c&.close - err_c = nil - if block_given? - return yield in_p, out_p, err_p, pid - else - th_stdout = Thread.new { out_p.read } if capture_stdout - th_stderr = Thread.new { err_p.read } if capture_stderr && capture_stderr != :merge_to_stdout - in_p.write stdin_data.to_str unless stdin_data.empty? - in_p.close - if (!th_stdout || th_stdout.join(timeout)) && (!th_stderr || th_stderr.join(timeout)) - timeout_error = nil - else - status = terminate(pid, signal, opt[:pgroup], reprieve) - terminated = Time.now - end - stdout = th_stdout.value if capture_stdout - stderr = th_stderr.value if capture_stderr && capture_stderr != :merge_to_stdout - out_p.close if capture_stdout - err_p.close if capture_stderr && capture_stderr != :merge_to_stdout - status ||= Process.wait2(pid)[1] - stdout = stdout_filter.call(stdout) if stdout_filter - stderr = stderr_filter.call(stderr) if stderr_filter - if timeout_error - bt = caller_locations - msg = "execution of #{bt.shift.label} expired timeout (#{timeout} sec)" - msg = failure_description(status, terminated, msg, [stdout, stderr].join("\n")) - raise timeout_error, msg, bt.map(&:to_s) - end - return stdout, stderr, status - end - ensure - [th_stdout, th_stderr].each do |th| - th.kill if th - end - [in_c, in_p, out_c, out_p, err_c, err_p].each do |io| - io&.close - end - [th_stdout, th_stderr].each do |th| - th.join if th - end - end - module_function :invoke_ruby - - def verbose_warning - class << (stderr = "".dup) - alias write concat - def flush; end - end - stderr, $stderr = $stderr, stderr - $VERBOSE = true - yield stderr - return $stderr - ensure - stderr, $stderr = $stderr, stderr - $VERBOSE = EnvUtil.original_verbose - EnvUtil.original_warning&.each {|i, v| Warning[i] = v} - end - module_function :verbose_warning - - def default_warning - $VERBOSE = false - yield - ensure - $VERBOSE = EnvUtil.original_verbose - end - module_function :default_warning - - def suppress_warning - $VERBOSE = nil - yield - ensure - $VERBOSE = EnvUtil.original_verbose - end - module_function :suppress_warning - - def under_gc_stress(stress = true) - stress, GC.stress = GC.stress, stress - yield - ensure - GC.stress = stress - end - module_function :under_gc_stress - - def with_default_external(enc) - suppress_warning { Encoding.default_external = enc } - yield - ensure - suppress_warning { Encoding.default_external = EnvUtil.original_external_encoding } - end - module_function :with_default_external - - def with_default_internal(enc) - suppress_warning { Encoding.default_internal = enc } - yield - ensure - suppress_warning { Encoding.default_internal = EnvUtil.original_internal_encoding } - end - module_function :with_default_internal - - def labeled_module(name, &block) - Module.new do - singleton_class.class_eval { - define_method(:to_s) {name} - alias inspect to_s - alias name to_s - } - class_eval(&block) if block - end - end - module_function :labeled_module - - def labeled_class(name, superclass = Object, &block) - Class.new(superclass) do - singleton_class.class_eval { - define_method(:to_s) {name} - alias inspect to_s - alias name to_s - } - class_eval(&block) if block - end - end - module_function :labeled_class - - if /darwin/ =~ RUBY_PLATFORM - DIAGNOSTIC_REPORTS_PATH = File.expand_path("~/Library/Logs/DiagnosticReports") - DIAGNOSTIC_REPORTS_TIMEFORMAT = '%Y-%m-%d-%H%M%S' - @ruby_install_name = RbConfig::CONFIG['RUBY_INSTALL_NAME'] - - def self.diagnostic_reports(signame, pid, now) - return unless %w[ABRT QUIT SEGV ILL TRAP].include?(signame) - cmd = File.basename(rubybin) - cmd = @ruby_install_name if "ruby-runner#{RbConfig::CONFIG["EXEEXT"]}" == cmd - path = DIAGNOSTIC_REPORTS_PATH - timeformat = DIAGNOSTIC_REPORTS_TIMEFORMAT - pat = "#{path}/#{cmd}_#{now.strftime(timeformat)}[-_]*.{crash,ips}" - first = true - 30.times do - first ? (first = false) : sleep(0.1) - Dir.glob(pat) do |name| - log = File.read(name) rescue next - case name - when /\.crash\z/ - if /\AProcess:\s+#{cmd} \[#{pid}\]$/ =~ log - File.unlink(name) - File.unlink("#{path}/.#{File.basename(name)}.plist") rescue nil - return log - end - when /\.ips\z/ - if /^ *"pid" *: *#{pid},/ =~ log - File.unlink(name) - return log - end - end - end - end - nil - end - else - def self.diagnostic_reports(signame, pid, now) - end - end - - def self.failure_description(status, now, message = "", out = "") - pid = status.pid - if signo = status.termsig - signame = Signal.signame(signo) - sigdesc = "signal #{signo}" - end - log = diagnostic_reports(signame, pid, now) - if signame - sigdesc = "SIG#{signame} (#{sigdesc})" - end - if status.coredump? - sigdesc = "#{sigdesc} (core dumped)" - end - full_message = ''.dup - message = message.call if Proc === message - if message and !message.empty? - full_message << message << "\n" - end - full_message << "pid #{pid}" - full_message << " exit #{status.exitstatus}" if status.exited? - full_message << " killed by #{sigdesc}" if sigdesc - if out and !out.empty? - full_message << "\n" << out.b.gsub(/^/, '| ') - full_message.sub!(/(? Date: Fri, 20 Oct 2023 11:23:49 +0900 Subject: [PATCH 19/83] Bump up required ruby version to 2.5 --- logger.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logger.gemspec b/logger.gemspec index 72a0cf3..5e8232e 100644 --- a/logger.gemspec +++ b/logger.gemspec @@ -18,5 +18,5 @@ Gem::Specification.new do |spec| spec.files = Dir.glob("lib/**/*.rb") + ["logger.gemspec"] spec.require_paths = ["lib"] - spec.required_ruby_version = ">= 2.3.0" + spec.required_ruby_version = ">= 2.5.0" end From 0996f90650fd95718f0ffe835b965de18654b71c Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Tue, 7 Nov 2023 14:17:40 +0900 Subject: [PATCH 20/83] Bump up 1.6.0 --- lib/logger/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logger/version.rb b/lib/logger/version.rb index f85c72e..202b6e4 100644 --- a/lib/logger/version.rb +++ b/lib/logger/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Logger - VERSION = "1.5.3" + VERSION = "1.6.0" end From 44b42b0f5c791a427606d2714e34ec7cbe9a2bc3 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 6 Jun 2024 12:07:29 +0900 Subject: [PATCH 21/83] Update license files with ruby/ruby --- LICENSE.txt => BSDL | 6 ++--- COPYING | 56 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 3 deletions(-) rename LICENSE.txt => BSDL (83%) create mode 100644 COPYING diff --git a/LICENSE.txt b/BSDL similarity index 83% rename from LICENSE.txt rename to BSDL index a009cae..66d9359 100644 --- a/LICENSE.txt +++ b/BSDL @@ -4,10 +4,10 @@ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. + notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..48e5a96 --- /dev/null +++ b/COPYING @@ -0,0 +1,56 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the +2-clause BSDL (see the file BSDL), or the conditions below: + +1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + +2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a. place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b. use the modified software only within your corporation or + organization. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a. distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b. accompany the distribution with the machine-readable source of + the software. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + +5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + +6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. From 5e540ee42005469380997c1fdd755d9790ee596c Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 6 Jun 2024 12:09:01 +0900 Subject: [PATCH 22/83] Exclude Ruby 2.5 from macos-latest that is macos-14 --- .github/workflows/test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6288bcd..fac7d18 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,6 +16,9 @@ jobs: matrix: ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }} os: [ ubuntu-latest, macos-latest, windows-latest ] + exclude: + - ruby: 2.5 + os: macos-latest runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 From 83502c2107c282e9e072865ab55252f2b37ec779 Mon Sep 17 00:00:00 2001 From: Baron Bloomer Date: Thu, 7 Apr 2022 12:32:18 +0100 Subject: [PATCH 23/83] Add support for symbols in #shift_age Resolves issue: https://github.com/ruby/logger/issues/46 --- lib/logger/period.rb | 16 +++---- test/logger/test_logperiod.rb | 83 +++++++++++++++-------------------- 2 files changed, 43 insertions(+), 56 deletions(-) diff --git a/lib/logger/period.rb b/lib/logger/period.rb index 0a291db..a0359de 100644 --- a/lib/logger/period.rb +++ b/lib/logger/period.rb @@ -8,14 +8,14 @@ module Period def next_rotate_time(now, shift_age) case shift_age - when 'daily' + when 'daily', :daily t = Time.mktime(now.year, now.month, now.mday) + SiD - when 'weekly' + when 'weekly', :weekly t = Time.mktime(now.year, now.month, now.mday) + SiD * (7 - now.wday) - when 'monthly' + when 'monthly', :monthly t = Time.mktime(now.year, now.month, 1) + SiD * 32 return Time.mktime(t.year, t.month, 1) - when 'now', 'everytime' + when 'now', 'everytime', :now, :everytime return now else raise ArgumentError, "invalid :shift_age #{shift_age.inspect}, should be daily, weekly, monthly, or everytime" @@ -30,13 +30,13 @@ def next_rotate_time(now, shift_age) def previous_period_end(now, shift_age) case shift_age - when 'daily' + when 'daily', :daily t = Time.mktime(now.year, now.month, now.mday) - SiD / 2 - when 'weekly' + when 'weekly', :weekly t = Time.mktime(now.year, now.month, now.mday) - (SiD * now.wday + SiD / 2) - when 'monthly' + when 'monthly', :monthly t = Time.mktime(now.year, now.month, 1) - SiD / 2 - when 'now', 'everytime' + when 'now', 'everytime', :now, :everytime return now else raise ArgumentError, "invalid :shift_age #{shift_age.inspect}, should be daily, weekly, monthly, or everytime" diff --git a/test/logger/test_logperiod.rb b/test/logger/test_logperiod.rb index 6e6e5e9..ee38d87 100644 --- a/test/logger/test_logperiod.rb +++ b/test/logger/test_logperiod.rb @@ -1,80 +1,67 @@ # coding: US-ASCII # frozen_string_literal: false -require 'logger' -require 'time' +require "logger" +require "time" class TestLogPeriod < Test::Unit::TestCase def test_next_rotate_time time = Time.parse("2019-07-18 13:52:02") - daily_result = Logger::Period.next_rotate_time(time, 'daily') - next_day = Time.parse("2019-07-19 00:00:00") - assert_equal(next_day, daily_result) + assert_next_rotate_time_words(time, "2019-07-19 00:00:00", ["daily", :daily]) + assert_next_rotate_time_words(time, "2019-07-21 00:00:00", ["weekly", :weekly]) + assert_next_rotate_time_words(time, "2019-08-01 00:00:00", ["monthly", :monthly]) - weekly_result = Logger::Period.next_rotate_time(time, 'weekly') - next_week = Time.parse("2019-07-21 00:00:00") - assert_equal(next_week, weekly_result) - - monthly_result = Logger::Period.next_rotate_time(time, 'monthly') - next_month = Time.parse("2019-08-1 00:00:00") - assert_equal(next_month, monthly_result) - - assert_raise(ArgumentError) { Logger::Period.next_rotate_time(time, 'invalid') } + assert_raise(ArgumentError) { Logger::Period.next_rotate_time(time, "invalid") } end def test_next_rotate_time_extreme_cases # First day of Month and Saturday time = Time.parse("2018-07-01 00:00:00") - daily_result = Logger::Period.next_rotate_time(time, 'daily') - next_day = Time.parse("2018-07-02 00:00:00") - assert_equal(next_day, daily_result) - - weekly_result = Logger::Period.next_rotate_time(time, 'weekly') - next_week = Time.parse("2018-07-08 00:00:00") - assert_equal(next_week, weekly_result) + assert_next_rotate_time_words(time, "2018-07-02 00:00:00", ["daily", :daily]) + assert_next_rotate_time_words(time, "2018-07-08 00:00:00", ["weekly", :weekly]) + assert_next_rotate_time_words(time, "2018-08-01 00:00:00", ["monthly", :monthly]) - monthly_result = Logger::Period.next_rotate_time(time, 'monthly') - next_month = Time.parse("2018-08-1 00:00:00") - assert_equal(next_month, monthly_result) - - assert_raise(ArgumentError) { Logger::Period.next_rotate_time(time, 'invalid') } + assert_raise(ArgumentError) { Logger::Period.next_rotate_time(time, "invalid") } end def test_previous_period_end time = Time.parse("2019-07-18 13:52:02") - daily_result = Logger::Period.previous_period_end(time, 'daily') - day_ago = Time.parse("2019-07-17 23:59:59") - assert_equal(day_ago, daily_result) - - weekly_result = Logger::Period.previous_period_end(time, 'weekly') - week_ago = Time.parse("2019-07-13 23:59:59") - assert_equal(week_ago, weekly_result) - - monthly_result = Logger::Period.previous_period_end(time, 'monthly') - month_ago = Time.parse("2019-06-30 23:59:59") - assert_equal(month_ago, monthly_result) + assert_previous_period_end_words(time, "2019-07-17 23:59:59", ["daily", :daily]) + assert_previous_period_end_words(time, "2019-07-13 23:59:59", ["weekly", :weekly]) + assert_previous_period_end_words(time, "2019-06-30 23:59:59", ["monthly", :monthly]) - assert_raise(ArgumentError) { Logger::Period.next_rotate_time(time, 'invalid') } + assert_raise(ArgumentError) { Logger::Period.previous_period_end(time, "invalid") } end def test_previous_period_end_extreme_cases # First day of Month and Saturday time = Time.parse("2018-07-01 00:00:00") + previous_date = "2018-06-30 23:59:59" - daily_result = Logger::Period.previous_period_end(time, 'daily') - day_ago = Time.parse("2018-06-30 23:59:59") - assert_equal(day_ago, daily_result) + assert_previous_period_end_words(time, previous_date, ["daily", :daily]) + assert_previous_period_end_words(time, previous_date, ["weekly", :weekly]) + assert_previous_period_end_words(time, previous_date, ["monthly", :monthly]) - weekly_result = Logger::Period.previous_period_end(time, 'weekly') - week_ago = Time.parse("2018-06-30 23:59:59") - assert_equal(week_ago, weekly_result) + assert_raise(ArgumentError) { Logger::Period.previous_period_end(time, "invalid") } + end + + private - monthly_result = Logger::Period.previous_period_end(time, 'monthly') - month_ago = Time.parse("2018-06-30 23:59:59") - assert_equal(month_ago, monthly_result) + def assert_next_rotate_time_words(time, next_date, words) + assert_time_words(:next_rotate_time, time, next_date, words) + end + + def assert_previous_period_end_words(time, previous_date, words) + assert_time_words(:previous_period_end, time, previous_date, words) + end - assert_raise(ArgumentError) { Logger::Period.next_rotate_time(time, 'invalid') } + def assert_time_words(method, time, date, words) + words.each do |word| + daily_result = Logger::Period.public_send(method, time, word) + expected_result = Time.parse(date) + assert_equal(expected_result, daily_result) + end end end From 0270e7bb9376cbf80374831e5036deb79ead7ffd Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 6 Jun 2024 18:12:36 +0900 Subject: [PATCH 24/83] Retired CHANGELOG --- CHANGELOG.md | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 8960ad3..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,25 +0,0 @@ -# HEAD - -* Support fiber-local log levels using `Logger#with_level` [#84](https://github.com/ruby/logger/issue/84) - -# 1.4.2 - -* Document that shift_age of 0 disables log file rotation [#43](https://github.com/ruby/logger/pull/43) (thanks to jeremyevans) -* Raise ArgumentError for invalid shift_age [#42](https://github.com/ruby/logger/pull/42) (thanks to jeremyevans) -* Honor Logger#level overrides [#41](https://github.com/ruby/logger/pull/41) (thanks to georgeclaghorn) - -# 1.4.1 - -Fixes: - -* Add missing files in gem (thanks to hsbt) - -# 1.4.0 - -Enhancements: - -* Add support for changing severity using bang methods [#15](https://github.com/ruby/logger/pull/15) (thanks to ioquatix) -* Set filename when initializing logger with a File object to make reopen work [#30](https://github.com/ruby/logger/pull/30) (thanks to jeremyevans) -* Add option to set the binary mode of the log device [#33](https://github.com/ruby/logger/pull/33) (thanks to refaelfranca) - -Also, large refactorings of codes and testing libraries are introduced. From 436a7d680f29c573f09a096298d36a356d1fac2f Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Fri, 16 Aug 2019 09:12:06 -0700 Subject: [PATCH 25/83] Add reraise_write_errors keyword argument to Logger and LogDevice This allows the user to specify exception classes to treat as regular exceptions instead of being swallowed. Among other things, it is useful for having Logger work with Timeout. Fixes Ruby Bug 9115. --- lib/logger.rb | 9 +++++++-- lib/logger/log_device.rb | 9 ++++++++- test/logger/test_logger.rb | 9 +++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/logger.rb b/lib/logger.rb index 4be5c33..a1f48d4 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -574,10 +574,14 @@ def fatal!; self.level = FATAL; end # - +shift_period_suffix+: sets the format for the filename suffix # for periodic log file rotation; default is '%Y%m%d'. # See {Periodic Rotation}[rdoc-ref:Logger@Periodic+Rotation]. + # - +reraise_write_errors+: An array of exception classes, which will + # be reraised if there is an error when writing to the log device. + # The default is to swallow all exceptions raised. # def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG, progname: nil, formatter: nil, datetime_format: nil, - binmode: false, shift_period_suffix: '%Y%m%d') + binmode: false, shift_period_suffix: '%Y%m%d', + reraise_write_errors: []) self.level = level self.progname = progname @default_formatter = Formatter.new @@ -589,7 +593,8 @@ def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG, @logdev = LogDevice.new(logdev, shift_age: shift_age, shift_size: shift_size, shift_period_suffix: shift_period_suffix, - binmode: binmode) + binmode: binmode, + reraise_write_errors: reraise_write_errors) end end diff --git a/lib/logger/log_device.rb b/lib/logger/log_device.rb index 84277a2..4876adf 100644 --- a/lib/logger/log_device.rb +++ b/lib/logger/log_device.rb @@ -11,9 +11,10 @@ class LogDevice attr_reader :filename include MonitorMixin - def initialize(log = nil, shift_age: nil, shift_size: nil, shift_period_suffix: nil, binmode: false) + def initialize(log = nil, shift_age: nil, shift_size: nil, shift_period_suffix: nil, binmode: false, reraise_write_errors: []) @dev = @filename = @shift_age = @shift_size = @shift_period_suffix = nil @binmode = binmode + @reraise_write_errors = reraise_write_errors mon_initialize set_dev(log) if @filename @@ -34,16 +35,22 @@ def write(message) if @shift_age and @dev.respond_to?(:stat) begin check_shift_log + rescue *@reraise_write_errors + raise rescue warn("log shifting failed. #{$!}") end end begin @dev.write(message) + rescue *@reraise_write_errors + raise rescue warn("log writing failed. #{$!}") end end + rescue *@reraise_write_errors + raise rescue Exception => ignored warn("log writing failed. #{ignored}") end diff --git a/test/logger/test_logger.rb b/test/logger/test_logger.rb index 37d0f58..2023553 100644 --- a/test/logger/test_logger.rb +++ b/test/logger/test_logger.rb @@ -113,6 +113,15 @@ def test_string_level assert_raise(ArgumentError) { @logger.level = 'something_wrong' } end + def test_reraise_write_errors + c = Object.new + e = Class.new(StandardError) + c.define_singleton_method(:write){|*| raise e} + c.define_singleton_method(:close){} + logger = Logger.new(c, :reraise_write_errors=>[e]) + assert_raise(e) { logger.warn('foo') } + end + def test_progname assert_nil(@logger.progname) @logger.progname = "name" From 3246f38328f20a106d0f720c6a4ff76eca1c6a3f Mon Sep 17 00:00:00 2001 From: Michael Chui Date: Tue, 20 Aug 2024 15:24:29 -0700 Subject: [PATCH 26/83] Guarantee level_override exists Some Ruby apps subclass Logger without running the superclass constructor, which means that `@level_override` isn't initialized properly. This can be fixed in some cases, but the gem should maintain backwards compatibility. --- lib/logger.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/logger.rb b/lib/logger.rb index a1f48d4..4735209 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -381,7 +381,7 @@ class Logger # Logging severity threshold (e.g. Logger::INFO). def level - @level_override[Fiber.current] || @level + level_override[Fiber.current] || @level end # Sets the log level; returns +severity+. @@ -406,14 +406,14 @@ def level=(severity) # logger.debug { "Hello" } # end def with_level(severity) - prev, @level_override[Fiber.current] = level, Severity.coerce(severity) + prev, level_override[Fiber.current] = level, Severity.coerce(severity) begin yield ensure if prev - @level_override[Fiber.current] = prev + level_override[Fiber.current] = prev else - @level_override.delete(Fiber.current) + level_override.delete(Fiber.current) end end end @@ -746,6 +746,11 @@ def format_severity(severity) SEV_LABEL[severity] || 'ANY' end + # Guarantee the existence of this ivar even when subclasses don't call the superclass constructor. + def level_override + @level_override ||= {} + end + def format_message(severity, datetime, progname, msg) (@formatter || @default_formatter).call(severity, datetime, progname, msg) end From bda937b4cc9283e33c5f19d5f0b8976541dbdba2 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Mon, 2 Sep 2024 11:28:22 +0900 Subject: [PATCH 27/83] Bump up 1.6.1 --- lib/logger/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logger/version.rb b/lib/logger/version.rb index 202b6e4..2a0801b 100644 --- a/lib/logger/version.rb +++ b/lib/logger/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Logger - VERSION = "1.6.0" + VERSION = "1.6.1" end From 195bdd80d82143d8cd488a9c83b853b994d7feb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A9=20Dupuis?= Date: Tue, 17 Sep 2024 11:53:48 -0700 Subject: [PATCH 28/83] Fix license link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 649684f..ceb1a21 100644 --- a/README.md +++ b/README.md @@ -101,4 +101,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/l ## License -The gem is available as open source under the terms of the [BSD-2-Clause](LICENSE.txt). +The gem is available as open source under the terms of the [BSD-2-Clause](BSDL). From f904ad2f7cfad4592a325c401d0ad1dcd62023a6 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 9 Oct 2024 12:54:16 +0900 Subject: [PATCH 29/83] Extract `Logger::LogDevice#handle_write_errors` --- lib/logger/log_device.rb | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/lib/logger/log_device.rb b/lib/logger/log_device.rb index 4876adf..a5c3759 100644 --- a/lib/logger/log_device.rb +++ b/lib/logger/log_device.rb @@ -30,29 +30,13 @@ def initialize(log = nil, shift_age: nil, shift_size: nil, shift_period_suffix: end def write(message) - begin + handle_write_errors("writing") do synchronize do if @shift_age and @dev.respond_to?(:stat) - begin - check_shift_log - rescue *@reraise_write_errors - raise - rescue - warn("log shifting failed. #{$!}") - end - end - begin - @dev.write(message) - rescue *@reraise_write_errors - raise - rescue - warn("log writing failed. #{$!}") + handle_write_errors("shifting") {check_shift_log} end + handle_write_errors("writing") {@dev.write(message)} end - rescue *@reraise_write_errors - raise - rescue Exception => ignored - warn("log writing failed. #{ignored}") end end @@ -121,6 +105,13 @@ def create_logfile(filename) logdev.sync = true end logdev + + def handle_write_errors(mesg) + yield + rescue *@reraise_write_errors + raise + rescue + warn("log #{mesg} failed. #{$!}") end def add_log_header(file) From 7b6146fee6d35ed47c68f482b81206ddf6e1e9c3 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 9 Oct 2024 14:05:57 +0900 Subject: [PATCH 30/83] Enable log file rotation on Windows Since ruby 2.3, a file opened with `File::SHARE_DELETE` and `File::BINARY` can be renamed or removed. --- lib/logger/log_device.rb | 105 ++++++++++++++++++++++------------ test/logger/test_logdevice.rb | 2 +- 2 files changed, 69 insertions(+), 38 deletions(-) diff --git a/lib/logger/log_device.rb b/lib/logger/log_device.rb index a5c3759..4c46278 100644 --- a/lib/logger/log_device.rb +++ b/lib/logger/log_device.rb @@ -67,6 +67,12 @@ def reopen(log = nil) private + # :stopdoc: + + MODE = File::WRONLY | File::APPEND + MODE_TO_OPEN = MODE | File::SHARE_DELETE | File::BINARY + MODE_TO_CREATE = MODE_TO_OPEN | File::CREAT | File::EXCL + def set_dev(log) if log.respond_to?(:write) and log.respond_to?(:close) @dev = log @@ -77,34 +83,54 @@ def set_dev(log) end else @dev = open_logfile(log) - @dev.sync = true - @dev.binmode if @binmode @filename = log end end + if MODE_TO_OPEN == MODE + def fixup_mode(dev, filename) + dev + end + else + def fixup_mode(dev, filename) + return dev if @binmode + dev.autoclose = false + old_dev = dev + dev = File.new(dev.fileno, mode: MODE, path: filename) + old_dev.close + PathAttr.set_path(dev, filename) if defined?(PathAttr) + dev + end + end + def open_logfile(filename) begin - File.open(filename, (File::WRONLY | File::APPEND)) + dev = File.open(filename, MODE_TO_OPEN) rescue Errno::ENOENT create_logfile(filename) + else + dev = fixup_mode(dev, filename) + dev.sync = true + dev.binmode if @binmode + dev end end def create_logfile(filename) begin - logdev = File.open(filename, (File::WRONLY | File::APPEND | File::CREAT | File::EXCL)) + logdev = File.open(filename, MODE_TO_CREATE) logdev.flock(File::LOCK_EX) + logdev = fixup_mode(logdev, filename) logdev.sync = true logdev.binmode if @binmode add_log_header(logdev) logdev.flock(File::LOCK_UN) + logdev rescue Errno::EEXIST # file is created by another process - logdev = open_logfile(filename) - logdev.sync = true + open_logfile(filename) end - logdev + end def handle_write_errors(mesg) yield @@ -135,40 +161,33 @@ def check_shift_log end end - if /mswin|mingw|cygwin/ =~ RbConfig::CONFIG['host_os'] - def lock_shift_log - yield - end - else - def lock_shift_log - retry_limit = 8 - retry_sleep = 0.1 - begin - File.open(@filename, File::WRONLY | File::APPEND) do |lock| - lock.flock(File::LOCK_EX) # inter-process locking. will be unlocked at closing file - if File.identical?(@filename, lock) and File.identical?(lock, @dev) - yield # log shifting - else - # log shifted by another process (i-node before locking and i-node after locking are different) - @dev.close rescue nil - @dev = open_logfile(@filename) - @dev.sync = true - end - end - rescue Errno::ENOENT - # @filename file would not exist right after #rename and before #create_logfile - if retry_limit <= 0 - warn("log rotation inter-process lock failed. #{$!}") + def lock_shift_log + retry_limit = 8 + retry_sleep = 0.1 + begin + File.open(@filename, MODE_TO_OPEN) do |lock| + lock.flock(File::LOCK_EX) # inter-process locking. will be unlocked at closing file + if File.identical?(@filename, lock) and File.identical?(lock, @dev) + yield # log shifting else - sleep retry_sleep - retry_limit -= 1 - retry_sleep *= 2 - retry + # log shifted by another process (i-node before locking and i-node after locking are different) + @dev.close rescue nil + @dev = open_logfile(@filename) end end - rescue - warn("log rotation inter-process lock failed. #{$!}") + rescue Errno::ENOENT + # @filename file would not exist right after #rename and before #create_logfile + if retry_limit <= 0 + warn("log rotation inter-process lock failed. #{$!}") + else + sleep retry_sleep + retry_limit -= 1 + retry_sleep *= 2 + retry + end end + rescue + warn("log rotation inter-process lock failed. #{$!}") end def shift_log_age @@ -203,3 +222,15 @@ def shift_log_period(period_end) end end end + +File.open(IO::NULL) do |f| + File.new(f.fileno, autoclose: false, path: "").path +rescue IOError + module PathAttr # :nodoc: + attr_reader :path + + def self.set_path(file, path) + file.extend(self).instance_variable_set(:@path, path) + end + end +end diff --git a/test/logger/test_logdevice.rb b/test/logger/test_logdevice.rb index 8f1c155..610905e 100644 --- a/test/logger/test_logdevice.rb +++ b/test/logger/test_logdevice.rb @@ -452,7 +452,7 @@ def test_shifting_size_not_rotate_too_much end ensure logdev0.close - end unless /mswin|mingw|cygwin/ =~ RbConfig::CONFIG['host_os'] + end def test_shifting_midnight Dir.mktmpdir do |tmpdir| From dae2b832cd280ce175d2d7dc1869b8abae114eed Mon Sep 17 00:00:00 2001 From: Hartley McGuire Date: Thu, 7 Nov 2024 00:17:05 +0000 Subject: [PATCH 31/83] Enable subclasses to configure level isolation (#103) `Logger#with_level` was recently added to enable configuring a `Logger`'s level for the duration of a block. However, the configured level is always tied to the currently running `Fiber`, which is not always ideal in applications that mix `Thread`s and `Fiber`s. For example, Active Support has provided a similar feature (`ActiveSupport::Logger#log_at`) which, depending on configuration, can be isolated to either `Thread`s or `Fiber`s. This commit enables subclasses of `Logger` to customize the level isolation. Ideally, it will enable replacing most of Active Support's `#log_at`, since both methods end up serving the same purpose. --- lib/logger.rb | 12 +++++++---- test/logger/test_severity.rb | 42 +++++++++++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/lib/logger.rb b/lib/logger.rb index 4735209..8d6e0d7 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -381,7 +381,7 @@ class Logger # Logging severity threshold (e.g. Logger::INFO). def level - level_override[Fiber.current] || @level + level_override[level_key] || @level end # Sets the log level; returns +severity+. @@ -406,14 +406,14 @@ def level=(severity) # logger.debug { "Hello" } # end def with_level(severity) - prev, level_override[Fiber.current] = level, Severity.coerce(severity) + prev, level_override[level_key] = level, Severity.coerce(severity) begin yield ensure if prev - level_override[Fiber.current] = prev + level_override[level_key] = prev else - level_override.delete(Fiber.current) + level_override.delete(level_key) end end end @@ -751,6 +751,10 @@ def level_override @level_override ||= {} end + def level_key + Fiber.current + end + def format_message(severity, datetime, progname, msg) (@formatter || @default_formatter).call(severity, datetime, progname, msg) end diff --git a/test/logger/test_severity.rb b/test/logger/test_severity.rb index e1069c8..fb26939 100644 --- a/test/logger/test_severity.rb +++ b/test/logger/test_severity.rb @@ -26,7 +26,7 @@ def test_level_assignment end end - def test_thread_local_level + def test_fiber_local_level logger = Logger.new(nil) logger.level = INFO # default level other = Logger.new(nil) @@ -40,14 +40,50 @@ def test_thread_local_level logger.with_level(DEBUG) do # verify reentrancy assert_equal(logger.level, DEBUG) - Thread.new do + Fiber.new do assert_equal(logger.level, INFO) logger.with_level(:WARN) do assert_equal(other.level, ERROR) assert_equal(logger.level, WARN) end assert_equal(logger.level, INFO) - end.join + end.resume + + assert_equal(logger.level, DEBUG) + end + assert_equal(logger.level, WARN) + end + assert_equal(logger.level, INFO) + end + + def test_thread_local_level + subclass = Class.new(Logger) do + def level_key + Thread.current + end + end + + logger = subclass.new(nil) + logger.level = INFO # default level + other = subclass.new(nil) + other.level = ERROR # default level + + assert_equal(other.level, ERROR) + logger.with_level(:WARN) do + assert_equal(other.level, ERROR) + assert_equal(logger.level, WARN) + + logger.with_level(DEBUG) do # verify reentrancy + assert_equal(logger.level, DEBUG) + + Fiber.new do + assert_equal(logger.level, DEBUG) + logger.with_level(:WARN) do + assert_equal(other.level, ERROR) + assert_equal(logger.level, WARN) + end + assert_equal(logger.level, DEBUG) + end.resume assert_equal(logger.level, DEBUG) end From 1a64cb552f0dc568cb7fb03c3b96a62f39c1d081 Mon Sep 17 00:00:00 2001 From: Mike Linksvayer Date: Mon, 25 Nov 2024 12:25:42 -0800 Subject: [PATCH 32/83] include license texts in gem --- logger.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logger.gemspec b/logger.gemspec index 5e8232e..ed55111 100644 --- a/logger.gemspec +++ b/logger.gemspec @@ -15,7 +15,7 @@ Gem::Specification.new do |spec| spec.homepage = "https://github.com/ruby/logger" spec.licenses = ["Ruby", "BSD-2-Clause"] - spec.files = Dir.glob("lib/**/*.rb") + ["logger.gemspec"] + spec.files = Dir.glob("lib/**/*.rb") + ["logger.gemspec", "BSDL", "COPYING"] spec.require_paths = ["lib"] spec.required_ruby_version = ">= 2.5.0" From a7fae5e790b67f4260118b2b776289a9bdbdef20 Mon Sep 17 00:00:00 2001 From: Mike Linksvayer Date: Mon, 25 Nov 2024 20:54:18 +0000 Subject: [PATCH 33/83] update license files in rdoc task --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 35dd06e..d630ceb 100644 --- a/Rakefile +++ b/Rakefile @@ -14,7 +14,7 @@ require "rdoc/task" RDoc::Task.new do |doc| doc.main = "README.md" doc.title = "Logger -- Ruby Standard Logger" - doc.rdoc_files = FileList.new %w[README.md lib LICENSE.txt] + doc.rdoc_files = FileList.new %w[README.md lib BSDL COPYING] doc.rdoc_dir = "html" end From 9512a54122060e83500c97451a634992033a8f20 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Mon, 2 Dec 2024 17:01:27 +0900 Subject: [PATCH 34/83] Enabled trusted publisher for rubygems.org --- .github/workflows/push_gem.yml | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/push_gem.yml diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml new file mode 100644 index 0000000..73c515c --- /dev/null +++ b/.github/workflows/push_gem.yml @@ -0,0 +1,46 @@ +name: Publish gem to rubygems.org + +on: + push: + tags: + - 'v*' + +permissions: + contents: read + +jobs: + push: + if: github.repository == 'ruby/logger' + runs-on: ubuntu-latest + + environment: + name: rubygems.org + url: https://rubygems.org/gems/logger + + permissions: + contents: write + id-token: write + + steps: + - name: Harden Runner + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 + with: + egress-policy: audit + + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + + - name: Set up Ruby + uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 + with: + bundler-cache: true + ruby-version: ruby + + - name: Publish to RubyGems + uses: rubygems/release-gem@9e85cb11501bebc2ae661c1500176316d3987059 # v1.1.0 + + - name: Create GitHub release + run: | + tag_name="$(git describe --tags --abbrev=0)" + gh release create "${tag_name}" --verify-tag --generate-notes + env: + GITHUB_TOKEN: ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }} From 2d07f086f8aa0bd5923a072ce7bd15e5dd301f16 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Mon, 2 Dec 2024 17:03:35 +0900 Subject: [PATCH 35/83] Bump up 1.6.2 --- lib/logger/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logger/version.rb b/lib/logger/version.rb index 2a0801b..15fc5bc 100644 --- a/lib/logger/version.rb +++ b/lib/logger/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Logger - VERSION = "1.6.1" + VERSION = "1.6.2" end From 97bce95f49fa7856a696bd8b55c5545dc6a977e6 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 13 Dec 2024 09:58:13 +0900 Subject: [PATCH 36/83] Bump up v1.6.3 --- lib/logger/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logger/version.rb b/lib/logger/version.rb index 15fc5bc..bb315c0 100644 --- a/lib/logger/version.rb +++ b/lib/logger/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Logger - VERSION = "1.6.2" + VERSION = "1.6.3" end From 4be05c22086825525b794c1768204593ea69e14f Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 19 Dec 2024 12:36:43 +0900 Subject: [PATCH 37/83] Use `__FILE__` for wasm `/dev/null` is not available on wasm. --- lib/logger/log_device.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logger/log_device.rb b/lib/logger/log_device.rb index 4c46278..b5b7390 100644 --- a/lib/logger/log_device.rb +++ b/lib/logger/log_device.rb @@ -223,7 +223,7 @@ def shift_log_period(period_end) end end -File.open(IO::NULL) do |f| +File.open(__FILE__) do |f| File.new(f.fileno, autoclose: false, path: "").path rescue IOError module PathAttr # :nodoc: From 216cedef7ce2b1979ed65c7c1ae5625b6e9c791a Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 19 Dec 2024 13:15:55 +0900 Subject: [PATCH 38/83] v1.6.4 --- lib/logger/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logger/version.rb b/lib/logger/version.rb index bb315c0..e1e6b97 100644 --- a/lib/logger/version.rb +++ b/lib/logger/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Logger - VERSION = "1.6.3" + VERSION = "1.6.4" end From b785aaa82efeb7d624b43999053e25fa45f0f70d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 06:50:18 +0000 Subject: [PATCH 39/83] Bump rubygems/release-gem from 1.1.0 to 1.1.1 Bumps [rubygems/release-gem](https://github.com/rubygems/release-gem) from 1.1.0 to 1.1.1. - [Release notes](https://github.com/rubygems/release-gem/releases) - [Commits](https://github.com/rubygems/release-gem/compare/9e85cb11501bebc2ae661c1500176316d3987059...a25424ba2ba8b387abc8ef40807c2c85b96cbe32) --- updated-dependencies: - dependency-name: rubygems/release-gem dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/push_gem.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index 73c515c..410096f 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -36,7 +36,7 @@ jobs: ruby-version: ruby - name: Publish to RubyGems - uses: rubygems/release-gem@9e85cb11501bebc2ae661c1500176316d3987059 # v1.1.0 + uses: rubygems/release-gem@a25424ba2ba8b387abc8ef40807c2c85b96cbe32 # v1.1.1 - name: Create GitHub release run: | From c6c64b02a07fbd332ecf2a265457387cca043f92 Mon Sep 17 00:00:00 2001 From: Mark Young Date: Tue, 31 Dec 2024 16:38:37 +0000 Subject: [PATCH 40/83] Provide a 'Changelog' link on rubygems.org/gems/logger By providing a 'changelog_uri' in the metadata of the gemspec a 'Changelog' link will be shown on https://rubygems.org/gems/logger which makes it quick and easy for someone to check on the changes introduced with a new version. Details of this functionality can be found on https://guides.rubygems.org/specification-reference/#metadata --- logger.gemspec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/logger.gemspec b/logger.gemspec index ed55111..d0b3e19 100644 --- a/logger.gemspec +++ b/logger.gemspec @@ -19,4 +19,6 @@ Gem::Specification.new do |spec| spec.require_paths = ["lib"] spec.required_ruby_version = ">= 2.5.0" + + spec.metadata["changelog_uri"] = spec.homepage + "/releases" end From b9daad7c76f086051daf61854ae467cfc9844497 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 9 Jan 2025 15:45:21 +0900 Subject: [PATCH 41/83] Added lib path to in assert_in_out_err --- test/logger/test_logdevice.rb | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/test/logger/test_logdevice.rb b/test/logger/test_logdevice.rb index 610905e..d3e4a99 100644 --- a/test/logger/test_logdevice.rb +++ b/test/logger/test_logdevice.rb @@ -19,6 +19,7 @@ def stat end def setup + @top_dir = File.expand_path('../../lib', __dir__) @tempfile = Tempfile.new("logger") @tempfile.close @filename = @tempfile.path @@ -456,7 +457,7 @@ def test_shifting_size_not_rotate_too_much def test_shifting_midnight Dir.mktmpdir do |tmpdir| - assert_in_out_err([*%W"--disable=gems -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") + assert_in_out_err([*%W"--disable=gems -I#{@top_dir} -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") begin; begin module FakeTime @@ -498,7 +499,7 @@ class << Time def test_shifting_weekly Dir.mktmpdir do |tmpdir| - assert_in_out_err([{"TZ"=>"UTC"}, *%W"-rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") + assert_in_out_err([{"TZ"=>"UTC"}, *%W"-I#{@top_dir} -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") begin; begin module FakeTime @@ -543,7 +544,7 @@ class << Time def test_shifting_monthly Dir.mktmpdir do |tmpdir| - assert_in_out_err([{"TZ"=>"UTC"}, *%W"-rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") + assert_in_out_err([{"TZ"=>"UTC"}, *%W"-I#{@top_dir} -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") begin; begin module FakeTime @@ -588,7 +589,7 @@ class << Time def test_shifting_dst_change Dir.mktmpdir do |tmpdir| - assert_in_out_err([{"TZ"=>"Europe/London"}, *%W"--disable=gems -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") + assert_in_out_err([{"TZ"=>"Europe/London"}, *%W"--disable=gems -I#{@top_dir} -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") begin; begin module FakeTime @@ -627,7 +628,7 @@ class << Time def test_shifting_weekly_dst_change Dir.mktmpdir do |tmpdir| - assert_separately([{"TZ"=>"Europe/London"}, *%W"-rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") + assert_separately([{"TZ"=>"Europe/London"}, *%W"-I#{@top_dir} -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") begin; begin module FakeTime @@ -658,7 +659,7 @@ class << Time def test_shifting_monthly_dst_change Dir.mktmpdir do |tmpdir| - assert_separately([{"TZ"=>"Europe/London"}, *%W"-rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") + assert_separately([{"TZ"=>"Europe/London"}, *%W"-I#{@top_dir} -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") begin; begin module FakeTime @@ -707,7 +708,7 @@ class << Time def test_shifting_midnight_exist_file Dir.mktmpdir do |tmpdir| - assert_in_out_err([*%W"--disable=gems -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") + assert_in_out_err([*%W"--disable=gems -I#{@top_dir} -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") begin; begin module FakeTime @@ -751,7 +752,7 @@ class << Time def test_shifting_weekly_exist_file Dir.mktmpdir do |tmpdir| - assert_in_out_err([{"TZ"=>"UTC"}, *%W"-rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") + assert_in_out_err([{"TZ"=>"UTC"}, *%W"-I#{@top_dir} -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") begin; begin module FakeTime @@ -798,7 +799,7 @@ class << Time def test_shifting_monthly_exist_file Dir.mktmpdir do |tmpdir| - assert_in_out_err([{"TZ"=>"UTC"}, *%W"-rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") + assert_in_out_err([{"TZ"=>"UTC"}, *%W"-I#{@top_dir} -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") begin; begin module FakeTime @@ -848,7 +849,8 @@ class << Time def run_children(n, args, src) r, w = IO.pipe [w, *(1..n).map do - f = IO.popen([EnvUtil.rubybin, *%w[--disable=gems -rlogger -], *args], "w", err: w) + f = IO.popen([EnvUtil.rubybin, *%w[--disable=gems -], *args], "w", err: w) + src = "$LOAD_PATH.unshift('#{@top_dir}'); require 'logger';#{src}" f.puts(src) f end].each(&:close) From fba3ee3fea15bfac52d5779a431191fb6f1b28fb Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 9 Jan 2025 18:17:33 +0900 Subject: [PATCH 42/83] Dir.glob is not working with bundled gems installation --- logger.gemspec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/logger.gemspec b/logger.gemspec index d0b3e19..09d9600 100644 --- a/logger.gemspec +++ b/logger.gemspec @@ -15,7 +15,11 @@ Gem::Specification.new do |spec| spec.homepage = "https://github.com/ruby/logger" spec.licenses = ["Ruby", "BSD-2-Clause"] - spec.files = Dir.glob("lib/**/*.rb") + ["logger.gemspec", "BSDL", "COPYING"] + # Specify which files should be added to the gem when it is released. + # The `git ls-files -z` loads the files in the RubyGem that have been added into git. + spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do + `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } + end spec.require_paths = ["lib"] spec.required_ruby_version = ">= 2.5.0" From 9f0afd896f3659321fbd03b86cd4e6e83da40577 Mon Sep 17 00:00:00 2001 From: Andrew Konchin Date: Thu, 9 Jan 2025 19:34:22 +0200 Subject: [PATCH 43/83] Add workaround for TruffleRuby and do not use File::SHARE_DELETE --- lib/logger/log_device.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/logger/log_device.rb b/lib/logger/log_device.rb index b5b7390..7a40160 100644 --- a/lib/logger/log_device.rb +++ b/lib/logger/log_device.rb @@ -70,7 +70,12 @@ def reopen(log = nil) # :stopdoc: MODE = File::WRONLY | File::APPEND - MODE_TO_OPEN = MODE | File::SHARE_DELETE | File::BINARY + # temporary workaround for TruffleRuby + if File.const_defined? :SHARE_DELETE + MODE_TO_OPEN = MODE | File::SHARE_DELETE | File::BINARY + else + MODE_TO_OPEN = MODE | File::BINARY + end MODE_TO_CREATE = MODE_TO_OPEN | File::CREAT | File::EXCL def set_dev(log) From ef3a1280387217824785831b7ced3c3f865807e8 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 10 Jan 2025 15:05:03 +0900 Subject: [PATCH 44/83] Bump up v1.6.5 --- lib/logger/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logger/version.rb b/lib/logger/version.rb index e1e6b97..84bb899 100644 --- a/lib/logger/version.rb +++ b/lib/logger/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Logger - VERSION = "1.6.4" + VERSION = "1.6.5" end From 07580da0666af08be4f459cf1799a15b92c6c56e Mon Sep 17 00:00:00 2001 From: Andrew Konchin Date: Fri, 10 Jan 2025 15:29:11 +0200 Subject: [PATCH 45/83] Skip failing tests on TruffleRuby and JRuby --- test/logger/test_logdevice.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/logger/test_logdevice.rb b/test/logger/test_logdevice.rb index d3e4a99..25c52c1 100644 --- a/test/logger/test_logdevice.rb +++ b/test/logger/test_logdevice.rb @@ -437,7 +437,9 @@ def test_shifting_size_not_rotate_too_much logdev1.write(message) assert_file.identical?(log, logdev1.dev) # NOTE: below assertion fails in JRuby 9.3 and TruffleRuby - assert_file.identical?(log + ".0", logdev2.dev) + unless %w[jruby truffleruby].include? RUBY_ENGINE + assert_file.identical?(log + ".0", logdev2.dev) + end logdev2.write(message) assert_file.identical?(log, logdev1.dev) From 1e594137033be246c2973eda3db7e19777a2ed83 Mon Sep 17 00:00:00 2001 From: Andrew Konchin Date: Fri, 10 Jan 2025 15:30:23 +0200 Subject: [PATCH 46/83] Add TruffleRuby in CI --- .github/workflows/test.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fac7d18..ad325f0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,7 @@ jobs: ruby-versions: uses: ruby/actions/.github/workflows/ruby_versions.yml@master with: - engine: cruby + engine: cruby-truffleruby min_version: 2.5 test: @@ -19,6 +19,10 @@ jobs: exclude: - ruby: 2.5 os: macos-latest + - ruby: truffleruby + os: windows-latest + - ruby: truffleruby-head + os: windows-latest runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 From 113b82a06b3076b93a71cd467e1605b23afb3088 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Fri, 10 Jan 2025 16:40:03 +0100 Subject: [PATCH 47/83] Improve comment in log_device.rb --- lib/logger/log_device.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logger/log_device.rb b/lib/logger/log_device.rb index 7a40160..31aa727 100644 --- a/lib/logger/log_device.rb +++ b/lib/logger/log_device.rb @@ -70,7 +70,7 @@ def reopen(log = nil) # :stopdoc: MODE = File::WRONLY | File::APPEND - # temporary workaround for TruffleRuby + # TruffleRuby < 24.2 does not have File::SHARE_DELETE if File.const_defined? :SHARE_DELETE MODE_TO_OPEN = MODE | File::SHARE_DELETE | File::BINARY else From 08f9fb3805a499ffd05e43506e1917345d9230cc Mon Sep 17 00:00:00 2001 From: Shizuo Fujita Date: Sat, 11 Jan 2025 12:14:18 +0900 Subject: [PATCH 48/83] Accept the object that has #to_path in Logger::LogDevice.new Because the `path` keyword in File.new will only accept objects that have `to_str`. --- lib/logger/log_device.rb | 1 + test/logger/test_logdevice.rb | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/lib/logger/log_device.rb b/lib/logger/log_device.rb index 31aa727..774bf99 100644 --- a/lib/logger/log_device.rb +++ b/lib/logger/log_device.rb @@ -99,6 +99,7 @@ def fixup_mode(dev, filename) else def fixup_mode(dev, filename) return dev if @binmode + filename = filename.respond_to?(:to_path) ? filename.to_path : filename dev.autoclose = false old_dev = dev dev = File.new(dev.fileno, mode: MODE, path: filename) diff --git a/test/logger/test_logdevice.rb b/test/logger/test_logdevice.rb index 25c52c1..2d1a201 100644 --- a/test/logger/test_logdevice.rb +++ b/test/logger/test_logdevice.rb @@ -3,6 +3,7 @@ require 'logger' require 'tempfile' require 'tmpdir' +require 'pathname' class TestLogDevice < Test::Unit::TestCase class LogExcnRaiser @@ -79,6 +80,20 @@ def test_initialize File.unlink(tempfile) tempfile.close(true) end + # logfile object with Pathname object + tempfile = Tempfile.new("logger") + pathname = Pathname.new(tempfile.path) + logdev = d(pathname) + begin + logdev.write('world') + logfile = File.read(pathname) + assert_equal(1, logfile.split(/\n/).size) + assert_match(/^world$/, logfile) + assert_equal(pathname, logdev.filename) + ensure + logdev.close + tempfile.close(true) + end end def test_write From c4e0c90facab2e43393d389e5306ede194b39038 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 06:38:30 +0000 Subject: [PATCH 49/83] Bump step-security/harden-runner from 2.10.2 to 2.10.3 Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.10.2 to 2.10.3. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/0080882f6c36860b6ba35c610c98ce87d4e2f26f...c95a14d0e5bab51a9f56296a4eb0e416910cd350) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/push_gem.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index 410096f..de09ae8 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 + uses: step-security/harden-runner@c95a14d0e5bab51a9f56296a4eb0e416910cd350 # v2.10.3 with: egress-policy: audit From 4682b6ff3a6a542d124dd0ee3dc4e3fdaa214b5c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 06:15:52 +0000 Subject: [PATCH 50/83] Bump step-security/harden-runner from 2.10.3 to 2.10.4 Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.10.3 to 2.10.4. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/c95a14d0e5bab51a9f56296a4eb0e416910cd350...cb605e52c26070c328afc4562f0b4ada7618a84e) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/push_gem.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index de09ae8..846d706 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@c95a14d0e5bab51a9f56296a4eb0e416910cd350 # v2.10.3 + uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 with: egress-policy: audit From 0eb10f2d278435899ce9055c98eb5b53caa0092a Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 13 Feb 2025 18:27:31 +0900 Subject: [PATCH 51/83] Bump up v1.6.6 --- lib/logger/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logger/version.rb b/lib/logger/version.rb index 84bb899..463be13 100644 --- a/lib/logger/version.rb +++ b/lib/logger/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Logger - VERSION = "1.6.5" + VERSION = "1.6.6" end From 022f304044e41f7ae786049fbc3df8e225da26d0 Mon Sep 17 00:00:00 2001 From: titusfortner Date: Thu, 25 Mar 2021 22:09:32 -0500 Subject: [PATCH 52/83] allow setting shift variables in LogDevice when using reopen --- lib/logger.rb | 5 ++- lib/logger/log_device.rb | 26 +++++++----- test/logger/test_logdevice.rb | 77 +++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 13 deletions(-) diff --git a/lib/logger.rb b/lib/logger.rb index 8d6e0d7..3e6ab38 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -621,8 +621,9 @@ def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG, # # "E, [2022-05-12T14:21:27.596726 #22428] ERROR -- : one\n", # # "E, [2022-05-12T14:23:05.847241 #22428] ERROR -- : three\n"] # - def reopen(logdev = nil) - @logdev&.reopen(logdev) + def reopen(logdev = nil, shift_age = nil, shift_size = nil, shift_period_suffix: nil, binmode: nil) + @logdev&.reopen(logdev, shift_age: shift_age, shift_size: shift_size, + shift_period_suffix: shift_period_suffix, binmode: binmode) self end diff --git a/lib/logger/log_device.rb b/lib/logger/log_device.rb index 774bf99..d1784ab 100644 --- a/lib/logger/log_device.rb +++ b/lib/logger/log_device.rb @@ -17,16 +17,7 @@ def initialize(log = nil, shift_age: nil, shift_size: nil, shift_period_suffix: @reraise_write_errors = reraise_write_errors mon_initialize set_dev(log) - if @filename - @shift_age = shift_age || 7 - @shift_size = shift_size || 1048576 - @shift_period_suffix = shift_period_suffix || '%Y%m%d' - - unless @shift_age.is_a?(Integer) - base_time = @dev.respond_to?(:stat) ? @dev.stat.mtime : Time.now - @next_rotate_time = next_rotate_time(base_time, @shift_age) - end - end + set_file(shift_age, shift_size, shift_period_suffix) if @filename end def write(message) @@ -50,9 +41,10 @@ def close end end - def reopen(log = nil) + def reopen(log = nil, shift_age: nil, shift_size: nil, shift_period_suffix: nil, binmode: nil) # reopen the same filename if no argument, do nothing for IO log ||= @filename if @filename + @binmode = binmode unless binmode.nil? if log synchronize do if @filename and @dev @@ -60,6 +52,7 @@ def reopen(log = nil) @filename = nil end set_dev(log) + set_file(shift_age, shift_size, shift_period_suffix) if @filename end end self @@ -92,6 +85,17 @@ def set_dev(log) end end + def set_file(shift_age, shift_size, shift_period_suffix) + @shift_age = shift_age.nil? ? @shift_age || 7 : shift_age + @shift_size = shift_size.nil? ? @shift_size || 1048576 : shift_size + @shift_period_suffix = shift_period_suffix.nil? ? @shift_period_suffix || '%Y%m%d' : shift_period_suffix + + unless @shift_age.is_a?(Integer) + base_time = @dev.respond_to?(:stat) ? @dev.stat.mtime : Time.now + @next_rotate_time = next_rotate_time(base_time, @shift_age) + end + end + if MODE_TO_OPEN == MODE def fixup_mode(dev, filename) dev diff --git a/test/logger/test_logdevice.rb b/test/logger/test_logdevice.rb index 2d1a201..05d3f63 100644 --- a/test/logger/test_logdevice.rb +++ b/test/logger/test_logdevice.rb @@ -205,6 +205,83 @@ def test_reopen_file_by_file end end + def test_shifting_size_with_reopen + tmpfile = Tempfile.new([File.basename(__FILE__, '.*'), '_1.log']) + logfile = tmpfile.path + logfile0 = logfile + '.0' + logfile1 = logfile + '.1' + logfile2 = logfile + '.2' + logfile3 = logfile + '.3' + tmpfile.close(true) + File.unlink(logfile) if File.exist?(logfile) + File.unlink(logfile0) if File.exist?(logfile0) + File.unlink(logfile1) if File.exist?(logfile1) + File.unlink(logfile2) if File.exist?(logfile2) + + logger = Logger.new(STDERR) + logger.reopen(logfile, 4, 100) + + logger.error("0" * 15) + assert_file.exist?(logfile) + assert_file.not_exist?(logfile0) + logger.error("0" * 15) + assert_file.exist?(logfile0) + assert_file.not_exist?(logfile1) + logger.error("0" * 15) + assert_file.exist?(logfile1) + assert_file.not_exist?(logfile2) + logger.error("0" * 15) + assert_file.exist?(logfile2) + assert_file.not_exist?(logfile3) + logger.error("0" * 15) + assert_file.not_exist?(logfile3) + logger.error("0" * 15) + assert_file.not_exist?(logfile3) + logger.close + File.unlink(logfile) + File.unlink(logfile0) + File.unlink(logfile1) + File.unlink(logfile2) + + tmpfile = Tempfile.new([File.basename(__FILE__, '.*'), '_2.log']) + logfile = tmpfile.path + logfile0 = logfile + '.0' + logfile1 = logfile + '.1' + logfile2 = logfile + '.2' + logfile3 = logfile + '.3' + tmpfile.close(true) + logger = Logger.new(logfile, 4, 150) + logger.error("0" * 15) + assert_file.exist?(logfile) + assert_file.not_exist?(logfile0) + logger.error("0" * 15) + assert_file.not_exist?(logfile0) + logger.error("0" * 15) + assert_file.exist?(logfile0) + assert_file.not_exist?(logfile1) + logger.error("0" * 15) + assert_file.not_exist?(logfile1) + logger.error("0" * 15) + assert_file.exist?(logfile1) + assert_file.not_exist?(logfile2) + logger.error("0" * 15) + assert_file.not_exist?(logfile2) + logger.error("0" * 15) + assert_file.exist?(logfile2) + assert_file.not_exist?(logfile3) + logger.error("0" * 15) + assert_file.not_exist?(logfile3) + logger.error("0" * 15) + assert_file.not_exist?(logfile3) + logger.error("0" * 15) + assert_file.not_exist?(logfile3) + logger.close + File.unlink(logfile) + File.unlink(logfile0) + File.unlink(logfile1) + File.unlink(logfile2) + end + def test_shifting_size tmpfile = Tempfile.new([File.basename(__FILE__, '.*'), '_1.log']) logfile = tmpfile.path From c937598c4d39e0e8ab4da890d100f2540d50e122 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 14 Feb 2025 12:06:07 +0900 Subject: [PATCH 53/83] Reduce repeating expressions --- lib/logger/log_device.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/logger/log_device.rb b/lib/logger/log_device.rb index d1784ab..44dce3d 100644 --- a/lib/logger/log_device.rb +++ b/lib/logger/log_device.rb @@ -86,9 +86,9 @@ def set_dev(log) end def set_file(shift_age, shift_size, shift_period_suffix) - @shift_age = shift_age.nil? ? @shift_age || 7 : shift_age - @shift_size = shift_size.nil? ? @shift_size || 1048576 : shift_size - @shift_period_suffix = shift_period_suffix.nil? ? @shift_period_suffix || '%Y%m%d' : shift_period_suffix + @shift_age = shift_age || @shift_age || 7 + @shift_size = shift_size || @shift_size || 1048576 + @shift_period_suffix = shift_period_suffix || @shift_period_suffix || '%Y%m%d' unless @shift_age.is_a?(Integer) base_time = @dev.respond_to?(:stat) ? @dev.stat.mtime : Time.now From 0d1c79146a72872befbb629dc42dace21c6fc064 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 14 Feb 2025 16:47:08 +0900 Subject: [PATCH 54/83] Refine conversion to path name Convert the given file name by the dedicated method, and re-use the converted name instead of the given argument. --- lib/logger/log_device.rb | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/logger/log_device.rb b/lib/logger/log_device.rb index 44dce3d..45545fa 100644 --- a/lib/logger/log_device.rb +++ b/lib/logger/log_device.rb @@ -97,16 +97,15 @@ def set_file(shift_age, shift_size, shift_period_suffix) end if MODE_TO_OPEN == MODE - def fixup_mode(dev, filename) + def fixup_mode(dev) dev end else - def fixup_mode(dev, filename) + def fixup_mode(dev) return dev if @binmode - filename = filename.respond_to?(:to_path) ? filename.to_path : filename dev.autoclose = false old_dev = dev - dev = File.new(dev.fileno, mode: MODE, path: filename) + dev = File.new(dev.fileno, mode: MODE, path: dev.path) old_dev.close PathAttr.set_path(dev, filename) if defined?(PathAttr) dev @@ -119,7 +118,7 @@ def open_logfile(filename) rescue Errno::ENOENT create_logfile(filename) else - dev = fixup_mode(dev, filename) + dev = fixup_mode(dev) dev.sync = true dev.binmode if @binmode dev @@ -130,7 +129,7 @@ def create_logfile(filename) begin logdev = File.open(filename, MODE_TO_CREATE) logdev.flock(File::LOCK_EX) - logdev = fixup_mode(logdev, filename) + logdev = fixup_mode(logdev) logdev.sync = true logdev.binmode if @binmode add_log_header(logdev) From 87b12e8e5513f9f2ded1a7ebc93a0996ecfa3658 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 14 Feb 2025 17:17:40 +0900 Subject: [PATCH 55/83] Extract `shift_log_file` The common part of `shift_log_age` and `shift_log_period`. --- lib/logger/log_device.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/logger/log_device.rb b/lib/logger/log_device.rb index 45545fa..98d5eb7 100644 --- a/lib/logger/log_device.rb +++ b/lib/logger/log_device.rb @@ -205,10 +205,7 @@ def shift_log_age File.rename("#{@filename}.#{i}", "#{@filename}.#{i+1}") end end - @dev.close rescue nil - File.rename("#{@filename}", "#{@filename}.0") - @dev = create_logfile(@filename) - return true + shift_log_file("#{@filename}.0") end def shift_log_period(period_end) @@ -224,8 +221,12 @@ def shift_log_period(period_end) break unless FileTest.exist?(age_file) end end + shift_log_file(age_file) + end + + def shift_log_file(shifted) @dev.close rescue nil - File.rename("#{@filename}", age_file) + File.rename(@filename, shifted) @dev = create_logfile(@filename) return true end From 4dbc1ac3b432f7ffbc18cda04891bb77a1cf6a59 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 14 Feb 2025 17:19:43 +0900 Subject: [PATCH 56/83] Let `lock_shift_log` return `true` on success In the case log shifted by another process, opened log device was returned. --- lib/logger/log_device.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/logger/log_device.rb b/lib/logger/log_device.rb index 98d5eb7..dbbc0d9 100644 --- a/lib/logger/log_device.rb +++ b/lib/logger/log_device.rb @@ -184,6 +184,7 @@ def lock_shift_log @dev = open_logfile(@filename) end end + true rescue Errno::ENOENT # @filename file would not exist right after #rename and before #create_logfile if retry_limit <= 0 From 1f8966475133673ed698b4ad70cacae40a43d50d Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 14 Feb 2025 17:33:05 +0900 Subject: [PATCH 57/83] Remove duplicate and old variable --- test/logger/test_logdevice.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/logger/test_logdevice.rb b/test/logger/test_logdevice.rb index 05d3f63..a65ceaf 100644 --- a/test/logger/test_logdevice.rb +++ b/test/logger/test_logdevice.rb @@ -842,8 +842,6 @@ class << Time end end - env_tz_works = /linux|darwin|freebsd/ =~ RUBY_PLATFORM # borrow from test/ruby/test_time_tz.rb - def test_shifting_weekly_exist_file Dir.mktmpdir do |tmpdir| assert_in_out_err([{"TZ"=>"UTC"}, *%W"-I#{@top_dir} -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") From 30e4359386ce6fc4471daa045922bccba292c831 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 14 Feb 2025 18:52:36 +0900 Subject: [PATCH 58/83] Copy permission and ownership at shift Fix #80 --- lib/logger/log_device.rb | 14 ++++++++++++++ test/logger/test_logdevice.rb | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/lib/logger/log_device.rb b/lib/logger/log_device.rb index dbbc0d9..cde3158 100644 --- a/lib/logger/log_device.rb +++ b/lib/logger/log_device.rb @@ -226,9 +226,23 @@ def shift_log_period(period_end) end def shift_log_file(shifted) + stat = @dev.stat @dev.close rescue nil File.rename(@filename, shifted) @dev = create_logfile(@filename) + mode, uid, gid = stat.mode, stat.uid, stat.gid + begin + @dev.chmod(mode) if mode + mode = nil + @dev.chown(uid, gid) + rescue Errno::EPERM + if mode + # failed to chmod, probably nothing can do more. + elsif uid + uid = nil + retry # to change gid only + end + end return true end end diff --git a/test/logger/test_logdevice.rb b/test/logger/test_logdevice.rb index a65ceaf..c9b0816 100644 --- a/test/logger/test_logdevice.rb +++ b/test/logger/test_logdevice.rb @@ -205,6 +205,23 @@ def test_reopen_file_by_file end end + def test_perm_after_shift + mode = 0o611 + File.open(@filename, "w") {|f| f.chmod mode} + logfile = @filename + logfile0 = logfile + '.0' + logdev = d(@filename, shift_age: 1, shift_size: 0) + logdev.write('hello') + logdev.write('hello') + logdev.close + + assert_equal File.stat(logfile0).mode, File.stat(logfile).mode + ensure + if logfile0 + File.unlink(logfile0) rescue nil + end + end + def test_shifting_size_with_reopen tmpfile = Tempfile.new([File.basename(__FILE__, '.*'), '_1.log']) logfile = tmpfile.path From 1efdf6b0145d875b94623bd43a8666378cd007b9 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 14 Feb 2025 19:28:30 +0900 Subject: [PATCH 59/83] Subclasses `initialize` must call super Warn wrong code, https://github.com/ruby/logger/pull/100: > Some Ruby apps subclass Logger without running the superclass > constructor, which means that `@level_override` isn't initialized > properly. --- lib/logger.rb | 9 +++++++++ test/logger/test_logger.rb | 15 +++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/lib/logger.rb b/lib/logger.rb index 3e6ab38..4273a43 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -749,6 +749,15 @@ def format_severity(severity) # Guarantee the existence of this ivar even when subclasses don't call the superclass constructor. def level_override + unless defined?(@level_override) + bad = self.class.instance_method(:initialize) + file, line = bad.source_location + Kernel.warn <<~";;;", uplevel: 2 + Logger not initialized properly + #{file}:#{line}: info: #{bad.owner}\##{bad.name}: \ + does not call super probably + ;;; + end @level_override ||= {} end diff --git a/test/logger/test_logger.rb b/test/logger/test_logger.rb index 2023553..ea27fba 100644 --- a/test/logger/test_logger.rb +++ b/test/logger/test_logger.rb @@ -399,4 +399,19 @@ def test_does_not_instantiate_log_device_for_File_NULL l = Logger.new(File::NULL) assert_nil(l.instance_variable_get(:@logdev)) end + + def test_subclass_initialize + bad_logger = Class.new(Logger) {def initialize(*); end}.new(IO::NULL) + line = __LINE__ - 1 + file = Regexp.quote(__FILE__) + assert_warning(/not initialized properly.*\n#{file}:#{line}:/) do + bad_logger.level + end + + good_logger = Class.new(Logger) {def initialize(*); super; end}.new(IO::NULL) + file = Regexp.quote(__FILE__) + assert_warning('') do + good_logger.level + end + end end From 552b07555257243e649dfb89b44ea6de2f92dee1 Mon Sep 17 00:00:00 2001 From: viralpraxis Date: Thu, 13 Feb 2025 00:02:31 +0300 Subject: [PATCH 60/83] [Feature #21133] Add `skip_header` option ref: https://bugs.ruby-lang.org/issues/21133 Creating a logger automatically writes a hardcoded header comment ("# Logfile created on ..."). While this helps verify that logdev is writable as early as possible (rather than on the first log entry), it also serves as a useful indicator of which program created the logfile. However, this header can introduce unnecessary complexity -- especially when working with third-party tools that need to ignore these lines. This commit introduces a `skip_header` boolean option (default is `false`), allowing API consumers to disable the header if needed. --- lib/logger.rb | 8 ++++++-- lib/logger/log_device.rb | 8 ++++++-- test/logger/test_logdevice.rb | 6 ++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/logger.rb b/lib/logger.rb index 3e6ab38..48b137d 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -577,11 +577,14 @@ def fatal!; self.level = FATAL; end # - +reraise_write_errors+: An array of exception classes, which will # be reraised if there is an error when writing to the log device. # The default is to swallow all exceptions raised. + # - +skip_header+: If +true+, prevents the logger from writing a header + # when creating a new log file. The default is +false+, meaning + # the header will be written as usual. # def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG, progname: nil, formatter: nil, datetime_format: nil, binmode: false, shift_period_suffix: '%Y%m%d', - reraise_write_errors: []) + reraise_write_errors: [], skip_header: false) self.level = level self.progname = progname @default_formatter = Formatter.new @@ -594,7 +597,8 @@ def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG, shift_size: shift_size, shift_period_suffix: shift_period_suffix, binmode: binmode, - reraise_write_errors: reraise_write_errors) + reraise_write_errors: reraise_write_errors, + skip_header: skip_header) end end diff --git a/lib/logger/log_device.rb b/lib/logger/log_device.rb index cde3158..e16f3b7 100644 --- a/lib/logger/log_device.rb +++ b/lib/logger/log_device.rb @@ -11,10 +11,14 @@ class LogDevice attr_reader :filename include MonitorMixin - def initialize(log = nil, shift_age: nil, shift_size: nil, shift_period_suffix: nil, binmode: false, reraise_write_errors: []) + def initialize( + log = nil, shift_age: nil, shift_size: nil, shift_period_suffix: nil, + binmode: false, reraise_write_errors: [], skip_header: false + ) @dev = @filename = @shift_age = @shift_size = @shift_period_suffix = nil @binmode = binmode @reraise_write_errors = reraise_write_errors + @skip_header = skip_header mon_initialize set_dev(log) set_file(shift_age, shift_size, shift_period_suffix) if @filename @@ -132,7 +136,7 @@ def create_logfile(filename) logdev = fixup_mode(logdev) logdev.sync = true logdev.binmode if @binmode - add_log_header(logdev) + add_log_header(logdev) unless @skip_header logdev.flock(File::LOCK_UN) logdev rescue Errno::EEXIST diff --git a/test/logger/test_logdevice.rb b/test/logger/test_logdevice.rb index c9b0816..ed7ca8a 100644 --- a/test/logger/test_logdevice.rb +++ b/test/logger/test_logdevice.rb @@ -502,6 +502,12 @@ def test_shifting_age_in_multiprocess end end + def test_open_without_header + d(@filename, skip_header: true) + + assert_equal("", File.read(@filename)) + end + def test_open_logfile_in_multiprocess tmpfile = Tempfile.new([File.basename(__FILE__, '.*'), '_1.log']) logfile = tmpfile.path From 0892e1a636e63849d1682b104a106d88c29e0162 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 14 Feb 2025 20:50:09 +0900 Subject: [PATCH 61/83] [DOC] Specify files for documents --- .document | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .document diff --git a/.document b/.document new file mode 100644 index 0000000..e2b9569 --- /dev/null +++ b/.document @@ -0,0 +1,4 @@ +BSDL +COPYING +README.md +lib/ From 25df1edf32ddb67685770cc278ab709cfe40f315 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 14 Feb 2025 20:51:33 +0900 Subject: [PATCH 62/83] [DOC] Missing descriptions of `Logger.new` arguments --- lib/logger.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/logger.rb b/lib/logger.rb index 4273a43..e0f3f77 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -547,6 +547,16 @@ def fatal!; self.level = FATAL; end # entries are to be written to the given stream. # - +nil+ or +File::NULL+: no entries are to be written. # + # Argument +shift_age+ must be on of: + # + # - The number of log files to be in the rotation. + # See {Size-Based Rotation}[rdoc-ref:Logger@Size-Based+Rotation]. + # - A string period indicator. + # See {Periodic Rotation}[rdoc-ref:Logger@Periodic+Rotation]. + # + # Argument +shift_size+ is the maximum size (in bytes) of each log file. + # See {Size-Based Rotation}[rdoc-ref:Logger@Size-Based+Rotation]. + # # Examples: # # Logger.new('t.log') @@ -566,14 +576,18 @@ def fatal!; self.level = FATAL; end # # - +formatter+: sets the entry formatter; default is +nil+. # See {formatter=}[Logger.html#attribute-i-formatter]. + # # - +datetime_format+: sets the format for entry timestamp; # default is +nil+. # See #datetime_format=. + # # - +binmode+: sets whether the logger writes in binary mode; # default is +false+. + # # - +shift_period_suffix+: sets the format for the filename suffix # for periodic log file rotation; default is '%Y%m%d'. # See {Periodic Rotation}[rdoc-ref:Logger@Periodic+Rotation]. + # # - +reraise_write_errors+: An array of exception classes, which will # be reraised if there is an error when writing to the log device. # The default is to swallow all exceptions raised. From 6f7f90854a8b58a9a0d78b9aacd8d153b2985627 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 14 Feb 2025 20:53:20 +0900 Subject: [PATCH 63/83] [DOC] Fix a typo --- lib/logger.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logger.rb b/lib/logger.rb index e0f3f77..62ec783 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -547,7 +547,7 @@ def fatal!; self.level = FATAL; end # entries are to be written to the given stream. # - +nil+ or +File::NULL+: no entries are to be written. # - # Argument +shift_age+ must be on of: + # Argument +shift_age+ must be one of: # # - The number of log files to be in the rotation. # See {Size-Based Rotation}[rdoc-ref:Logger@Size-Based+Rotation]. From f80a18e6bfc24715f4c6595d0b78f5f1e123dd57 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 14 Feb 2025 20:54:51 +0900 Subject: [PATCH 64/83] [DOC] Fix markups for the global variables --- lib/logger.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/logger.rb b/lib/logger.rb index 62ec783..25e2c27 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -543,8 +543,8 @@ def fatal!; self.level = FATAL; end # - A string filepath: entries are to be written # to the file at that path; if the file at that path exists, # new entries are appended. - # - An IO stream (typically +$stdout+, +$stderr+. or an open file): - # entries are to be written to the given stream. + # - An IO stream (typically $stdout, $stderr. or + # an open file): entries are to be written to the given stream. # - +nil+ or +File::NULL+: no entries are to be written. # # Argument +shift_age+ must be one of: From 88cd1735ed19855e90eff18bf765fdc43167ed5c Mon Sep 17 00:00:00 2001 From: George Ogata Date: Wed, 22 Mar 2023 01:14:05 -0400 Subject: [PATCH 65/83] Expose the logdev The motivation here is to fix a Rails issue caused by the way ActiveSupport extends the ruby Logger to add broadcasting of messages to multiple destinations. [1] I believe the problem could be much more elegantly solved if Logger exposed the underlying LogDevice. Going by repo history, the existence of this object hasn't changed since 2003, so I think it's stable enough to expose. In addition to letting you read the logdev, this also lets you pass a logdev in. To implement broadcasting, we could now define a LogDevice subclass that delegates its 3 methods to the LogDevices of a list of underlying loggers, and simply create a new logger with this device. [1]: https://github.com/rails/rails/blob/ba19dbc49956a73f417abd68c7a5f33e302eacd3/activesupport/lib/active_support/logger.rb#L23 --- lib/logger.rb | 15 ++++++++++++++- test/logger/test_logger.rb | 10 ++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/logger.rb b/lib/logger.rb index 25e2c27..4838107 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -545,6 +545,7 @@ def fatal!; self.level = FATAL; end # new entries are appended. # - An IO stream (typically $stdout, $stderr. or # an open file): entries are to be written to the given stream. + # - An instance of Logger::LogDevice, such as the #logdev of another Logger. # - +nil+ or +File::NULL+: no entries are to be written. # # Argument +shift_age+ must be one of: @@ -603,7 +604,13 @@ def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG, self.formatter = formatter @logdev = nil @level_override = {} - if logdev && logdev != File::NULL + return unless logdev + case logdev + when File::NULL + # null logger + when LogDevice + @logdev = logdev + else @logdev = LogDevice.new(logdev, shift_age: shift_age, shift_size: shift_size, shift_period_suffix: shift_period_suffix, @@ -612,6 +619,12 @@ def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG, end end + # The underlying log device. + # + # This is the first argument passed to the constructor, wrapped in a + # Logger::LogDevice, along with the binmode flag and rotation options. + attr_reader :logdev + # Sets the logger's output stream: # # - If +logdev+ is +nil+, reopens the current output stream. diff --git a/test/logger/test_logger.rb b/test/logger/test_logger.rb index ea27fba..75a0f74 100644 --- a/test/logger/test_logger.rb +++ b/test/logger/test_logger.rb @@ -177,6 +177,16 @@ def test_initialize assert_nil(logger.datetime_format) end + def test_logdev + logger = Logger.new(STDERR) + assert_instance_of(Logger::LogDevice, logger.logdev) + + logdev = Logger::LogDevice.new(STDERR) + logger = Logger.new(logdev) + assert_instance_of(Logger::LogDevice, logger.logdev) + assert_equal(STDERR, logger.logdev.dev) + end + def test_initialize_with_level # default logger = Logger.new(STDERR) From 9e506e50f357f48d2940ab5069ce9c030300eaaf Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 14 Feb 2025 22:23:52 +0900 Subject: [PATCH 66/83] [DOC] Add .rdoc_options --- .rdoc_options | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .rdoc_options diff --git a/.rdoc_options b/.rdoc_options new file mode 100644 index 0000000..2d29a05 --- /dev/null +++ b/.rdoc_options @@ -0,0 +1,3 @@ +--- +main_page: README.md +title: Documentation for Logger From c1cfcb52bd43d14d5563bf7814ef607cdfb4d503 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 14 Feb 2025 23:12:56 +0900 Subject: [PATCH 67/83] Include selected files only in the gem file --- logger.gemspec | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/logger.gemspec b/logger.gemspec index 09d9600..d8ffba0 100644 --- a/logger.gemspec +++ b/logger.gemspec @@ -17,9 +17,12 @@ Gem::Specification.new do |spec| # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. - spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do - `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } - end + pattern = %W[ + :(glob,top)* :/exe :/ext :/lib + :^/.git* :^/Gemfile* :^/Rakefile* + :(literal,top,exclude)#{File.basename(__FILE__)} + ] + spec.files = IO.popen(%w[git ls-files -z] + pattern, chdir: __dir__, &:read).split("\0") spec.require_paths = ["lib"] spec.required_ruby_version = ">= 2.5.0" From 752b50bbeaf373338b472c0dc7beeb5752c74558 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 06:54:06 +0000 Subject: [PATCH 68/83] Bump step-security/harden-runner from 2.10.4 to 2.11.0 Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.10.4 to 2.11.0. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/cb605e52c26070c328afc4562f0b4ada7618a84e...4d991eb9b905ef189e4c376166672c3f2f230481) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/push_gem.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index 846d706..847493f 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0 with: egress-policy: audit From f474d07d9890a03e6e40430c4e2ee933c6193d7e Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 27 Mar 2025 10:32:53 +0900 Subject: [PATCH 69/83] Bump up v1.7.0 --- lib/logger/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logger/version.rb b/lib/logger/version.rb index 463be13..0d74bec 100644 --- a/lib/logger/version.rb +++ b/lib/logger/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Logger - VERSION = "1.6.6" + VERSION = "1.7.0" end From 91e4483505e98417149bc050695f7f426de98d8f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Apr 2025 07:01:05 +0000 Subject: [PATCH 70/83] Bump step-security/harden-runner from 2.11.0 to 2.11.1 Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.11.0 to 2.11.1. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/4d991eb9b905ef189e4c376166672c3f2f230481...c6295a65d1254861815972266d5933fd6e532bdf) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.11.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/push_gem.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index 847493f..610628a 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0 + uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1 with: egress-policy: audit From 156d64835b80c0cff6aa2c6878895054d16f035d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Apr 2025 06:14:32 +0000 Subject: [PATCH 71/83] Bump step-security/harden-runner from 2.11.1 to 2.12.0 Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.11.1 to 2.12.0. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/c6295a65d1254861815972266d5933fd6e532bdf...0634a2670c59f64b4a01f0f96f84700a4088b9f0) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.12.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/push_gem.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index 610628a..2396c78 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1 + uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 with: egress-policy: audit From 81c837b895533f7733e9185dea21ec23f469b169 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Mon, 12 May 2025 19:52:52 +0900 Subject: [PATCH 72/83] Update the latest versions of GitHub Actions --- .github/workflows/push_gem.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index 2396c78..64cb5c3 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -27,10 +27,10 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set up Ruby - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 + uses: ruby/setup-ruby@e34163cd15f4bb403dcd72d98e295997e6a55798 # v1.238.0 with: bundler-cache: true ruby-version: ruby From 9cdb56aa875026eaebacb1d5e4882db7aed690c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Jun 2025 06:49:17 +0000 Subject: [PATCH 73/83] Bump step-security/harden-runner from 2.12.0 to 2.12.1 Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.12.0 to 2.12.1. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/0634a2670c59f64b4a01f0f96f84700a4088b9f0...002fdce3c6a235733a90a27c80493a3241e56863) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.12.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/push_gem.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index 64cb5c3..fbc0b0a 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 + uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1 with: egress-policy: audit From 160142a7bfbb969442f36307ee6c647d0a752e2d Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 20 Jun 2025 13:46:16 +0900 Subject: [PATCH 74/83] Use GITHUB_TOKEN instead of admin credential --- .github/workflows/push_gem.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index fbc0b0a..297ac7b 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -43,4 +43,4 @@ jobs: tag_name="$(git describe --tags --abbrev=0)" gh release create "${tag_name}" --verify-tag --generate-notes env: - GITHUB_TOKEN: ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 7b9e9769c9b54b0c8750e9a60dd778c2e19fca6b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Jul 2025 08:28:31 +0000 Subject: [PATCH 75/83] Bump step-security/harden-runner from 2.12.1 to 2.12.2 Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.12.1 to 2.12.2. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/002fdce3c6a235733a90a27c80493a3241e56863...6c439dc8bdf85cadbbce9ed30d1c7b959517bc49) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.12.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/push_gem.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index 297ac7b..460fb77 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1 + uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2 with: egress-policy: audit From 7ac7a8c3bbe6d00c8134f12af4eb53b4e92e7a03 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Jul 2025 08:32:01 +0000 Subject: [PATCH 76/83] Bump step-security/harden-runner from 2.12.2 to 2.13.0 Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.12.2 to 2.13.0. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/6c439dc8bdf85cadbbce9ed30d1c7b959517bc49...ec9f2d5744a09debf3a187a3f4f675c53b671911) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.13.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/push_gem.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index 460fb77..9ffbcfd 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2 + uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 with: egress-policy: audit From b953337ecbf626e01dbadd36012837d7fe582b96 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 09:54:49 +0000 Subject: [PATCH 77/83] Bump actions/checkout from 4 to 5 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/push_gem.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index 9ffbcfd..9903b23 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -27,7 +27,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Set up Ruby uses: ruby/setup-ruby@e34163cd15f4bb403dcd72d98e295997e6a55798 # v1.238.0 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ad325f0..9e037d6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,7 +25,7 @@ jobs: os: windows-latest runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: From a5a4b7da070cced373cdf41dc4dbaa5dca9d3a6f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Sep 2025 06:27:05 +0000 Subject: [PATCH 78/83] Bump step-security/harden-runner from 2.13.0 to 2.13.1 Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.13.0 to 2.13.1. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/ec9f2d5744a09debf3a187a3f4f675c53b671911...f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.13.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/push_gem.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index 9903b23..5ec3a88 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1 with: egress-policy: audit From 401f4136c8c786dbee6f2b3c8053a9f6ac9d76c0 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Wed, 29 Oct 2025 15:20:52 +0900 Subject: [PATCH 79/83] Update the latest versions of actions --- .github/workflows/push_gem.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index 5ec3a88..7ba29e7 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -30,13 +30,13 @@ jobs: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Set up Ruby - uses: ruby/setup-ruby@e34163cd15f4bb403dcd72d98e295997e6a55798 # v1.238.0 + uses: ruby/setup-ruby@d5126b9b3579e429dd52e51e68624dda2e05be25 # v1.267.0 with: bundler-cache: true ruby-version: ruby - name: Publish to RubyGems - uses: rubygems/release-gem@a25424ba2ba8b387abc8ef40807c2c85b96cbe32 # v1.1.1 + uses: rubygems/release-gem@1c162a739e8b4cb21a676e97b087e8268d8fc40b # v1.1.2 - name: Create GitHub release run: | From 3f58316b0974b53178763553c7d71cbf9bb48016 Mon Sep 17 00:00:00 2001 From: Olle Jonsson Date: Mon, 10 Nov 2025 09:34:10 +0100 Subject: [PATCH 80/83] test_logdevice: Suppress warnings in a test power_assert warns about "this Ruby version does not support pattern matching" for versions before 3.0. This avoids issues when running the tests on those versions. --- test/logger/test_logdevice.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/logger/test_logdevice.rb b/test/logger/test_logdevice.rb index ed7ca8a..f8350df 100644 --- a/test/logger/test_logdevice.rb +++ b/test/logger/test_logdevice.rb @@ -745,7 +745,7 @@ class << Time def test_shifting_weekly_dst_change Dir.mktmpdir do |tmpdir| - assert_separately([{"TZ"=>"Europe/London"}, *%W"-I#{@top_dir} -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") + assert_separately([{"TZ"=>"Europe/London"}, *%W"-I#{@top_dir} -W0 -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") begin; begin module FakeTime @@ -776,7 +776,7 @@ class << Time def test_shifting_monthly_dst_change Dir.mktmpdir do |tmpdir| - assert_separately([{"TZ"=>"Europe/London"}, *%W"-I#{@top_dir} -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") + assert_separately([{"TZ"=>"Europe/London"}, *%W"-I#{@top_dir} -W0 -rlogger -C#{tmpdir} -"], "#{<<-"begin;"}\n#{<<-'end;'}") begin; begin module FakeTime From 2bd35211bc4d41102b35d65aae6f4818afbfe73b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 08:44:25 +0000 Subject: [PATCH 81/83] Bump step-security/harden-runner from 2.13.1 to 2.13.2 Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.13.1 to 2.13.2. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a...95d9a5deda9de15063e7595e9719c11c38c90ae2) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.13.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/push_gem.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index 7ba29e7..5e34c8b 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1 + uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2 with: egress-policy: audit From e16be675408a53f54e3312a468abc4155147e1ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 06:02:45 +0000 Subject: [PATCH 82/83] Bump actions/checkout from 5 to 6 Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Commits](https://github.com/actions/checkout/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/push_gem.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index 5e34c8b..70cad70 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -27,7 +27,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - name: Set up Ruby uses: ruby/setup-ruby@d5126b9b3579e429dd52e51e68624dda2e05be25 # v1.267.0 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9e037d6..73a7361 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,7 +25,7 @@ jobs: os: windows-latest runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: From 9f6e7f0061713dd5b6855638f627973b27bfb0ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 06:02:09 +0000 Subject: [PATCH 83/83] Bump step-security/harden-runner from 2.13.2 to 2.13.3 Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.13.2 to 2.13.3. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/95d9a5deda9de15063e7595e9719c11c38c90ae2...df199fb7be9f65074067a9eb93f12bb4c5547cf2) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.13.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/push_gem.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml index 70cad70..5c4951a 100644 --- a/.github/workflows/push_gem.yml +++ b/.github/workflows/push_gem.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2 + uses: step-security/harden-runner@df199fb7be9f65074067a9eb93f12bb4c5547cf2 # v2.13.3 with: egress-policy: audit