debride 1.13.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 +22 -0
- data/Rakefile +3 -3
- data/bin/debride +1 -1
- data/lib/debride.rb +50 -15
- data/test/test_debride.rb +82 -3
- data.tar.gz.sig +0 -0
- metadata +13 -13
- 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,25 @@
|
|
|
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
|
+
|
|
16
|
+
=== 1.14.0 / 2025-12-11
|
|
17
|
+
|
|
18
|
+
* 2 minor enhancements:
|
|
19
|
+
|
|
20
|
+
* Bumped path_expander to 2.0.0.
|
|
21
|
+
* Switched to prism for ruby parsing. Use --legacy for RubyParser.
|
|
22
|
+
|
|
1
23
|
=== 1.13.0 / 2025-06-10
|
|
2
24
|
|
|
3
25
|
* 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,8 +21,8 @@ Hoe.spec "debride" do
|
|
|
21
21
|
license "MIT"
|
|
22
22
|
|
|
23
23
|
dependency "sexp_processor", "~> 4.17"
|
|
24
|
-
dependency "
|
|
25
|
-
dependency "path_expander", "~>
|
|
24
|
+
dependency "prism", "~> 1.7"
|
|
25
|
+
dependency "path_expander", "~> 2.0"
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def run dir, whitelist
|
data/bin/debride
CHANGED
data/lib/debride.rb
CHANGED
|
@@ -3,16 +3,22 @@
|
|
|
3
3
|
require "optparse"
|
|
4
4
|
require "set"
|
|
5
5
|
require "stringio"
|
|
6
|
+
require "timeout"
|
|
6
7
|
|
|
7
|
-
require "ruby_parser"
|
|
8
8
|
require "sexp_processor"
|
|
9
9
|
require "path_expander"
|
|
10
10
|
|
|
11
|
+
require "prism"
|
|
12
|
+
require "prism/translation/ruby_parser"
|
|
13
|
+
|
|
14
|
+
class NotRubyParser < Prism::Translation::RubyParser # compatibility layer
|
|
15
|
+
end
|
|
16
|
+
|
|
11
17
|
##
|
|
12
18
|
# A static code analyzer that points out possible dead methods.
|
|
13
19
|
|
|
14
20
|
class Debride < MethodBasedSexpProcessor
|
|
15
|
-
VERSION = "1.
|
|
21
|
+
VERSION = "1.15.0" # :nodoc:
|
|
16
22
|
PROJECT = "debride"
|
|
17
23
|
|
|
18
24
|
def self.load_plugins proj = PROJECT
|
|
@@ -47,14 +53,12 @@ class Debride < MethodBasedSexpProcessor
|
|
|
47
53
|
# Top level runner for bin/debride.
|
|
48
54
|
|
|
49
55
|
def self.run args
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
debride = Debride.new opt
|
|
56
|
+
debride = Debride.new parse_options args
|
|
53
57
|
|
|
54
58
|
extensions = self.file_extensions
|
|
55
59
|
glob = "**/*.{#{extensions.join(",")}}"
|
|
56
60
|
expander = PathExpander.new(args, glob)
|
|
57
|
-
files = expander.process
|
|
61
|
+
files = expander.process.to_a
|
|
58
62
|
excl = debride.option[:exclude]
|
|
59
63
|
excl.map! { |fd| File.directory?(fd) ? "#{fd}/**/*" : fd } if excl
|
|
60
64
|
|
|
@@ -97,8 +101,9 @@ class Debride < MethodBasedSexpProcessor
|
|
|
97
101
|
raise "Unhandled type: #{path_or_io.class}:#{path_or_io.inspect}"
|
|
98
102
|
end
|
|
99
103
|
|
|
100
|
-
|
|
101
|
-
|
|
104
|
+
parser = option[:parser].new
|
|
105
|
+
parser.process file, path, option[:timeout]
|
|
106
|
+
rescue RubyParser::SyntaxError, RegexpError => e
|
|
102
107
|
warn "Parse Error parsing #{path}. Skipping."
|
|
103
108
|
warn " #{e.message}"
|
|
104
109
|
rescue Timeout::Error
|
|
@@ -161,6 +166,11 @@ class Debride < MethodBasedSexpProcessor
|
|
|
161
166
|
options[:minimum] = n
|
|
162
167
|
end
|
|
163
168
|
|
|
169
|
+
opts.on "--legacy", "Use RubyParser for parsing." do
|
|
170
|
+
require "ruby_parser"
|
|
171
|
+
option[:parser] = RubyParser
|
|
172
|
+
end
|
|
173
|
+
|
|
164
174
|
opts.on("-v", "--verbose", "Verbose. Show progress processing files.") do
|
|
165
175
|
options[:verbose] = true
|
|
166
176
|
end
|
|
@@ -208,6 +218,9 @@ class Debride < MethodBasedSexpProcessor
|
|
|
208
218
|
self.option = { :whitelist => [] }.merge options
|
|
209
219
|
self.known = Hash.new { |h,k| h[k] = Set.new }
|
|
210
220
|
self.called = Set.new
|
|
221
|
+
|
|
222
|
+
option[:parser] ||= NotRubyParser
|
|
223
|
+
|
|
211
224
|
super()
|
|
212
225
|
end
|
|
213
226
|
|
|
@@ -330,27 +343,30 @@ class Debride < MethodBasedSexpProcessor
|
|
|
330
343
|
end
|
|
331
344
|
when *RAILS_MACRO_METHODS
|
|
332
345
|
# s(:call, nil, :has_one, s(:lit, :has_one_relation), ...)
|
|
333
|
-
_, _, _,
|
|
346
|
+
_, _, _, name, * = sexp
|
|
334
347
|
|
|
335
348
|
# try to detect route scope vs model scope
|
|
336
349
|
if context.include? :module or context.include? :class then
|
|
337
|
-
|
|
338
|
-
|
|
350
|
+
if string_like? name then
|
|
351
|
+
file, line = sexp.file, sexp.line
|
|
352
|
+
record_method name.last, file, line
|
|
353
|
+
end
|
|
339
354
|
end
|
|
340
355
|
when /_path$/ then
|
|
341
356
|
method_name = method_name.to_s.delete_suffix("_path").to_sym if option[:rails]
|
|
342
357
|
when /^deliver_/ then
|
|
343
358
|
method_name = method_name.to_s.delete_prefix("deliver_").to_sym if option[:rails]
|
|
344
359
|
when :alias_method then
|
|
360
|
+
# s(:call, nil, :alias_method, lhs, rhs)
|
|
345
361
|
_, _, _, lhs, rhs = sexp
|
|
346
362
|
|
|
347
|
-
if
|
|
348
|
-
lhs = lhs.last
|
|
349
|
-
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
|
|
350
366
|
|
|
351
367
|
record_method lhs, sexp.file, sexp.line
|
|
352
368
|
|
|
353
|
-
called << rhs
|
|
369
|
+
called << rhs # TODO: why?
|
|
354
370
|
end
|
|
355
371
|
end
|
|
356
372
|
|
|
@@ -361,6 +377,10 @@ class Debride < MethodBasedSexpProcessor
|
|
|
361
377
|
sexp
|
|
362
378
|
end
|
|
363
379
|
|
|
380
|
+
def string_like? s
|
|
381
|
+
Sexp === s and %i[lit str].include?(s.sexp_type)
|
|
382
|
+
end
|
|
383
|
+
|
|
364
384
|
def process_alias exp
|
|
365
385
|
_, (_, lhs), (_, rhs) = exp
|
|
366
386
|
|
|
@@ -463,6 +483,21 @@ class Debride < MethodBasedSexpProcessor
|
|
|
463
483
|
|
|
464
484
|
alias process_safe_call process_call
|
|
465
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
|
+
|
|
466
501
|
##
|
|
467
502
|
# Calculate the difference between known methods and called methods.
|
|
468
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
|
|
@@ -342,13 +379,52 @@ class TestDebride < Minitest::Test
|
|
|
342
379
|
end
|
|
343
380
|
|
|
344
381
|
def test_block_pass_empty
|
|
382
|
+
ruby = <<~RUBY
|
|
383
|
+
def g(&)
|
|
384
|
+
f(&) # block forwarding
|
|
385
|
+
end
|
|
386
|
+
g
|
|
387
|
+
RUBY
|
|
388
|
+
|
|
389
|
+
assert_process [], ruby
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
def test_hash__shorthand
|
|
345
393
|
ruby = <<-RUBY.strip
|
|
346
|
-
|
|
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
|
|
347
405
|
RUBY
|
|
348
406
|
|
|
349
407
|
assert_process [], ruby
|
|
350
408
|
end
|
|
351
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
|
+
|
|
352
428
|
def test_safe_navigation_operator
|
|
353
429
|
ruby = <<-RUBY.strip
|
|
354
430
|
class Seattle
|
|
@@ -409,7 +485,7 @@ class TestDebride < Minitest::Test
|
|
|
409
485
|
end
|
|
410
486
|
|
|
411
487
|
def test_rails_dsl_macro_definitions
|
|
412
|
-
ruby =
|
|
488
|
+
ruby = <<~'RUBY'
|
|
413
489
|
class RailsModel
|
|
414
490
|
has_one :has_one_relation
|
|
415
491
|
has_one :uncalled_has_one_relation
|
|
@@ -421,6 +497,9 @@ class TestDebride < Minitest::Test
|
|
|
421
497
|
has_and_belongs_to_many :uncalled_has_and_belongs_to_many_relation
|
|
422
498
|
scope :scope_method
|
|
423
499
|
scope :uncalled_scope_method
|
|
500
|
+
scope :"interpolated_#{method}"
|
|
501
|
+
scope "another_#{method}"
|
|
502
|
+
scope "yet_another_#{method}".to_sym
|
|
424
503
|
|
|
425
504
|
def instance_method_caller
|
|
426
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
|
|
@@ -45,53 +45,53 @@ dependencies:
|
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
46
|
version: '4.17'
|
|
47
47
|
- !ruby/object:Gem::Dependency
|
|
48
|
-
name:
|
|
48
|
+
name: prism
|
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '
|
|
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: '
|
|
60
|
+
version: '1.7'
|
|
61
61
|
- !ruby/object:Gem::Dependency
|
|
62
62
|
name: path_expander
|
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
|
64
64
|
requirements:
|
|
65
65
|
- - "~>"
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: '
|
|
67
|
+
version: '2.0'
|
|
68
68
|
type: :runtime
|
|
69
69
|
prerelease: false
|
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
|
71
71
|
requirements:
|
|
72
72
|
- - "~>"
|
|
73
73
|
- !ruby/object:Gem::Version
|
|
74
|
-
version: '
|
|
74
|
+
version: '2.0'
|
|
75
75
|
- !ruby/object:Gem::Dependency
|
|
76
76
|
name: rdoc
|
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
|
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
|
|
@@ -164,7 +164,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
164
164
|
- !ruby/object:Gem::Version
|
|
165
165
|
version: '0'
|
|
166
166
|
requirements: []
|
|
167
|
-
rubygems_version: 3.
|
|
167
|
+
rubygems_version: 3.7.2
|
|
168
168
|
specification_version: 4
|
|
169
169
|
summary: Analyze code for potentially uncalled / dead methods, now with auto-removal.
|
|
170
170
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|