From 69fcaec798a457045221df142989f2fda602467a Mon Sep 17 00:00:00 2001 From: Simon Perepelitsa Date: Tue, 14 Aug 2018 15:39:48 +0300 Subject: [PATCH 01/10] Improve performance --- .travis.yml | 4 --- lib/ruby_warning_filter.rb | 50 +++++++++++--------------------------- test/bench.rb | 4 +-- 3 files changed, 16 insertions(+), 42 deletions(-) diff --git a/.travis.yml b/.travis.yml index cec065e..749e642 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,5 @@ language: ruby rvm: - - "2.0.0" - - "2.1" - - "2.2" - - "2.3" - "2.4" - "2.5" - ruby-head diff --git a/lib/ruby_warning_filter.rb b/lib/ruby_warning_filter.rb index 08e0d0f..4513cae 100644 --- a/lib/ruby_warning_filter.rb +++ b/lib/ruby_warning_filter.rb @@ -20,33 +20,39 @@ # class RubyWarningFilter < DelegateClass(IO) attr_reader :ruby_warnings + BACKTRACE = "\tfrom" + NEWLINE = "\n" + RUBY_WARNING = %r{:(\d+|in `\S+'): warning:} + EVAL_REDEFINED = /\(eval\):\d+: warning: previous definition of .+ was here/ + + # Variables used in tag attributes (Slim) always cause a warning. + # TODO: Report this. + IGNORED_TEMPLATE_WARNING = %r{\.slim:\d+: warning: possibly useless use of a variable in void context$} def initialize(io, ignore_path: Gem.path) super(io) @ruby_warnings = 0 @ignored = false - @ignore_path = ignore_path.to_set # Gem path can contain symlinks. # Some warnings use real path instead of symlinks so we need to ignore both. - ignore_path.each do |a| - @ignore_path << File.realpath(a) if File.exist?(a) - end + ignore_full_path = ignore_path + ignore_path.select{ |a| File.exist?(a) }.map{ |a| File.realpath(a) } + @ignore_regexp = Regexp.new("^(#{Regexp.union(ignore_full_path).source})") end def write(line) - if @ignored && (backtrace?(line) || line == "\n") + if @ignored && (line.start_with?(BACKTRACE) || line == NEWLINE) # Ignore the whole backtrace after ignored warning. # Some warnings write newline separately for some reason. @ignored = true nil - elsif @ignored && eval_redefined?(line) + elsif @ignored && EVAL_REDEFINED.match?(line) # Some gems use eval to redefine methods and the second warning with the source does not have file path, so we need to ignore that explicitly. @ignored = false nil - elsif ruby_warning?(line) - @ignored = ignored_warning?(line) + elsif RUBY_WARNING.match?(line) + @ignored = IGNORED_TEMPLATE_WARNING.match?(line) || @ignore_regexp.match?(line) unless @ignored @ruby_warnings += 1 super @@ -55,32 +61,4 @@ def write(line) super end end - - private - - def ruby_warning?(line) - line =~ %r{:(\d+|in `\S+'): warning:} - end - - def ignored_warning?(line) - external_warning?(line) || ignored_template_warning?(line) - end - - def external_warning?(line) - @ignore_path.any?{ |path| line.start_with?(path) } - end - - # Variables used in tag attributes (Slim) always cause a warning. - # TODO: Report this. - def ignored_template_warning?(line) - line =~ %r{\.slim:\d+: warning: possibly useless use of a variable in void context$} - end - - def backtrace?(line) - line.start_with?("\tfrom") - end - - def eval_redefined?(line) - line =~ /\(eval\):\d+: warning: previous definition of .+ was here/ - end end diff --git a/test/bench.rb b/test/bench.rb index 0c9f5af..9d8faec 100644 --- a/test/bench.rb +++ b/test/bench.rb @@ -22,8 +22,8 @@ def write_errors(io) # Sample results in Ruby 2.3.1: # -# plain File 80.673k (± 2.5%) i/s - 410.454k in 5.091134s -# RubyWarningFilter 11.934k (± 4.7%) i/s - 59.721k in 5.017126s +# plain File 75.140k (± 4.3%) i/s - 374.952k in 5.000983s +# RubyWarningFilter 40.768k (± 4.6%) i/s - 205.377k in 5.050529s Benchmark.ips do |x| x.report "plain File" do write_errors(file) From d44c22e08e58cbd44be7dcf789d7b9f240ac3079 Mon Sep 17 00:00:00 2001 From: Simon Perepelitsa Date: Tue, 14 Aug 2018 15:58:03 +0300 Subject: [PATCH 02/10] Prepare for release --- Readme.md | 4 ++-- ruby_warning_filter.gemspec | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Readme.md b/Readme.md index 89d29ef..a473528 100644 --- a/Readme.md +++ b/Readme.md @@ -9,7 +9,7 @@ With the help of this gem you can filter out all those useless messages and only Add to your Gemfile: ```ruby -gem "ruby_warning_filter", "~> 1.0.0" +gem "ruby_warning_filter", "~> 1.1.0" ``` Put the following code somewhere before your project is loaded. In a Rails application, a good place would be at the end of "config/boot.rb". @@ -28,4 +28,4 @@ The filter works by proxying all writes to stderr. It has been running for a whi [![Build Status](https://travis-ci.org/semaperepelitsa/ruby_warning_filter.svg?branch=master)](https://travis-ci.org/semaperepelitsa/ruby_warning_filter) -The gem is tested against Ruby versions 2.5 down to 2.0. +The gem is tested against Ruby 2.5, 2.4. diff --git a/ruby_warning_filter.gemspec b/ruby_warning_filter.gemspec index 37ca1a2..dceee22 100644 --- a/ruby_warning_filter.gemspec +++ b/ruby_warning_filter.gemspec @@ -1,10 +1,11 @@ Gem::Specification.new do |gem| gem.name = "ruby_warning_filter" - gem.version = "1.0.1" + gem.version = "1.1.0" gem.summary = "Hassle-free Ruby warnings" gem.license = "MIT" - gem.author = "Semyon Perepelitsa" + gem.author = "Simon Perepelitsa" gem.email = "sema@sema.in" + gem.required_ruby_version = '>= 2.4.0' gem.homepage = "https://github.com/semaperepelitsa/ruby_warning_filter" From 5838b6ad33a7c6bc06b193fc2245a6360e200557 Mon Sep 17 00:00:00 2001 From: Simon Perepelitsa Date: Tue, 18 Sep 2018 02:40:31 +0300 Subject: [PATCH 03/10] Update benchmark to also include newlines --- test/bench.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/bench.rb b/test/bench.rb index 9d8faec..98b240a 100644 --- a/test/bench.rb +++ b/test/bench.rb @@ -10,20 +10,22 @@ def write_errors(io) io.write("/path/to/gems/file.rb:297: warning: instance variable @object not initialized\n") end - 10.times do |i| + 7.times do |i| io.write("\tfrom /something/foo/bar:#{i}:in `
'") + io.write("\n") end - 10.times do + 7.times do io.write("(eval):1: warning: previous definition of foo was here") + io.write("\n") end end # Sample results in Ruby 2.3.1: # -# plain File 75.140k (± 4.3%) i/s - 374.952k in 5.000983s -# RubyWarningFilter 40.768k (± 4.6%) i/s - 205.377k in 5.050529s +# plain File 78.633k (± 2.0%) i/s - 393.692k in 5.008743s +# RubyWarningFilter 39.980k (± 3.4%) i/s - 200.889k in 5.031314s Benchmark.ips do |x| x.report "plain File" do write_errors(file) From 524d6c237f4c5e026792550db65561e9df023b1b Mon Sep 17 00:00:00 2001 From: Simon Perepelitsa Date: Tue, 18 Sep 2018 02:42:27 +0300 Subject: [PATCH 04/10] Perform faster check first (equality) --- lib/ruby_warning_filter.rb | 2 +- test/bench.rb | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/ruby_warning_filter.rb b/lib/ruby_warning_filter.rb index 4513cae..76dbf9d 100644 --- a/lib/ruby_warning_filter.rb +++ b/lib/ruby_warning_filter.rb @@ -42,7 +42,7 @@ def initialize(io, ignore_path: Gem.path) end def write(line) - if @ignored && (line.start_with?(BACKTRACE) || line == NEWLINE) + if @ignored && (line == NEWLINE || line.start_with?(BACKTRACE)) # Ignore the whole backtrace after ignored warning. # Some warnings write newline separately for some reason. @ignored = true diff --git a/test/bench.rb b/test/bench.rb index 98b240a..c3721c4 100644 --- a/test/bench.rb +++ b/test/bench.rb @@ -24,8 +24,8 @@ def write_errors(io) # Sample results in Ruby 2.3.1: # -# plain File 78.633k (± 2.0%) i/s - 393.692k in 5.008743s -# RubyWarningFilter 39.980k (± 3.4%) i/s - 200.889k in 5.031314s +# plain File 81.435k (± 2.5%) i/s - 411.632k in 5.057905s +# RubyWarningFilter 41.323k (± 2.5%) i/s - 210.236k in 5.090913s Benchmark.ips do |x| x.report "plain File" do write_errors(file) @@ -35,5 +35,3 @@ def write_errors(io) write_errors(filter) end end - - From 8ff2a4060d4b07cc18560c69a6ea2bd7cb2cf882 Mon Sep 17 00:00:00 2001 From: Simon Perepelitsa Date: Tue, 18 Sep 2018 02:52:14 +0300 Subject: [PATCH 05/10] Fix newlines would be sometimes ignored after a custom warning --- lib/ruby_warning_filter.rb | 1 + test/ruby_warnings_filter_test.rb | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/ruby_warning_filter.rb b/lib/ruby_warning_filter.rb index 76dbf9d..1a3cbaf 100644 --- a/lib/ruby_warning_filter.rb +++ b/lib/ruby_warning_filter.rb @@ -58,6 +58,7 @@ def write(line) super end else + @ignored = false super end end diff --git a/test/ruby_warnings_filter_test.rb b/test/ruby_warnings_filter_test.rb index 943d720..5624a4c 100644 --- a/test/ruby_warnings_filter_test.rb +++ b/test/ruby_warnings_filter_test.rb @@ -15,7 +15,8 @@ def setup def test_no_effect assert_equal 0, @err.ruby_warnings @err.puts "hello" - assert_equal "hello\n", @err.string + @err.print "world", "\n" + assert_equal "hello\nworld\n", @err.string assert_equal 0, @err.ruby_warnings end @@ -32,7 +33,11 @@ def test_ruby_warning @err.write "/path/to/ruby/2.2.0/gems/dragonfly-1.0.6/lib/dragonfly/utils.rb:41:in `uri_unescape': warning: URI.unescape is obsolete" @err.write "\n" - assert_equal "/path/to/script/middleware_test.rb:58: warning: assigned but unused variable - status\n", + # warn "custom warning" + @err.write "custom warning" + @err.write "\n" + + assert_equal "/path/to/script/middleware_test.rb:58: warning: assigned but unused variable - status\ncustom warning\n", @err.string assert_equal 1, @err.ruby_warnings end From c8d709b3b5e1f85aec2e2c7376f9a2cc57f2a922 Mon Sep 17 00:00:00 2001 From: Simon Perepelitsa Date: Tue, 2 Apr 2019 21:26:46 +0300 Subject: [PATCH 06/10] Add frozen_string_literal directive for future-proofing --- lib/ruby_warning_filter.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ruby_warning_filter.rb b/lib/ruby_warning_filter.rb index 1a3cbaf..aa5156a 100644 --- a/lib/ruby_warning_filter.rb +++ b/lib/ruby_warning_filter.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true require "delegate" require "set" @@ -21,7 +22,6 @@ class RubyWarningFilter < DelegateClass(IO) attr_reader :ruby_warnings BACKTRACE = "\tfrom" - NEWLINE = "\n" RUBY_WARNING = %r{:(\d+|in `\S+'): warning:} EVAL_REDEFINED = /\(eval\):\d+: warning: previous definition of .+ was here/ @@ -42,7 +42,7 @@ def initialize(io, ignore_path: Gem.path) end def write(line) - if @ignored && (line == NEWLINE || line.start_with?(BACKTRACE)) + if @ignored && (line == "\n" || line.start_with?(BACKTRACE)) # Ignore the whole backtrace after ignored warning. # Some warnings write newline separately for some reason. @ignored = true From 866879e05f81f9c6e576f0814811bb325705a017 Mon Sep 17 00:00:00 2001 From: Simon Perepelitsa Date: Tue, 2 Apr 2019 21:31:28 +0300 Subject: [PATCH 07/10] Test Ruby 2.6 as well --- .travis.yml | 1 + Readme.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 749e642..c9af5c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: ruby rvm: - "2.4" - "2.5" + - "2.6" - ruby-head matrix: allow_failures: diff --git a/Readme.md b/Readme.md index a473528..d6f2680 100644 --- a/Readme.md +++ b/Readme.md @@ -28,4 +28,4 @@ The filter works by proxying all writes to stderr. It has been running for a whi [![Build Status](https://travis-ci.org/semaperepelitsa/ruby_warning_filter.svg?branch=master)](https://travis-ci.org/semaperepelitsa/ruby_warning_filter) -The gem is tested against Ruby 2.5, 2.4. +The gem is tested against Ruby 2.6, 2.5, 2.4. From 51fbd34269c9657395d44163da1da50dbec9e3e4 Mon Sep 17 00:00:00 2001 From: Simon Perepelitsa Date: Tue, 2 Apr 2019 21:47:43 +0300 Subject: [PATCH 08/10] Ignore new Ruby 2.6 warning --- lib/ruby_warning_filter.rb | 8 +++++++- test/ruby_warnings_filter_test.rb | 7 +++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/ruby_warning_filter.rb b/lib/ruby_warning_filter.rb index aa5156a..f8fa5c3 100644 --- a/lib/ruby_warning_filter.rb +++ b/lib/ruby_warning_filter.rb @@ -29,6 +29,10 @@ class RubyWarningFilter < DelegateClass(IO) # TODO: Report this. IGNORED_TEMPLATE_WARNING = %r{\.slim:\d+: warning: possibly useless use of a variable in void context$} + # The source of this warning cannot be located so we have to ignore it completely + # See example: https://github.com/deivid-rodriguez/pry-byebug/issues/221 + IGNORED_EVAL_WARNING = %r{^
:1: warning: .+ in eval may not return location in binding; use Binding#source_location instead$} + def initialize(io, ignore_path: Gem.path) super(io) @@ -52,7 +56,9 @@ def write(line) @ignored = false nil elsif RUBY_WARNING.match?(line) - @ignored = IGNORED_TEMPLATE_WARNING.match?(line) || @ignore_regexp.match?(line) + @ignored = IGNORED_TEMPLATE_WARNING.match?(line) || + IGNORED_EVAL_WARNING.match?(line) || + @ignore_regexp.match?(line) unless @ignored @ruby_warnings += 1 super diff --git a/test/ruby_warnings_filter_test.rb b/test/ruby_warnings_filter_test.rb index 5624a4c..2d5c932 100644 --- a/test/ruby_warnings_filter_test.rb +++ b/test/ruby_warnings_filter_test.rb @@ -92,4 +92,11 @@ def test_template_warning @err.string assert_equal 1, @err.ruby_warnings end + + def test_eval_warning + @err.write "
:1: warning: __FILE__ in eval may not return location in binding; use Binding#source_location instead\n" + @err.write "
:1: warning: __LINE__ in eval may not return location in binding; use Binding#source_location instead\n" + assert_equal "", @err.string + assert_equal 0, @err.ruby_warnings + end end From 05f27a1c49f204bd8d792a74e0c57565cfdf1b95 Mon Sep 17 00:00:00 2001 From: Simon Perepelitsa Date: Tue, 2 Apr 2019 21:58:25 +0300 Subject: [PATCH 09/10] Handle
warning without a line number --- lib/ruby_warning_filter.rb | 4 ++-- test/ruby_warnings_filter_test.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ruby_warning_filter.rb b/lib/ruby_warning_filter.rb index f8fa5c3..385adf5 100644 --- a/lib/ruby_warning_filter.rb +++ b/lib/ruby_warning_filter.rb @@ -22,7 +22,7 @@ class RubyWarningFilter < DelegateClass(IO) attr_reader :ruby_warnings BACKTRACE = "\tfrom" - RUBY_WARNING = %r{:(\d+|in `\S+'): warning:} + RUBY_WARNING = %r{(^
|:\d+|:in `\S+'): warning:} EVAL_REDEFINED = /\(eval\):\d+: warning: previous definition of .+ was here/ # Variables used in tag attributes (Slim) always cause a warning. @@ -31,7 +31,7 @@ class RubyWarningFilter < DelegateClass(IO) # The source of this warning cannot be located so we have to ignore it completely # See example: https://github.com/deivid-rodriguez/pry-byebug/issues/221 - IGNORED_EVAL_WARNING = %r{^
:1: warning: .+ in eval may not return location in binding; use Binding#source_location instead$} + IGNORED_EVAL_WARNING = %r{^
(:\d+)?: warning: .+ in eval may not return location in binding; use Binding#source_location instead$} def initialize(io, ignore_path: Gem.path) super(io) diff --git a/test/ruby_warnings_filter_test.rb b/test/ruby_warnings_filter_test.rb index 2d5c932..e39576a 100644 --- a/test/ruby_warnings_filter_test.rb +++ b/test/ruby_warnings_filter_test.rb @@ -95,7 +95,7 @@ def test_template_warning def test_eval_warning @err.write "
:1: warning: __FILE__ in eval may not return location in binding; use Binding#source_location instead\n" - @err.write "
:1: warning: __LINE__ in eval may not return location in binding; use Binding#source_location instead\n" + @err.write "
: warning: __LINE__ in eval may not return location in binding; use Binding#source_location instead\n" assert_equal "", @err.string assert_equal 0, @err.ruby_warnings end From 33b89d04b885345a7ea14eea6b1859ac401b8397 Mon Sep 17 00:00:00 2001 From: Simon Perepelitsa Date: Mon, 17 Jun 2019 17:35:00 +0100 Subject: [PATCH 10/10] Ignore warnings from C-extensions --- lib/ruby_warning_filter.rb | 2 +- test/ruby_warnings_filter_test.rb | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/ruby_warning_filter.rb b/lib/ruby_warning_filter.rb index 385adf5..b69954f 100644 --- a/lib/ruby_warning_filter.rb +++ b/lib/ruby_warning_filter.rb @@ -22,7 +22,7 @@ class RubyWarningFilter < DelegateClass(IO) attr_reader :ruby_warnings BACKTRACE = "\tfrom" - RUBY_WARNING = %r{(^
|:\d+|:in `\S+'): warning:} + RUBY_WARNING = %r{(^
|\.bundle|:\d+|:in `\S+'): warning:} EVAL_REDEFINED = /\(eval\):\d+: warning: previous definition of .+ was here/ # Variables used in tag attributes (Slim) always cause a warning. diff --git a/test/ruby_warnings_filter_test.rb b/test/ruby_warnings_filter_test.rb index e39576a..71fbb0b 100644 --- a/test/ruby_warnings_filter_test.rb +++ b/test/ruby_warnings_filter_test.rb @@ -28,6 +28,7 @@ def test_ruby_warning @err.write "#{@gems_dir}/unicode_utils-1.4.0/lib/unicode_utils/sid.rb:11: warning: shadowing outer local variable - al\n" @err.write "/path/to/ruby/2.2.0/gems/unicode_utils-1.4.0/lib/unicode_utils/sid.rb:11: warning: shadowing outer local variable - al\n" + @err.write "/path/to/ruby/2.2.0/gems/fast_blank-1.0.0/lib/fast_blank.bundle: warning: method redefined; discarding old blank?" # This warning actually writes newline separately. @err.write "/path/to/ruby/2.2.0/gems/dragonfly-1.0.6/lib/dragonfly/utils.rb:41:in `uri_unescape': warning: URI.unescape is obsolete"