warning 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +8 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +28 -1
- data/lib/warning.rb +98 -14
- data/test/fixtures/mismatched_indentations.rb +4 -0
- data/test/test_warning.rb +98 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 719af8cdb41da57d07edb0fa0eac81d2bb017d5d816cadf98e600cc75e63f4aa
|
4
|
+
data.tar.gz: 169550daf070386f36072d01c9c36303c631b6f598cf358e0f16e786f1d4ac68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ddf24399c73e0b2b747189d02972c3616482ac90c3c9e89b16b8594a1e2c6cf005b3b81bab905de6f30d3fd1882d806c8746fd317f59e6915408f80f054ee8f
|
7
|
+
data.tar.gz: a5f1d714b59737dd6e67ab000687783acff87c3fe5cfd85bac2828c91556a7de5637d082e82d0a34198b53580a324c69639da93e07c0436e4f648e0031c7ff00
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
=== 1.1.0 (2020-06-12)
|
2
|
+
|
3
|
+
* Allow Warning.process to be called with a hash of actions instead of a block (jeremyevans)
|
4
|
+
|
5
|
+
* Handle Warning.process blocks that return :default, :backtrace, or :raise specially (jeremyevans)
|
6
|
+
|
7
|
+
* Add support for :mismatched_indentations as regexp argument to Warning.ignore (qortex) (#7)
|
8
|
+
|
1
9
|
=== 1.0.0 (2020-01-21)
|
2
10
|
|
3
11
|
* Add support for :taint as regexp argument to Warning.ignore (jeremyevans)
|
data/MIT-LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
ruby-warning adds custom processing for warnings, including the
|
4
4
|
ability to ignore specific warning messages, ignore warnings
|
5
|
-
in specific files/directories,
|
5
|
+
in specific files/directories, include backtraces with warnings,
|
6
|
+
treat warnings as errors, deduplicate warnings, and add
|
6
7
|
custom handling for all warnings in specific files/directories.
|
7
8
|
|
8
9
|
ruby-warning requires ruby 2.4+, as previous versions of ruby do
|
@@ -32,6 +33,7 @@ appropriate regexp. The supported symbols are:
|
|
32
33
|
* :fixnum
|
33
34
|
* :keyword_separation
|
34
35
|
* :method_redefined
|
36
|
+
* :mismatched_indentations
|
35
37
|
* :missing_gvar
|
36
38
|
* :missing_ivar
|
37
39
|
* :not_reached
|
@@ -47,6 +49,14 @@ string instead of performing the default behavior. You can call
|
|
47
49
|
<tt>Warning.process</tt> multiple times and it will operate intelligently,
|
48
50
|
choosing the longest path prefix that the string starts with.
|
49
51
|
|
52
|
+
<tt>Warning.process</tt> blocks can return +:default+ to use the default
|
53
|
+
behavior, +:backtrace+ to use the default behavior and also print the backtrace
|
54
|
+
or +:raise+ to raise the warning string as a RuntimeError.
|
55
|
+
|
56
|
+
<tt>Warning.process</tt> can also accept a hash of actions instead of a block,
|
57
|
+
with keys being regexps (or symbols supported by <tt>Warning.ignore</tt>) and
|
58
|
+
values being callable objects (or +:default+, +:backtrace+, or +:raise+).
|
59
|
+
|
50
60
|
<tt>Warning.dedup</tt> deduplicates warnings, so that if a warning is received
|
51
61
|
that is the same as a warning that has already been processed, the warning is
|
52
62
|
ignored. Note that this should be used with care, since if the application
|
@@ -93,6 +103,23 @@ loading any code that could cause warnings.
|
|
93
103
|
LOGGER.error(warning)
|
94
104
|
end
|
95
105
|
|
106
|
+
# Write warnings in the current file to $stderr, but include backtrace
|
107
|
+
Warning.process(__FILE__) do |warning|
|
108
|
+
:backtrace
|
109
|
+
end
|
110
|
+
|
111
|
+
# Raise warnings in the current file as RuntimeErrors, with the warning
|
112
|
+
# string as the exception message
|
113
|
+
Warning.process(__FILE__) do |warning|
|
114
|
+
:raise
|
115
|
+
end
|
116
|
+
|
117
|
+
# Raise keyword argument separation warnings in the current file as
|
118
|
+
# RuntimeErrors, and write ambiguous slash warnings to $stderr, including
|
119
|
+
# the backtrace
|
120
|
+
Warning.process(__FILE__, keyword_separation: :raise,
|
121
|
+
ambiguous_slash: :backtrace)
|
122
|
+
|
96
123
|
# Deduplicate warnings
|
97
124
|
Warning.dedup
|
98
125
|
|
data/lib/warning.rb
CHANGED
@@ -18,8 +18,17 @@ module Warning
|
|
18
18
|
keyword_separation: /: warning: (?:Using the last argument (?:for `.+' )?as keyword parameters is deprecated; maybe \*\* should be added to the call|Passing the keyword argument (?:for `.+' )?as the last hash parameter is deprecated|Splitting the last argument (?:for `.+' )?into positional and keyword parameters is deprecated|The called method (?:`.+' )?is defined here)\n\z/,
|
19
19
|
safe: /: warning: (?:rb_safe_level_2_warning|rb_safe_level|rb_set_safe_level_force|rb_set_safe_level|rb_secure|rb_insecure_operation|rb_check_safe_obj|\$SAFE) will (?:be removed|become a normal global variable) in Ruby 3\.0\n\z/,
|
20
20
|
taint: /: warning: (?:rb_error_untrusted|rb_check_trusted|Pathname#taint|Pathname#untaint|rb_env_path_tainted|Object#tainted\?|Object#taint|Object#untaint|Object#untrusted\?|Object#untrust|Object#trust|rb_obj_infect|rb_tainted_str_new|rb_tainted_str_new_cstr) is deprecated and will be removed in Ruby 3\.2\.\n\z/,
|
21
|
+
mismatched_indentations: /: warning: mismatched indentations at '.+' with '.+' at \d+\n\z/,
|
21
22
|
}
|
22
23
|
|
24
|
+
# Map of action symbols to procs that return the symbol
|
25
|
+
ACTION_PROC_MAP = {
|
26
|
+
default: proc{|_| :default},
|
27
|
+
backtrace: proc{|_| :backtrace},
|
28
|
+
raise: proc{|_| :raise},
|
29
|
+
}
|
30
|
+
private_constant :ACTION_PROC_MAP
|
31
|
+
|
23
32
|
# Clear all current ignored warnings, warning processors, and duplicate check cache.
|
24
33
|
# Also disables deduplicating warnings if that is currently enabled.
|
25
34
|
def clear
|
@@ -81,14 +90,7 @@ module Warning
|
|
81
90
|
# # Ignore all uninitialized instance variable and method redefined warnings in current file
|
82
91
|
# Warning.ignore([:missing_ivar, :method_redefined], __FILE__)
|
83
92
|
def ignore(regexp, path='')
|
84
|
-
|
85
|
-
when Regexp
|
86
|
-
# already regexp
|
87
|
-
when Symbol
|
88
|
-
regexp = IGNORE_MAP.fetch(regexp)
|
89
|
-
when Array
|
90
|
-
regexp = Regexp.union(regexp.map{|re| IGNORE_MAP.fetch(re)})
|
91
|
-
else
|
93
|
+
unless regexp = convert_regexp(regexp)
|
92
94
|
raise TypeError, "first argument to Warning.ignore should be Regexp, Symbol, or Array of Symbols, got #{regexp.inspect}"
|
93
95
|
end
|
94
96
|
|
@@ -110,7 +112,52 @@ module Warning
|
|
110
112
|
# Warning.process(__FILE__) do |warning|
|
111
113
|
# LOGGER.error(warning)
|
112
114
|
# end
|
113
|
-
|
115
|
+
#
|
116
|
+
# The block can return one of the following symbols:
|
117
|
+
#
|
118
|
+
# :default :: Take the default action (call super, printing to $stderr).
|
119
|
+
# :backtrace :: Take the default action (call super, printing to $stderr),
|
120
|
+
# and also print the backtrace.
|
121
|
+
# :raise :: Raise a RuntimeError with the warning as the message.
|
122
|
+
#
|
123
|
+
# If the block returns anything else, it is assumed the block completely handled
|
124
|
+
# the warning and takes no other action.
|
125
|
+
#
|
126
|
+
# Instead of passing a block, you can pass a hash of actions to take for specific
|
127
|
+
# warnings, using regexp as keys and a callable objects as values:
|
128
|
+
#
|
129
|
+
# Warning.ignore(__FILE__,
|
130
|
+
# /instance variable @\w+ not initialized/ => proc do |warning|
|
131
|
+
# LOGGER.warning(warning)
|
132
|
+
# end,
|
133
|
+
# /global variable `\$\w+' not initialized/ => proc do |warning|
|
134
|
+
# LOGGER.error(warning)
|
135
|
+
# end
|
136
|
+
# )
|
137
|
+
#
|
138
|
+
# Instead of passing a regexp as a key, you can pass a symbol that is recognized
|
139
|
+
# by Warning.ignore. Instead of passing a callable object as a value, you can
|
140
|
+
# pass a symbol, which will be treated as a callable object that returns that symbol:
|
141
|
+
#
|
142
|
+
# Warning.process(__FILE__, :missing_ivar=>:backtrace, :keyword_separation=>:raise)
|
143
|
+
def process(path='', actions=nil, &block)
|
144
|
+
if block
|
145
|
+
if actions
|
146
|
+
raise ArgumentError, "cannot pass both actions and block to Warning.process"
|
147
|
+
end
|
148
|
+
elsif actions
|
149
|
+
block = {}
|
150
|
+
actions.each do |regexp, value|
|
151
|
+
unless regexp = convert_regexp(regexp)
|
152
|
+
raise TypeError, "action provided to Warning.process should be Regexp, Symbol, or Array of Symbols, got #{regexp.inspect}"
|
153
|
+
end
|
154
|
+
|
155
|
+
block[regexp] = ACTION_PROC_MAP[value] || value
|
156
|
+
end
|
157
|
+
else
|
158
|
+
raise ArgumentError, "must pass either actions or block to Warning.process"
|
159
|
+
end
|
160
|
+
|
114
161
|
synchronize do
|
115
162
|
@process << [path, block]
|
116
163
|
@process.sort_by!(&:first)
|
@@ -138,18 +185,55 @@ module Warning
|
|
138
185
|
synchronize{@dedup[str] = true}
|
139
186
|
end
|
140
187
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
188
|
+
action = catch(:action) do
|
189
|
+
synchronize{@process.dup}.each do |path, block|
|
190
|
+
if str.start_with?(path)
|
191
|
+
if block.is_a?(Hash)
|
192
|
+
block.each do |regexp, blk|
|
193
|
+
if str =~ regexp
|
194
|
+
throw :action, blk.call(str)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
else
|
198
|
+
throw :action, block.call(str)
|
199
|
+
end
|
200
|
+
end
|
145
201
|
end
|
202
|
+
|
203
|
+
:default
|
146
204
|
end
|
147
205
|
|
148
|
-
|
206
|
+
case action
|
207
|
+
when :default
|
208
|
+
super
|
209
|
+
when :backtrace
|
210
|
+
super
|
211
|
+
$stderr.puts caller
|
212
|
+
when :raise
|
213
|
+
raise str
|
214
|
+
else
|
215
|
+
# nothing
|
216
|
+
end
|
217
|
+
|
218
|
+
nil
|
149
219
|
end
|
150
220
|
|
151
221
|
private
|
152
222
|
|
223
|
+
# Convert the given Regexp, Symbol, or Array of Symbols into a Regexp.
|
224
|
+
def convert_regexp(regexp)
|
225
|
+
case regexp
|
226
|
+
when Regexp
|
227
|
+
regexp
|
228
|
+
when Symbol
|
229
|
+
IGNORE_MAP.fetch(regexp)
|
230
|
+
when Array
|
231
|
+
Regexp.union(regexp.map{|re| IGNORE_MAP.fetch(re)})
|
232
|
+
else
|
233
|
+
# nothing
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
153
237
|
def synchronize(&block)
|
154
238
|
@monitor.synchronize(&block)
|
155
239
|
end
|
data/test/test_warning.rb
CHANGED
@@ -6,8 +6,12 @@ require 'pathname'
|
|
6
6
|
class WarningTest < Minitest::Test
|
7
7
|
module EnvUtil
|
8
8
|
def verbose_warning
|
9
|
+
stderr = ""
|
9
10
|
class << (stderr = "")
|
10
11
|
alias write <<
|
12
|
+
def puts(*a)
|
13
|
+
self << a.join("\n")
|
14
|
+
end
|
11
15
|
end
|
12
16
|
stderr, $stderr, verbose, $VERBOSE = $stderr, stderr, $VERBOSE, true
|
13
17
|
yield stderr
|
@@ -351,6 +355,18 @@ class WarningTest < Minitest::Test
|
|
351
355
|
end
|
352
356
|
end
|
353
357
|
|
358
|
+
def test_warning_ignore_mismatched_indentation
|
359
|
+
assert_warning(/warning: mismatched indentations/) do
|
360
|
+
load 'test/fixtures/mismatched_indentations.rb'
|
361
|
+
end
|
362
|
+
|
363
|
+
Warning.ignore(:mismatched_indentations, 'test/fixtures/mismatched_indentations.rb')
|
364
|
+
|
365
|
+
assert_warning '' do
|
366
|
+
load 'test/fixtures/mismatched_indentations.rb'
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
354
370
|
def test_warning_process
|
355
371
|
obj = Object.new
|
356
372
|
warn = nil
|
@@ -414,4 +430,86 @@ class WarningTest < Minitest::Test
|
|
414
430
|
assert_equal(4, warn.first)
|
415
431
|
assert_match(/instance variable @ivar6 not initialized/, warn.last)
|
416
432
|
end
|
433
|
+
|
434
|
+
def test_warning_process_block_return_default
|
435
|
+
w = nil
|
436
|
+
Warning.process(__FILE__) do |warning|
|
437
|
+
w = warning
|
438
|
+
:default
|
439
|
+
end
|
440
|
+
|
441
|
+
assert_warning(/instance variable @ivar not initialized/) do
|
442
|
+
ivar
|
443
|
+
end
|
444
|
+
assert_match(/instance variable @ivar not initialized/, w)
|
445
|
+
end
|
446
|
+
|
447
|
+
def test_warning_process_block_return_backtrace
|
448
|
+
w = nil
|
449
|
+
Warning.process(__FILE__) do |warning|
|
450
|
+
w = warning
|
451
|
+
:backtrace
|
452
|
+
end
|
453
|
+
|
454
|
+
assert_warning(/instance variable @ivar not initialized.*#{__FILE__}/m) do
|
455
|
+
ivar
|
456
|
+
end
|
457
|
+
assert_match(/instance variable @ivar not initialized/, w)
|
458
|
+
end
|
459
|
+
|
460
|
+
def test_warning_process_block_return_raise
|
461
|
+
w = nil
|
462
|
+
Warning.process(__FILE__) do |warning|
|
463
|
+
w = warning
|
464
|
+
:raise
|
465
|
+
end
|
466
|
+
|
467
|
+
assert_raises(RuntimeError, /instance variable @ivar not initialized/) do
|
468
|
+
EnvUtil.verbose_warning{ivar}
|
469
|
+
end
|
470
|
+
assert_match(/instance variable @ivar not initialized/, w)
|
471
|
+
end
|
472
|
+
|
473
|
+
def test_warning_process_action
|
474
|
+
w = nil
|
475
|
+
Warning.process(__FILE__, :missing_ivar=>:default, :missing_gvar=>:backtrace, :ambiguous_slash=>:raise)
|
476
|
+
Warning.process(__FILE__, :not_reached=>proc do |warning|
|
477
|
+
w = warning
|
478
|
+
:raise
|
479
|
+
end)
|
480
|
+
|
481
|
+
assert_warning(/instance variable @ivar not initialized/) do
|
482
|
+
ivar
|
483
|
+
end
|
484
|
+
|
485
|
+
assert_warning(/global variable `\$gvar' not initialized.*#{__FILE__}/m) do
|
486
|
+
$gvar
|
487
|
+
end
|
488
|
+
|
489
|
+
Warning.process(__FILE__) do |warning|
|
490
|
+
w = warning
|
491
|
+
:raise
|
492
|
+
end
|
493
|
+
|
494
|
+
assert_raises(RuntimeError, /warning: ambiguous first argument; put parentheses or a space even after `\/' operator/) do
|
495
|
+
EnvUtil.verbose_warning{instance_eval('d /a/', __FILE__)}
|
496
|
+
end
|
497
|
+
|
498
|
+
assert_raises(RuntimeError, /warning: statement not reached/) do
|
499
|
+
EnvUtil.verbose_warning{instance_eval('def self.b; return; 1 end', __FILE__)}
|
500
|
+
end
|
501
|
+
assert_match(/warning: statement not reached/, w)
|
502
|
+
end
|
503
|
+
|
504
|
+
def test_warning_process_action_and_block
|
505
|
+
assert_raises(ArgumentError) do
|
506
|
+
Warning.process(__FILE__)
|
507
|
+
end
|
508
|
+
end
|
509
|
+
|
510
|
+
def test_warning_process_no_action_and_no_block
|
511
|
+
assert_raises(ArgumentError) do
|
512
|
+
Warning.process(__FILE__, :missing_ivar=>:default){}
|
513
|
+
end
|
514
|
+
end
|
417
515
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: warning
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Evans
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest-global_expectations
|
@@ -27,8 +27,9 @@ dependencies:
|
|
27
27
|
description: |
|
28
28
|
ruby-warning adds custom processing for warnings, including the
|
29
29
|
ability to ignore specific warning messages, ignore warnings
|
30
|
-
in specific files/directories,
|
31
|
-
warnings
|
30
|
+
in specific files/directories, include backtraces with warnings,
|
31
|
+
treat warnings as errors, deduplicate warnings, and add
|
32
|
+
custom handling for all warnings in specific files/directories.
|
32
33
|
email: code@jeremyevans.net
|
33
34
|
executables: []
|
34
35
|
extensions: []
|
@@ -42,6 +43,7 @@ files:
|
|
42
43
|
- README.rdoc
|
43
44
|
- Rakefile
|
44
45
|
- lib/warning.rb
|
46
|
+
- test/fixtures/mismatched_indentations.rb
|
45
47
|
- test/test_freeze_warning.rb
|
46
48
|
- test/test_warning.rb
|
47
49
|
homepage: https://github.com/jeremyevans/ruby-warning
|