debride 1.8.2 → 1.9.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 +12 -0
- data/Rakefile +4 -3
- data/lib/debride.rb +91 -48
- data/test/test_debride.rb +77 -16
- data.tar.gz.sig +0 -0
- metadata +18 -17
- 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: 1c2b2a4fb03bd2f6f8a5406f0b413e3159b49ac6a9b0c3641bedc7a6e724a548
|
4
|
+
data.tar.gz: cdeb2dc596fe5e496ed940a989fe84f482480c2a2cc7436228e1c4b07755ccbf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a11b67c7d6a82313be67dbb1680c54ab9f9db3e0f769ab2ce96980ebfb696cc5dd607d6107cb0cc00c9a5c966553439deea89fa0acd13be83707e6393b52070b
|
7
|
+
data.tar.gz: f2f4eb04d9c348109b88fcca245233554bae0febe496ead9c08622653add4a2cdd10bb4405b7bff9cc308972d5cc46f46241aa56162976d2f89cf03c4ba9e2d4
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/History.rdoc
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
=== 1.9.0 / 2022-05-23
|
2
|
+
|
3
|
+
* 3 minor enhancements:
|
4
|
+
|
5
|
+
* Added --json and --yaml output options.
|
6
|
+
* Added io argument to #report, added tests for #report.
|
7
|
+
* Improved processing of --exclude with directories (adds trailing slash).
|
8
|
+
|
9
|
+
* 1 bug fix:
|
10
|
+
|
11
|
+
* Fixed exception thrown in #report when using --focus. (cbillen)
|
12
|
+
|
1
13
|
=== 1.8.2 / 2019-09-24
|
2
14
|
|
3
15
|
* 1 bug fix:
|
data/Rakefile
CHANGED
@@ -26,15 +26,16 @@ end
|
|
26
26
|
def run dir, whitelist
|
27
27
|
abort "Specify dir to scan with D=<path>" unless dir
|
28
28
|
|
29
|
-
ENV["GEM_HOME"] = "tmp/isolate
|
30
|
-
ENV["GEM_PATH"] = "../../debride-erb/dev/tmp/isolate
|
29
|
+
ENV["GEM_HOME"] = "tmp/isolate"
|
30
|
+
ENV["GEM_PATH"] = "../../debride-erb/dev/tmp/isolate"
|
31
31
|
|
32
32
|
whitelist = whitelist && ["--whitelist", whitelist]
|
33
33
|
verbose = ENV["V"] && "-v"
|
34
|
+
exclude = ENV["E"] && ["--exclude", ENV["E"]]
|
34
35
|
|
35
36
|
require "debride"
|
36
37
|
|
37
|
-
args = ["--rails", verbose, whitelist, dir].flatten.compact
|
38
|
+
args = ["--rails", verbose, whitelist, exclude, dir].flatten.compact
|
38
39
|
|
39
40
|
Debride.run(args).report
|
40
41
|
end
|
data/lib/debride.rb
CHANGED
@@ -8,21 +8,11 @@ require "ruby_parser"
|
|
8
8
|
require "sexp_processor"
|
9
9
|
require "path_expander"
|
10
10
|
|
11
|
-
# :stopdoc:
|
12
|
-
class File
|
13
|
-
RUBY19 = "<3".respond_to? :encoding unless defined? RUBY19 # :nodoc:
|
14
|
-
|
15
|
-
class << self
|
16
|
-
alias :binread :read unless RUBY19
|
17
|
-
end
|
18
|
-
end
|
19
|
-
# :startdoc:
|
20
|
-
|
21
11
|
##
|
22
12
|
# A static code analyzer that points out possible dead methods.
|
23
13
|
|
24
14
|
class Debride < MethodBasedSexpProcessor
|
25
|
-
VERSION = "1.
|
15
|
+
VERSION = "1.9.0" # :nodoc:
|
26
16
|
PROJECT = "debride"
|
27
17
|
|
28
18
|
def self.load_plugins proj = PROJECT
|
@@ -66,6 +56,8 @@ class Debride < MethodBasedSexpProcessor
|
|
66
56
|
expander = PathExpander.new(args, glob)
|
67
57
|
files = expander.process
|
68
58
|
excl = debride.option[:exclude]
|
59
|
+
excl.map! { |fd| File.directory?(fd) ? "#{fd}/" : fd } if excl
|
60
|
+
|
69
61
|
files = expander.filter_files files, StringIO.new(excl.join "\n") if excl
|
70
62
|
|
71
63
|
debride.run(files)
|
@@ -94,33 +86,34 @@ class Debride < MethodBasedSexpProcessor
|
|
94
86
|
end
|
95
87
|
|
96
88
|
def process_rb path_or_io
|
97
|
-
|
98
|
-
warn "Processing ruby: #{path_or_io}" if option[:verbose]
|
99
|
-
|
100
|
-
case path_or_io
|
101
|
-
when String then
|
102
|
-
path, file = path_or_io, File.binread(path_or_io)
|
103
|
-
when IO, StringIO then
|
104
|
-
path, file = "(io)", path_or_io.read
|
105
|
-
else
|
106
|
-
raise "Unhandled type: #{path_or_io.class}:#{path_or_io.inspect}"
|
107
|
-
end
|
89
|
+
warn "Processing ruby: #{path_or_io}" if option[:verbose]
|
108
90
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
91
|
+
case path_or_io
|
92
|
+
when String then
|
93
|
+
path, file = path_or_io, File.binread(path_or_io)
|
94
|
+
when IO, StringIO then
|
95
|
+
path, file = "(io)", path_or_io.read
|
96
|
+
else
|
97
|
+
raise "Unhandled type: #{path_or_io.class}:#{path_or_io.inspect}"
|
116
98
|
end
|
99
|
+
|
100
|
+
rp = RubyParser.for_current_ruby rescue RubyParser.new
|
101
|
+
rp.process(file, path, option[:timeout])
|
102
|
+
rescue Racc::ParseError, RegexpError => e
|
103
|
+
warn "Parse Error parsing #{path}. Skipping."
|
104
|
+
warn " #{e.message}"
|
105
|
+
rescue Timeout::Error
|
106
|
+
warn "TIMEOUT parsing #{path}. Skipping."
|
117
107
|
end
|
118
108
|
|
119
109
|
##
|
120
110
|
# Parse command line options and return a hash of parsed option values.
|
121
111
|
|
122
112
|
def self.parse_options args
|
123
|
-
options = {
|
113
|
+
options = {
|
114
|
+
:whitelist => [],
|
115
|
+
:format => :text,
|
116
|
+
}
|
124
117
|
|
125
118
|
op = OptionParser.new do |opts|
|
126
119
|
opts.banner = "debride [options] files_or_dirs"
|
@@ -160,6 +153,14 @@ class Debride < MethodBasedSexpProcessor
|
|
160
153
|
opts.on("-v", "--verbose", "Verbose. Show progress processing files.") do
|
161
154
|
options[:verbose] = true
|
162
155
|
end
|
156
|
+
|
157
|
+
opts.on "--json" do
|
158
|
+
options[:format] = :json
|
159
|
+
end
|
160
|
+
|
161
|
+
opts.on "--yaml" do
|
162
|
+
options[:format] = :yaml
|
163
|
+
end
|
163
164
|
end
|
164
165
|
|
165
166
|
op.parse! args
|
@@ -397,37 +398,79 @@ class Debride < MethodBasedSexpProcessor
|
|
397
398
|
by_class.sort_by { |k,v| k }
|
398
399
|
end
|
399
400
|
|
401
|
+
def missing_locations
|
402
|
+
focus = option[:focus]
|
403
|
+
|
404
|
+
missing.map { |klass, meths|
|
405
|
+
bad = meths.map { |meth|
|
406
|
+
location =
|
407
|
+
method_locations["#{klass}##{meth}"] ||
|
408
|
+
method_locations["#{klass}::#{meth}"]
|
409
|
+
|
410
|
+
if focus then
|
411
|
+
path = location[/(.+):\d+/, 1]
|
412
|
+
|
413
|
+
next unless File.fnmatch(focus, path)
|
414
|
+
end
|
415
|
+
|
416
|
+
[meth, location]
|
417
|
+
}.compact
|
418
|
+
|
419
|
+
[klass, bad]
|
420
|
+
}
|
421
|
+
.to_h
|
422
|
+
.reject { |k,v| v.empty? }
|
423
|
+
end
|
424
|
+
|
400
425
|
##
|
401
426
|
# Print out a report of suspects.
|
402
427
|
|
403
|
-
def report
|
428
|
+
def report io = $stdout
|
404
429
|
focus = option[:focus]
|
430
|
+
type = option[:format] || :text
|
405
431
|
|
432
|
+
send "report_#{type}", io, focus, missing_locations
|
433
|
+
end
|
434
|
+
|
435
|
+
def report_text io, focus, missing
|
406
436
|
if focus then
|
407
|
-
puts "Focusing on #{focus}"
|
408
|
-
puts
|
437
|
+
io.puts "Focusing on #{focus}"
|
438
|
+
io.puts
|
409
439
|
end
|
410
440
|
|
411
|
-
puts "These methods MIGHT not be called:"
|
441
|
+
io.puts "These methods MIGHT not be called:"
|
412
442
|
|
413
443
|
missing.each do |klass, meths|
|
414
|
-
bad = meths.map { |meth|
|
415
|
-
location =
|
416
|
-
method_locations["#{klass}##{meth}"] ||
|
417
|
-
method_locations["#{klass}::#{meth}"]
|
418
|
-
path = location[/(.+):\d+$/, 1]
|
444
|
+
bad = meths.map { |(meth, location)| " %-35s %s" % [meth, location] }
|
419
445
|
|
420
|
-
|
446
|
+
io.puts
|
447
|
+
io.puts klass
|
448
|
+
io.puts bad.join "\n"
|
449
|
+
end
|
450
|
+
end
|
421
451
|
|
422
|
-
|
423
|
-
|
424
|
-
bad.compact!
|
425
|
-
next if bad.empty?
|
452
|
+
def report_json io, focus, missing
|
453
|
+
require "json"
|
426
454
|
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
455
|
+
data = {
|
456
|
+
:missing => missing
|
457
|
+
}
|
458
|
+
|
459
|
+
data[:focus] = focus if focus
|
460
|
+
|
461
|
+
JSON.dump data, io
|
462
|
+
end
|
463
|
+
|
464
|
+
def report_yaml io, focus, missing
|
465
|
+
require "yaml"
|
466
|
+
|
467
|
+
data = {
|
468
|
+
:missing => missing
|
469
|
+
}
|
470
|
+
|
471
|
+
data[:focus] = focus if focus
|
472
|
+
|
473
|
+
YAML.dump data, io
|
431
474
|
end
|
432
475
|
|
433
476
|
##
|
data/test/test_debride.rb
CHANGED
@@ -8,10 +8,31 @@ class SafeDebride < Debride
|
|
8
8
|
end
|
9
9
|
|
10
10
|
class TestDebride < Minitest::Test
|
11
|
+
EXP_LIST = [["Debride",
|
12
|
+
[:process_attrasgn,
|
13
|
+
:process_call,
|
14
|
+
:process_cdecl,
|
15
|
+
:process_colon2,
|
16
|
+
:process_colon3,
|
17
|
+
:process_const,
|
18
|
+
:process_defn,
|
19
|
+
:process_defs,
|
20
|
+
:process_rb,
|
21
|
+
:report,
|
22
|
+
:report_json,
|
23
|
+
:report_text,
|
24
|
+
:report_yaml]]]
|
25
|
+
|
26
|
+
formatted_vals = EXP_LIST.map { |k,vs|
|
27
|
+
[k, vs.map { |v| [v, "lib/debride.rb:###"] } ]
|
28
|
+
}.to_h
|
29
|
+
|
30
|
+
EXP_FORMATTED = { :missing => formatted_vals }
|
31
|
+
|
11
32
|
def assert_option arg, exp_arg, exp_opt
|
12
33
|
opt = SafeDebride.parse_options arg
|
13
34
|
|
14
|
-
exp_opt = {:whitelist => []}.merge exp_opt
|
35
|
+
exp_opt = {:whitelist => [], :format => :text}.merge exp_opt
|
15
36
|
assert_equal exp_opt, opt
|
16
37
|
assert_equal exp_arg, arg
|
17
38
|
end
|
@@ -27,20 +48,13 @@ class TestDebride < Minitest::Test
|
|
27
48
|
end
|
28
49
|
|
29
50
|
def test_sanity
|
30
|
-
skip "This is slow" unless ENV["SLOW"]
|
31
|
-
|
32
51
|
debride = nil
|
33
52
|
|
34
53
|
assert_silent do
|
35
54
|
debride = Debride.run %w[lib]
|
36
55
|
end
|
37
56
|
|
38
|
-
|
39
|
-
[:process_attrasgn, :process_call, :process_cdecl, :process_colon2,
|
40
|
-
:process_colon3, :process_const, :process_defn, :process_defs,
|
41
|
-
:process_rb, :report]]]
|
42
|
-
|
43
|
-
assert_equal exp, debride.missing
|
57
|
+
assert_equal EXP_LIST, debride.missing
|
44
58
|
end
|
45
59
|
|
46
60
|
def test_parse_options
|
@@ -85,16 +99,63 @@ class TestDebride < Minitest::Test
|
|
85
99
|
end
|
86
100
|
|
87
101
|
def test_exclude_files
|
88
|
-
|
102
|
+
debride = Debride.run %w[--exclude test/ lib test]
|
89
103
|
|
90
|
-
|
104
|
+
assert_equal EXP_LIST, debride.missing
|
105
|
+
end
|
91
106
|
|
92
|
-
|
93
|
-
|
94
|
-
:process_colon3, :process_const, :process_defn, :process_defs,
|
95
|
-
:process_rb, :report]]]
|
107
|
+
def test_exclude_files__multiple
|
108
|
+
debride = Debride.run %w[--exclude test,lib lib test]
|
96
109
|
|
97
|
-
|
110
|
+
assert_empty debride.missing
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_exclude_files__dir_without_slash
|
114
|
+
debride = Debride.run %w[--exclude test lib test]
|
115
|
+
|
116
|
+
assert_equal EXP_LIST, debride.missing
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_focus
|
120
|
+
debride = Debride.run %w[--focus lib/debride.rb lib test]
|
121
|
+
io = StringIO.new
|
122
|
+
|
123
|
+
debride.report(io)
|
124
|
+
|
125
|
+
assert_includes io.string, "Focusing on lib/debride.rb"
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_format__plain
|
129
|
+
debride = Debride.run %w[lib]
|
130
|
+
io = StringIO.new
|
131
|
+
|
132
|
+
debride.report(io)
|
133
|
+
|
134
|
+
assert_match %r%process_attrasgn\s+lib/debride.rb:\d+-\d+%, io.string
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_format__json
|
138
|
+
debride = Debride.run %w[lib --json]
|
139
|
+
io = StringIO.new
|
140
|
+
|
141
|
+
debride.report(io)
|
142
|
+
|
143
|
+
exp = JSON.load JSON.dump EXP_FORMATTED # force stringify
|
144
|
+
data = JSON.load io.string.gsub(/\d+-\d+/, "###")
|
145
|
+
|
146
|
+
assert_equal exp, data
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_format__yaml
|
150
|
+
debride = Debride.run %w[lib --yaml]
|
151
|
+
io = StringIO.new
|
152
|
+
|
153
|
+
debride.report(io)
|
154
|
+
|
155
|
+
exp = EXP_FORMATTED
|
156
|
+
data = YAML.load io.string.gsub(/\d+-\d+/, "###")
|
157
|
+
|
158
|
+
assert_equal exp, data
|
98
159
|
end
|
99
160
|
|
100
161
|
def test_whitelist
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: debride
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Davis
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain:
|
11
11
|
- |
|
12
12
|
-----BEGIN CERTIFICATE-----
|
13
|
-
|
13
|
+
MIIDPjCCAiagAwIBAgIBBjANBgkqhkiG9w0BAQsFADBFMRMwEQYDVQQDDApyeWFu
|
14
14
|
ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB
|
15
|
-
|
15
|
+
GRYDY29tMB4XDTIxMTIyMzIzMTkwNFoXDTIyMTIyMzIzMTkwNFowRTETMBEGA1UE
|
16
16
|
AwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS
|
17
17
|
JomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda
|
18
18
|
b9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx
|
@@ -22,14 +22,14 @@ cert_chain:
|
|
22
22
|
qhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV
|
23
23
|
gBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw
|
24
24
|
HQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBCwUAA4IB
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
AQCKB5jfsuSnKb+t/Wrh3UpdkmX7TrEsjVmERC0pPqzQ5GQJgmEXDD7oMgaKXaAq
|
26
|
+
x2m+KSZDrqk7c8uho5OX6YMqg4KdxehfSLqqTZGoeV78qwf/jpPQZKTf+W9gUSJh
|
27
|
+
zsWpo4K50MP+QtdSbKXZwjAafpQ8hK0MnnZ/aeCsW9ov5vdXpYbf3dpg6ADXRGE7
|
28
|
+
lQY2y1tJ5/chqu6h7dQmnm2ABUqx9O+JcN9hbCYoA5i/EeubUEtFIh2w3SpO6YfB
|
29
|
+
JFmxn4h9YO/pVdB962BdBNNDia0kgIjI3ENnkLq0dKpYU3+F3KhEuTksLO0L6X/V
|
30
|
+
YsuyUzsMz6GQA4khyaMgKNSD
|
31
31
|
-----END CERTIFICATE-----
|
32
|
-
date:
|
32
|
+
date: 2022-05-23 00:00:00.000000000 Z
|
33
33
|
dependencies:
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: sexp_processor
|
@@ -99,14 +99,14 @@ dependencies:
|
|
99
99
|
requirements:
|
100
100
|
- - "~>"
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version: '3.
|
102
|
+
version: '3.23'
|
103
103
|
type: :development
|
104
104
|
prerelease: false
|
105
105
|
version_requirements: !ruby/object:Gem::Requirement
|
106
106
|
requirements:
|
107
107
|
- - "~>"
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version: '3.
|
109
|
+
version: '3.23'
|
110
110
|
description: Analyze code for potentially uncalled / dead methods, now with auto-removal.
|
111
111
|
email:
|
112
112
|
- ryand-ruby@zenspider.com
|
@@ -133,8 +133,9 @@ files:
|
|
133
133
|
homepage: https://github.com/seattlerb/debride
|
134
134
|
licenses:
|
135
135
|
- MIT
|
136
|
-
metadata:
|
137
|
-
|
136
|
+
metadata:
|
137
|
+
homepage_uri: https://github.com/seattlerb/debride
|
138
|
+
post_install_message:
|
138
139
|
rdoc_options:
|
139
140
|
- "--main"
|
140
141
|
- README.rdoc
|
@@ -151,8 +152,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
151
152
|
- !ruby/object:Gem::Version
|
152
153
|
version: '0'
|
153
154
|
requirements: []
|
154
|
-
rubygems_version: 3.
|
155
|
-
signing_key:
|
155
|
+
rubygems_version: 3.3.12
|
156
|
+
signing_key:
|
156
157
|
specification_version: 4
|
157
158
|
summary: Analyze code for potentially uncalled / dead methods, now with auto-removal.
|
158
159
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|