ruby_warning_filter 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/Manifest.txt +7 -0
- data/Rakefile +11 -0
- data/Readme.md +29 -0
- data/lib/ruby_warning_filter.rb +82 -0
- data/ruby_warning_filter.gemspec +13 -0
- data/test/ruby_warnings_filter_test.rb +87 -0
- metadata +51 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 821c2df551dbf8fdcd0ba9889fbe8716606626d4
|
4
|
+
data.tar.gz: 2b06bcb3f1d649eef059437075db368da6678e7d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 695653150630dc7307f548f6c031e8fbc898ff24c918788b928628e8e99bcf9a39ce0243abbe8baaf2cc1bb2f57c77c8b2d208e3c583ffc4c55a7f96ab4645e7
|
7
|
+
data.tar.gz: 6df030eafa9370d022744a44e50537ca5e4814aea2568306f498812936a4cee935ddcea5759114ff350befbc3e4bcfc711c68e6eaa98f4686ba8a5155a49fb04
|
data/Gemfile
ADDED
data/Manifest.txt
ADDED
data/Rakefile
ADDED
data/Readme.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Hassle-free Ruby warnings
|
2
|
+
|
3
|
+
Ruby warnings are cool. They prevent you from making typos in instance variables, making unused variables, accidentally overriding methods, and more. Unfortunately, many libraries still don’t check their code for warnings. In a big enough project you end up with tons of warnings from all the libraries you use which renders the whole thing useless. But it doesn’t have to be this way!
|
4
|
+
|
5
|
+
With the help of this gem you can filter out all those useless messages and only get the warnings relevant to your code.
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
Add to your Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem "ruby_warning_filter", "~> 1.0.0"
|
13
|
+
```
|
14
|
+
|
15
|
+
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".
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
$VERBOSE = true
|
19
|
+
require "ruby_warning_filter"
|
20
|
+
$stderr = RubyWarningFilter.new($stderr)
|
21
|
+
```
|
22
|
+
|
23
|
+
When running your app or tests you should see only relevant warnings. Now, go fix them!
|
24
|
+
|
25
|
+
## Feedback
|
26
|
+
|
27
|
+
[![Build Status](https://travis-ci.org/semaperepelitsa/ruby_warning_filter.svg?branch=master)](https://travis-ci.org/semaperepelitsa/ruby_warning_filter)
|
28
|
+
|
29
|
+
The filter works by proxying all writes to stderr. It has been running for a while in many of my work projects with good results. However, it is probably not comprehensive. Please, report any warnings that it misses or swallows by error.
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
# Filter IO from Ruby warnings that come out of external gems.
|
4
|
+
# There is no other way currently to filter out Ruby warnings other than hijacking stderr.
|
5
|
+
#
|
6
|
+
# $VERBOSE = true
|
7
|
+
# require "ruby_warning_filter"
|
8
|
+
# $stderr = RubyWarningFilter.new($stderr)
|
9
|
+
#
|
10
|
+
# Number of occurred non-filtered warnings can be read with ruby_warnings:
|
11
|
+
#
|
12
|
+
# $stderr.ruby_warnings #=> 0
|
13
|
+
# @foo # warning: instance variable @foo not initialized
|
14
|
+
# $stderr.ruby_warnings #=> 1
|
15
|
+
#
|
16
|
+
# The filter only overrides "write" method. This is OK since Ruby uses "write" internally
|
17
|
+
# when emitting warnings. Helper methods such as "puts", "print", "printf" will do native "write"
|
18
|
+
# bypassing the filter.
|
19
|
+
#
|
20
|
+
class RubyWarningFilter < DelegateClass(IO)
|
21
|
+
attr_reader :ruby_warnings
|
22
|
+
|
23
|
+
def initialize(io, ignore_path: Gem.path)
|
24
|
+
super(io)
|
25
|
+
@ruby_warnings = 0
|
26
|
+
@ignored = false
|
27
|
+
@ignore_path = ignore_path
|
28
|
+
end
|
29
|
+
|
30
|
+
def write(line)
|
31
|
+
if @ignored && (backtrace?(line) || line == "\n")
|
32
|
+
# Ignore the whole backtrace after ignored warning.
|
33
|
+
# Some warnings write newline separately for some reason.
|
34
|
+
@ignored = true
|
35
|
+
nil
|
36
|
+
elsif @ignored && eval_redefined?(line)
|
37
|
+
# 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.
|
38
|
+
@ignored = false
|
39
|
+
nil
|
40
|
+
elsif ruby_warning?(line)
|
41
|
+
@ignored = ignored_warning?(line)
|
42
|
+
unless @ignored
|
43
|
+
@ruby_warnings += 1
|
44
|
+
super
|
45
|
+
end
|
46
|
+
else
|
47
|
+
super
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def ruby_warning?(line)
|
54
|
+
line =~ %r{:(\d+|in `\S+'): warning:}
|
55
|
+
end
|
56
|
+
|
57
|
+
def ignored_warning?(line)
|
58
|
+
external_warning?(line) || ignored_template_warning?(line)
|
59
|
+
end
|
60
|
+
|
61
|
+
def external_warning?(line)
|
62
|
+
@ignore_path.any?{ |path| line.start_with?(path) }
|
63
|
+
end
|
64
|
+
|
65
|
+
# Variables used in tag attributes (Slim) always cause a warning.
|
66
|
+
# TODO: Report this.
|
67
|
+
def ignored_template_warning?(line)
|
68
|
+
line =~ %r{\.slim:\d+: warning: possibly useless use of a variable in void context$}
|
69
|
+
end
|
70
|
+
|
71
|
+
def backtrace?(line)
|
72
|
+
line.start_with?("\tfrom")
|
73
|
+
end
|
74
|
+
|
75
|
+
def whitespace?(line)
|
76
|
+
line =~ /^\s*$/
|
77
|
+
end
|
78
|
+
|
79
|
+
def eval_redefined?(line)
|
80
|
+
line =~ /\(eval\):\d+: warning: previous definition of .+ was here/
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Gem::Specification.new do |gem|
|
2
|
+
gem.name = "ruby_warning_filter"
|
3
|
+
gem.version = "1.0.0"
|
4
|
+
gem.summary = "Hassle-free Ruby warnings"
|
5
|
+
gem.license = "MIT"
|
6
|
+
gem.author = "Semyon Perepelitsa"
|
7
|
+
gem.email = "sema@sema.in"
|
8
|
+
|
9
|
+
gem.homepage = "https://github.com/semaperepelitsa/ruby_warning_filter"
|
10
|
+
|
11
|
+
gem.files = File.read("Manifest.txt").split("\n")
|
12
|
+
gem.test_files = gem.files.grep(%r{^test/})
|
13
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require_relative "../lib/ruby_warning_filter"
|
3
|
+
gem "minitest", "~> 5.0"
|
4
|
+
require "minitest/autorun"
|
5
|
+
require "stringio"
|
6
|
+
STDOUT.sync = true
|
7
|
+
|
8
|
+
class RubyWarningsFilterTest < MiniTest::Test
|
9
|
+
def setup
|
10
|
+
@err = RubyWarningFilter.new(StringIO.new, ignore_path: ["/path/to/ruby/2.2.0/gems"])
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_no_effect
|
14
|
+
assert_equal 0, @err.ruby_warnings
|
15
|
+
@err.puts "hello"
|
16
|
+
assert_equal "hello\n", @err.string
|
17
|
+
assert_equal 0, @err.ruby_warnings
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_ruby_warning
|
21
|
+
@err.write "/path/to/script/middleware_test.rb:58: warning: assigned but unused variable - status\n"
|
22
|
+
assert_equal "/path/to/script/middleware_test.rb:58: warning: assigned but unused variable - status\n",
|
23
|
+
@err.string
|
24
|
+
assert_equal 1, @err.ruby_warnings
|
25
|
+
|
26
|
+
@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"
|
27
|
+
|
28
|
+
# This warning actually writes newline separately.
|
29
|
+
@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"
|
30
|
+
@err.write "\n"
|
31
|
+
|
32
|
+
assert_equal "/path/to/script/middleware_test.rb:58: warning: assigned but unused variable - status\n",
|
33
|
+
@err.string
|
34
|
+
assert_equal 1, @err.ruby_warnings
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_backtrace
|
38
|
+
# in gem
|
39
|
+
@err.write "/path/to/ruby/2.2.0/gems/sass-3.4.12/lib/sass/util/normalized_map.rb:2: warning: loading in progress...\n"
|
40
|
+
@err.write "\tfrom /path/to/app/bin/rails:4:in `<main>'\n"
|
41
|
+
|
42
|
+
# in app
|
43
|
+
@err.write "/path/to/app/script:1: warning: loading in progress...\n"
|
44
|
+
@err.write "\tfrom /path/to/app/bin/rails:4:in `<main>'\n"
|
45
|
+
|
46
|
+
@err.write "something other\n"
|
47
|
+
|
48
|
+
assert_equal \
|
49
|
+
"/path/to/app/script:1: warning: loading in progress...\n"\
|
50
|
+
"\tfrom /path/to/app/bin/rails:4:in `<main>'\n"\
|
51
|
+
"something other\n",
|
52
|
+
@err.string
|
53
|
+
|
54
|
+
assert_equal 1, @err.ruby_warnings
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_method_redefined_eval
|
58
|
+
# in gem
|
59
|
+
@err.write "/path/to/ruby/2.2.0/gems/compass-core-1.0.3/lib/gradient_support.rb:319: warning: method redefined; discarding old to_moz\n"
|
60
|
+
@err.write "(eval):2: warning: previous definition of to_moz was here\n"
|
61
|
+
|
62
|
+
# in app
|
63
|
+
@err.write "/path/to/app.rb:123: warning: method redefined; discarding old foo\n"
|
64
|
+
@err.write "(eval):2: warning: previous definition of foo was here\n"
|
65
|
+
|
66
|
+
@err.write "something other\n"
|
67
|
+
|
68
|
+
assert_equal \
|
69
|
+
"/path/to/app.rb:123: warning: method redefined; discarding old foo\n"\
|
70
|
+
"(eval):2: warning: previous definition of foo was here\n"\
|
71
|
+
"something other\n",
|
72
|
+
@err.string
|
73
|
+
|
74
|
+
assert_equal 2, @err.ruby_warnings
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_template_warning
|
78
|
+
@err.write "/path/to/app/template.html.slim:2: warning: possibly useless use of a variable in void context\n"
|
79
|
+
assert_equal "", @err.string
|
80
|
+
assert_equal 0, @err.ruby_warnings
|
81
|
+
|
82
|
+
@err.write "/path/to/app/template.html.slim:2: warning: assigned but unused variable - foo\n"
|
83
|
+
assert_equal "/path/to/app/template.html.slim:2: warning: assigned but unused variable - foo\n",
|
84
|
+
@err.string
|
85
|
+
assert_equal 1, @err.ruby_warnings
|
86
|
+
end
|
87
|
+
end
|
metadata
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby_warning_filter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Semyon Perepelitsa
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-05-04 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email: sema@sema.in
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- Gemfile
|
20
|
+
- Manifest.txt
|
21
|
+
- Rakefile
|
22
|
+
- Readme.md
|
23
|
+
- lib/ruby_warning_filter.rb
|
24
|
+
- ruby_warning_filter.gemspec
|
25
|
+
- test/ruby_warnings_filter_test.rb
|
26
|
+
homepage: https://github.com/semaperepelitsa/ruby_warning_filter
|
27
|
+
licenses:
|
28
|
+
- MIT
|
29
|
+
metadata: {}
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubyforge_project:
|
46
|
+
rubygems_version: 2.4.5
|
47
|
+
signing_key:
|
48
|
+
specification_version: 4
|
49
|
+
summary: Hassle-free Ruby warnings
|
50
|
+
test_files:
|
51
|
+
- test/ruby_warnings_filter_test.rb
|