warning 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|