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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b16bea89c5bac1de568f81f4403fc92146971a327298add5127d6d8ef1bd55c
4
- data.tar.gz: 6c2fc0d65c1115038ba58779410a078ff5f070222683221c5bb604420afc803d
3
+ metadata.gz: 1c2b2a4fb03bd2f6f8a5406f0b413e3159b49ac6a9b0c3641bedc7a6e724a548
4
+ data.tar.gz: cdeb2dc596fe5e496ed940a989fe84f482480c2a2cc7436228e1c4b07755ccbf
5
5
  SHA512:
6
- metadata.gz: '099d5cd9f89fe640524ae7c95acd3f24afdefad7f03914c35abe7676bed3e9509ba4bd6cd73cf760fc0805bda07b7da995a2431d33340feed9f5c7fbf2501b36'
7
- data.tar.gz: bc8ed6323a86bfd4f386b81195e2d9d919f4d484a0515c599fa2d1a53d3318650e71fffd2e87683d83603f3ce5e84fb3b4e90a21e4777d782d4d0699c414e448
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/ruby-2.0.0"
30
- ENV["GEM_PATH"] = "../../debride-erb/dev/tmp/isolate/ruby-2.0.0"
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.8.2" # :nodoc:
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
- begin
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
- rp = RubyParser.for_current_ruby rescue RubyParser.new
110
- rp.process(file, path, option[:timeout])
111
- rescue Racc::ParseError, RegexpError => e
112
- warn "Parse Error parsing #{path}. Skipping."
113
- warn " #{e.message}"
114
- rescue Timeout::Error
115
- warn "TIMEOUT parsing #{path}. Skipping."
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 = {:whitelist => []}
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
- next if focus and not File.fnmatch(focus, path)
446
+ io.puts
447
+ io.puts klass
448
+ io.puts bad.join "\n"
449
+ end
450
+ end
421
451
 
422
- " %-35s %s" % [meth, location]
423
- }
424
- bad.compact!
425
- next if bad.empty?
452
+ def report_json io, focus, missing
453
+ require "json"
426
454
 
427
- puts
428
- puts klass
429
- puts bad.join "\n"
430
- end
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
- exp = [["Debride",
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
- skip "This is slow" unless ENV["SLOW"]
102
+ debride = Debride.run %w[--exclude test/ lib test]
89
103
 
90
- debride = Debride.run %w[--exclude test lib]
104
+ assert_equal EXP_LIST, debride.missing
105
+ end
91
106
 
92
- exp = [["Debride",
93
- [:process_attrasgn, :process_call, :process_cdecl, :process_colon2,
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
- assert_equal exp, debride.missing
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.8.2
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
- MIIDPjCCAiagAwIBAgIBAzANBgkqhkiG9w0BAQsFADBFMRMwEQYDVQQDDApyeWFu
13
+ MIIDPjCCAiagAwIBAgIBBjANBgkqhkiG9w0BAQsFADBFMRMwEQYDVQQDDApyeWFu
14
14
  ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB
15
- GRYDY29tMB4XDTE4MTIwNDIxMzAxNFoXDTE5MTIwNDIxMzAxNFowRTETMBEGA1UE
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
- AQCbJwLmpJR2PomLU+Zzw3KRzH/hbyUWc/ftru71AopZ1fy4iY9J/BW5QYKVYwbP
26
- V0FSBWtvfI/RdwfKGtuGhPKECZgmLieGuZ3XCc09qPu1bdg7i/tu1p0t0c6163ku
27
- nDMDIC/t/DAFK0TY9I3HswuyZGbLW7rgF0DmiuZdN/RPhHq2pOLMLXJmFclCb/im
28
- 9yToml/06TJdUJ5p64mkBs0TzaK66DIB1Smd3PdtfZqoRV+EwaXMdx0Hb3zdR1JR
29
- Em82dBUFsipwMLCYj39kcyHWAxyl6Ae1Cn9r/ItVBCxoeFdrHjfavnrIEoXUt4bU
30
- UfBugfLD19bu3nvL+zTAGx/U
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: 2019-09-25 00:00:00.000000000 Z
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.18'
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.18'
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
- post_install_message:
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.0.6
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