debride 1.8.2 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
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