debride 1.14.0 → 1.15.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
- checksums.yaml.gz.sig +0 -0
- data/History.rdoc +15 -0
- data/Rakefile +2 -2
- data/bin/debride +1 -1
- data/lib/debride.rb +34 -18
- data/test/test_debride.rb +78 -2
- data.tar.gz.sig +0 -0
- metadata +9 -9
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 77baff9dbc4bab278d0e6b6fe16772ecdce26b00c4c7b24469e0680f0d608c41
|
|
4
|
+
data.tar.gz: 885b6274f63f3d76c6a106543d28be50f177fcc6fa6adad7cf642c0b3ef7f0d8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 421c0cb4b4aa45ed2e7897254549def50af4f4491a029676bcc7671aa026e8cda45b9774073eef8d3bffa15665f7df0466e1b6a68f236fc0b0c2ee12806461a5
|
|
7
|
+
data.tar.gz: 2cc4e04095596764513090fffe356835d3af36c192395dbe7753470801e623f826bf72c54371de30bf1d9006d4cf109809cffc1419e887607914623cc8a1bb82
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/History.rdoc
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
=== 1.15.0 / 2026-01-02
|
|
2
|
+
|
|
3
|
+
* 1 minor enhancement:
|
|
4
|
+
|
|
5
|
+
* Added process_hash to handle hash shortcut syntax in case it is a call. (TSMMark)
|
|
6
|
+
|
|
7
|
+
* 6 bug fixes:
|
|
8
|
+
|
|
9
|
+
* Bump prism dependency to 1.7+.
|
|
10
|
+
* Load debride with require_relative in bin/debride.
|
|
11
|
+
* Minor fixes for prism 1.7 and ruby 4.0.
|
|
12
|
+
* Oops! Fixed --legacy option definition.
|
|
13
|
+
* Properly handle scope/alias_method with interoplation. (alagos)
|
|
14
|
+
* Removed prism patches now that they've been upstreamed.
|
|
15
|
+
|
|
1
16
|
=== 1.14.0 / 2025-12-11
|
|
2
17
|
|
|
3
18
|
* 2 minor enhancements:
|
data/Rakefile
CHANGED
|
@@ -11,7 +11,7 @@ Hoe::add_include_dirs("../../sexp_processor/dev/lib",
|
|
|
11
11
|
"../../path_expander/dev/lib",
|
|
12
12
|
"lib")
|
|
13
13
|
|
|
14
|
-
Hoe.plugin :
|
|
14
|
+
Hoe.plugin :isolate_binaries
|
|
15
15
|
Hoe.plugin :seattlerb
|
|
16
16
|
Hoe.plugin :rdoc
|
|
17
17
|
Hoe.plugin :cov
|
|
@@ -21,7 +21,7 @@ Hoe.spec "debride" do
|
|
|
21
21
|
license "MIT"
|
|
22
22
|
|
|
23
23
|
dependency "sexp_processor", "~> 4.17"
|
|
24
|
-
dependency "prism", "~> 1.
|
|
24
|
+
dependency "prism", "~> 1.7"
|
|
25
25
|
dependency "path_expander", "~> 2.0"
|
|
26
26
|
end
|
|
27
27
|
|
data/bin/debride
CHANGED
data/lib/debride.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require "optparse"
|
|
4
4
|
require "set"
|
|
5
5
|
require "stringio"
|
|
6
|
+
require "timeout"
|
|
6
7
|
|
|
7
8
|
require "sexp_processor"
|
|
8
9
|
require "path_expander"
|
|
@@ -10,13 +11,6 @@ require "path_expander"
|
|
|
10
11
|
require "prism"
|
|
11
12
|
require "prism/translation/ruby_parser"
|
|
12
13
|
|
|
13
|
-
unless Prism::Translation::RubyParser.method_defined? :process then
|
|
14
|
-
class Prism::Translation::RubyParser # compatibility layer
|
|
15
|
-
def process(ruby, file, timeout=nil) =
|
|
16
|
-
Timeout.timeout(timeout) { parse ruby, file }
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
14
|
class NotRubyParser < Prism::Translation::RubyParser # compatibility layer
|
|
21
15
|
end
|
|
22
16
|
|
|
@@ -24,7 +18,7 @@ end
|
|
|
24
18
|
# A static code analyzer that points out possible dead methods.
|
|
25
19
|
|
|
26
20
|
class Debride < MethodBasedSexpProcessor
|
|
27
|
-
VERSION = "1.
|
|
21
|
+
VERSION = "1.15.0" # :nodoc:
|
|
28
22
|
PROJECT = "debride"
|
|
29
23
|
|
|
30
24
|
def self.load_plugins proj = PROJECT
|
|
@@ -108,8 +102,8 @@ class Debride < MethodBasedSexpProcessor
|
|
|
108
102
|
end
|
|
109
103
|
|
|
110
104
|
parser = option[:parser].new
|
|
111
|
-
parser.process
|
|
112
|
-
rescue
|
|
105
|
+
parser.process file, path, option[:timeout]
|
|
106
|
+
rescue RubyParser::SyntaxError, RegexpError => e
|
|
113
107
|
warn "Parse Error parsing #{path}. Skipping."
|
|
114
108
|
warn " #{e.message}"
|
|
115
109
|
rescue Timeout::Error
|
|
@@ -172,7 +166,7 @@ class Debride < MethodBasedSexpProcessor
|
|
|
172
166
|
options[:minimum] = n
|
|
173
167
|
end
|
|
174
168
|
|
|
175
|
-
opts.on "--legacy" "Use RubyParser for parsing." do
|
|
169
|
+
opts.on "--legacy", "Use RubyParser for parsing." do
|
|
176
170
|
require "ruby_parser"
|
|
177
171
|
option[:parser] = RubyParser
|
|
178
172
|
end
|
|
@@ -349,27 +343,30 @@ class Debride < MethodBasedSexpProcessor
|
|
|
349
343
|
end
|
|
350
344
|
when *RAILS_MACRO_METHODS
|
|
351
345
|
# s(:call, nil, :has_one, s(:lit, :has_one_relation), ...)
|
|
352
|
-
_, _, _,
|
|
346
|
+
_, _, _, name, * = sexp
|
|
353
347
|
|
|
354
348
|
# try to detect route scope vs model scope
|
|
355
349
|
if context.include? :module or context.include? :class then
|
|
356
|
-
|
|
357
|
-
|
|
350
|
+
if string_like? name then
|
|
351
|
+
file, line = sexp.file, sexp.line
|
|
352
|
+
record_method name.last, file, line
|
|
353
|
+
end
|
|
358
354
|
end
|
|
359
355
|
when /_path$/ then
|
|
360
356
|
method_name = method_name.to_s.delete_suffix("_path").to_sym if option[:rails]
|
|
361
357
|
when /^deliver_/ then
|
|
362
358
|
method_name = method_name.to_s.delete_prefix("deliver_").to_sym if option[:rails]
|
|
363
359
|
when :alias_method then
|
|
360
|
+
# s(:call, nil, :alias_method, lhs, rhs)
|
|
364
361
|
_, _, _, lhs, rhs = sexp
|
|
365
362
|
|
|
366
|
-
if
|
|
367
|
-
lhs = lhs.last
|
|
368
|
-
rhs = rhs.last
|
|
363
|
+
if string_like? lhs and string_like? rhs then
|
|
364
|
+
lhs = lhs.last.to_sym
|
|
365
|
+
rhs = rhs.last.to_sym
|
|
369
366
|
|
|
370
367
|
record_method lhs, sexp.file, sexp.line
|
|
371
368
|
|
|
372
|
-
called << rhs
|
|
369
|
+
called << rhs # TODO: why?
|
|
373
370
|
end
|
|
374
371
|
end
|
|
375
372
|
|
|
@@ -380,6 +377,10 @@ class Debride < MethodBasedSexpProcessor
|
|
|
380
377
|
sexp
|
|
381
378
|
end
|
|
382
379
|
|
|
380
|
+
def string_like? s
|
|
381
|
+
Sexp === s and %i[lit str].include?(s.sexp_type)
|
|
382
|
+
end
|
|
383
|
+
|
|
383
384
|
def process_alias exp
|
|
384
385
|
_, (_, lhs), (_, rhs) = exp
|
|
385
386
|
|
|
@@ -482,6 +483,21 @@ class Debride < MethodBasedSexpProcessor
|
|
|
482
483
|
|
|
483
484
|
alias process_safe_call process_call
|
|
484
485
|
|
|
486
|
+
def process_hash sexp
|
|
487
|
+
_, *pairs = sexp
|
|
488
|
+
|
|
489
|
+
pairs.each_slice 2 do |k, v|
|
|
490
|
+
if v.nil? && k.sexp_type == :lit then
|
|
491
|
+
called << k.last
|
|
492
|
+
else
|
|
493
|
+
process k
|
|
494
|
+
process v
|
|
495
|
+
end
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
sexp
|
|
499
|
+
end
|
|
500
|
+
|
|
485
501
|
##
|
|
486
502
|
# Calculate the difference between known methods and called methods.
|
|
487
503
|
|
data/test/test_debride.rb
CHANGED
|
@@ -20,6 +20,7 @@ class TestDebride < Minitest::Test
|
|
|
20
20
|
:process_const,
|
|
21
21
|
:process_defn,
|
|
22
22
|
:process_defs,
|
|
23
|
+
:process_hash,
|
|
23
24
|
:process_op_asgn2,
|
|
24
25
|
:process_rb,
|
|
25
26
|
:process_safe_call,
|
|
@@ -46,13 +47,15 @@ class TestDebride < Minitest::Test
|
|
|
46
47
|
assert_equal exp_arg, arg
|
|
47
48
|
end
|
|
48
49
|
|
|
49
|
-
def assert_process exp, ruby, opts
|
|
50
|
+
def assert_process exp, ruby, called:nil, **opts
|
|
50
51
|
io = StringIO.new ruby
|
|
51
52
|
|
|
52
53
|
debride = Debride.new opts
|
|
53
54
|
debride.process debride.process_rb io
|
|
54
55
|
|
|
55
56
|
assert_equal exp, debride.missing
|
|
57
|
+
assert_equal Set[*called], debride.called if called
|
|
58
|
+
|
|
56
59
|
debride
|
|
57
60
|
end
|
|
58
61
|
|
|
@@ -240,6 +243,40 @@ class TestDebride < Minitest::Test
|
|
|
240
243
|
assert_process [], s
|
|
241
244
|
end
|
|
242
245
|
|
|
246
|
+
def test_call__alias_method__symbol
|
|
247
|
+
ruby = <<~'RUBY'
|
|
248
|
+
class QuarterPounder
|
|
249
|
+
alias_method :get_x, :x
|
|
250
|
+
end
|
|
251
|
+
RUBY
|
|
252
|
+
|
|
253
|
+
exp = [["QuarterPounder", [:get_x]]]
|
|
254
|
+
|
|
255
|
+
assert_process exp, ruby, called:%i[x alias_method]
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def test_call__alias_method__string
|
|
259
|
+
ruby = <<~'RUBY'
|
|
260
|
+
class QuarterPounder
|
|
261
|
+
alias_method "get_x", "x"
|
|
262
|
+
end
|
|
263
|
+
RUBY
|
|
264
|
+
|
|
265
|
+
exp = [["QuarterPounder", [:get_x]]]
|
|
266
|
+
|
|
267
|
+
assert_process exp, ruby, called:%i[x alias_method]
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def test_call__alias_method__interpolated
|
|
271
|
+
ruby = <<~'RUBY'
|
|
272
|
+
class QuarterPounder
|
|
273
|
+
alias_method "get_#{integr}", integr
|
|
274
|
+
end
|
|
275
|
+
RUBY
|
|
276
|
+
|
|
277
|
+
assert_process [], ruby, called:%i[integr alias_method]
|
|
278
|
+
end
|
|
279
|
+
|
|
243
280
|
def test_alias_method_chain
|
|
244
281
|
ruby = <<-RUBY.strip
|
|
245
282
|
class QuarterPounder
|
|
@@ -352,6 +389,42 @@ class TestDebride < Minitest::Test
|
|
|
352
389
|
assert_process [], ruby
|
|
353
390
|
end
|
|
354
391
|
|
|
392
|
+
def test_hash__shorthand
|
|
393
|
+
ruby = <<-RUBY.strip
|
|
394
|
+
class Seattle
|
|
395
|
+
def self.status
|
|
396
|
+
{ raining: }
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
def self.raining
|
|
400
|
+
true
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
Seattle.status
|
|
405
|
+
RUBY
|
|
406
|
+
|
|
407
|
+
assert_process [], ruby
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
def test_hash__not_shorthand
|
|
411
|
+
ruby = <<-RUBY.strip
|
|
412
|
+
class Seattle
|
|
413
|
+
def self.status
|
|
414
|
+
{ missing: }
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
def self.raining
|
|
418
|
+
true
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
Seattle.status
|
|
423
|
+
RUBY
|
|
424
|
+
|
|
425
|
+
assert_process [["Seattle", [:raining]]], ruby
|
|
426
|
+
end
|
|
427
|
+
|
|
355
428
|
def test_safe_navigation_operator
|
|
356
429
|
ruby = <<-RUBY.strip
|
|
357
430
|
class Seattle
|
|
@@ -412,7 +485,7 @@ class TestDebride < Minitest::Test
|
|
|
412
485
|
end
|
|
413
486
|
|
|
414
487
|
def test_rails_dsl_macro_definitions
|
|
415
|
-
ruby =
|
|
488
|
+
ruby = <<~'RUBY'
|
|
416
489
|
class RailsModel
|
|
417
490
|
has_one :has_one_relation
|
|
418
491
|
has_one :uncalled_has_one_relation
|
|
@@ -424,6 +497,9 @@ class TestDebride < Minitest::Test
|
|
|
424
497
|
has_and_belongs_to_many :uncalled_has_and_belongs_to_many_relation
|
|
425
498
|
scope :scope_method
|
|
426
499
|
scope :uncalled_scope_method
|
|
500
|
+
scope :"interpolated_#{method}"
|
|
501
|
+
scope "another_#{method}"
|
|
502
|
+
scope "yet_another_#{method}".to_sym
|
|
427
503
|
|
|
428
504
|
def instance_method_caller
|
|
429
505
|
has_one_relation
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: debride
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.15.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ryan Davis
|
|
@@ -50,14 +50,14 @@ dependencies:
|
|
|
50
50
|
requirements:
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '1.
|
|
53
|
+
version: '1.7'
|
|
54
54
|
type: :runtime
|
|
55
55
|
prerelease: false
|
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
|
57
57
|
requirements:
|
|
58
58
|
- - "~>"
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
|
-
version: '1.
|
|
60
|
+
version: '1.7'
|
|
61
61
|
- !ruby/object:Gem::Dependency
|
|
62
62
|
name: path_expander
|
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -78,20 +78,20 @@ dependencies:
|
|
|
78
78
|
requirements:
|
|
79
79
|
- - ">="
|
|
80
80
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: '
|
|
81
|
+
version: '6.0'
|
|
82
82
|
- - "<"
|
|
83
83
|
- !ruby/object:Gem::Version
|
|
84
|
-
version: '
|
|
84
|
+
version: '8'
|
|
85
85
|
type: :development
|
|
86
86
|
prerelease: false
|
|
87
87
|
version_requirements: !ruby/object:Gem::Requirement
|
|
88
88
|
requirements:
|
|
89
89
|
- - ">="
|
|
90
90
|
- !ruby/object:Gem::Version
|
|
91
|
-
version: '
|
|
91
|
+
version: '6.0'
|
|
92
92
|
- - "<"
|
|
93
93
|
- !ruby/object:Gem::Version
|
|
94
|
-
version: '
|
|
94
|
+
version: '8'
|
|
95
95
|
- !ruby/object:Gem::Dependency
|
|
96
96
|
name: simplecov
|
|
97
97
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -112,14 +112,14 @@ dependencies:
|
|
|
112
112
|
requirements:
|
|
113
113
|
- - "~>"
|
|
114
114
|
- !ruby/object:Gem::Version
|
|
115
|
-
version: '4.
|
|
115
|
+
version: '4.5'
|
|
116
116
|
type: :development
|
|
117
117
|
prerelease: false
|
|
118
118
|
version_requirements: !ruby/object:Gem::Requirement
|
|
119
119
|
requirements:
|
|
120
120
|
- - "~>"
|
|
121
121
|
- !ruby/object:Gem::Version
|
|
122
|
-
version: '4.
|
|
122
|
+
version: '4.5'
|
|
123
123
|
description: Analyze code for potentially uncalled / dead methods, now with auto-removal.
|
|
124
124
|
email:
|
|
125
125
|
- ryand-ruby@zenspider.com
|
metadata.gz.sig
CHANGED
|
Binary file
|