debride 1.8.2 → 1.10.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: 59c8a2f9b5b719c39af3b257881dbc7440f7f1c7000b4e55efdb411120f7cbde
4
+ data.tar.gz: 398c595e7080ecab2a3c2195f7a5176c4a4f19ecf517543a9fdc6d7b9dfe3eb4
5
5
  SHA512:
6
- metadata.gz: '099d5cd9f89fe640524ae7c95acd3f24afdefad7f03914c35abe7676bed3e9509ba4bd6cd73cf760fc0805bda07b7da995a2431d33340feed9f5c7fbf2501b36'
7
- data.tar.gz: bc8ed6323a86bfd4f386b81195e2d9d919f4d484a0515c599fa2d1a53d3318650e71fffd2e87683d83603f3ce5e84fb3b4e90a21e4777d782d4d0699c414e448
6
+ metadata.gz: dce7e6ad57ab80693a10c2292192515ced017a6e944aa12c2fde55f766d818357bdc4e7b9c99ab14348a6039a299e3fecd3d105e3a02e544cabba0e5e03d54e5
7
+ data.tar.gz: bc1ec0cf4667aedfc5a85fbf076e3442f08d9acfc7ed2b4e480308f59a6301defcab4222f330f53832af693139aa324ab3cc83ad2d8bc80d1fa63c6e1edc0f18
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
@@ -13,6 +13,7 @@ Hoe::add_include_dirs("../../sexp_processor/dev/lib",
13
13
  Hoe.plugin :isolate
14
14
  Hoe.plugin :seattlerb
15
15
  Hoe.plugin :rdoc
16
+ Hoe.plugin :cov
16
17
 
17
18
  Hoe.spec "debride" do
18
19
  developer "Ryan Davis", "ryand-ruby@zenspider.com"
@@ -26,15 +27,17 @@ end
26
27
  def run dir, whitelist
27
28
  abort "Specify dir to scan with D=<path>" unless dir
28
29
 
29
- ENV["GEM_HOME"] = "tmp/isolate/ruby-2.0.0"
30
- ENV["GEM_PATH"] = "../../debride-erb/dev/tmp/isolate/ruby-2.0.0"
30
+ ENV["GEM_HOME"] = "tmp/isolate"
31
+ ENV["GEM_PATH"] = "../../debride-erb/dev/tmp/isolate"
31
32
 
32
33
  whitelist = whitelist && ["--whitelist", whitelist]
33
34
  verbose = ENV["V"] && "-v"
35
+ exclude = ENV["E"] && ["--exclude", ENV["E"]]
36
+ minimum = ENV["M"] && ["--minimum", ENV["M"]]
34
37
 
35
38
  require "debride"
36
39
 
37
- args = ["--rails", verbose, whitelist, dir].flatten.compact
40
+ args = ["--rails", verbose, minimum, whitelist, exclude, dir].flatten.compact
38
41
 
39
42
  Debride.run(args).report
40
43
  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"
@@ -157,9 +150,21 @@ class Debride < MethodBasedSexpProcessor
157
150
  options[:rails] = true
158
151
  end
159
152
 
153
+ opts.on("-m", "--minimum N", Integer, "Don't show hits less than N locs.") do |n|
154
+ options[:minimum] = n
155
+ end
156
+
160
157
  opts.on("-v", "--verbose", "Verbose. Show progress processing files.") do
161
158
  options[:verbose] = true
162
159
  end
160
+
161
+ opts.on "--json" do
162
+ options[:format] = :json
163
+ end
164
+
165
+ opts.on "--yaml" do
166
+ options[:format] = :yaml
167
+ end
163
168
  end
164
169
 
165
170
  op.parse! args
@@ -239,6 +244,10 @@ class Debride < MethodBasedSexpProcessor
239
244
  _, _, _, *args = sexp
240
245
  file, line = sexp.file, sexp.line
241
246
  args.each do |(_, name)|
247
+ if Sexp === name then
248
+ process name
249
+ next
250
+ end
242
251
  record_method name, file, line
243
252
  record_method "#{name}=".to_sym, file, line
244
253
  end
@@ -247,6 +256,10 @@ class Debride < MethodBasedSexpProcessor
247
256
  _, _, _, *args = sexp
248
257
  file, line = sexp.file, sexp.line
249
258
  args.each do |(_, name)|
259
+ if Sexp === name then
260
+ process name
261
+ next
262
+ end
250
263
  record_method "#{name}=".to_sym, file, line
251
264
  end
252
265
  when :attr_reader then
@@ -254,6 +267,10 @@ class Debride < MethodBasedSexpProcessor
254
267
  _, _, _, *args = sexp
255
268
  file, line = sexp.file, sexp.line
256
269
  args.each do |(_, name)|
270
+ if Sexp === name then
271
+ process name
272
+ next
273
+ end
257
274
  record_method name, file, line
258
275
  end
259
276
  when :send, :public_send, :__send__ then
@@ -262,6 +279,18 @@ class Debride < MethodBasedSexpProcessor
262
279
  if Sexp === msg_arg && [:lit, :str].include?(msg_arg.sexp_type) then
263
280
  called << msg_arg.last.to_sym
264
281
  end
282
+ when :delegate then
283
+ # s(:call, nil, :delegate, ..., s(:hash, s(:lit, :to), s(:lit, :delegator)))
284
+ possible_hash = sexp.last
285
+ if Sexp === possible_hash && possible_hash.sexp_type == :hash
286
+ possible_hash.sexp_body.each_slice(2) do |key, val|
287
+ next unless key == s(:lit, :to)
288
+ next unless Sexp === val
289
+
290
+ called << val.last if val.sexp_type == :lit
291
+ called << val.last.to_sym if val.sexp_type == :str
292
+ end
293
+ end
265
294
  when *RAILS_DSL_METHODS, *RAILS_VALIDATION_METHODS then
266
295
  if option[:rails]
267
296
  # s(:call, nil, :before_save, s(:lit, :save_callback), s(:hash, ...))
@@ -281,10 +310,16 @@ class Debride < MethodBasedSexpProcessor
281
310
  when *RAILS_MACRO_METHODS
282
311
  # s(:call, nil, :has_one, s(:lit, :has_one_relation), ...)
283
312
  _, _, _, (_, name), * = sexp
284
- file, line = sexp.file, sexp.line
285
- record_method name, file, line
313
+
314
+ # try to detect route scope vs model scope
315
+ if context.include? :module or context.include? :class then
316
+ file, line = sexp.file, sexp.line
317
+ record_method name, file, line
318
+ end
286
319
  when /_path$/ then
287
- method_name = method_name.to_s[0..-6].to_sym if option[:rails]
320
+ method_name = method_name.to_s.delete_suffix("_path").to_sym if option[:rails]
321
+ when /^deliver_/ then
322
+ method_name = method_name.to_s.delete_prefix("deliver_").to_sym if option[:rails]
288
323
  end
289
324
 
290
325
  called << method_name
@@ -302,6 +337,7 @@ class Debride < MethodBasedSexpProcessor
302
337
  process val
303
338
 
304
339
  signature = "#{klass_name}::#{name}"
340
+
305
341
  known[name] << klass_name
306
342
 
307
343
  file, line = exp.file, exp.line
@@ -312,12 +348,16 @@ class Debride < MethodBasedSexpProcessor
312
348
 
313
349
  def name_to_string exp
314
350
  case exp.sexp_type
351
+ when :const then
352
+ exp.last.to_s
315
353
  when :colon2 then
316
- _, (_, lhs), rhs = exp
317
- "#{lhs}::#{rhs}"
354
+ _, lhs, rhs = exp
355
+ "#{name_to_string lhs}::#{rhs}"
318
356
  when :colon3 then
319
357
  _, rhs = exp
320
358
  "::#{rhs}"
359
+ when :self then # wtf?
360
+ "self"
321
361
  else
322
362
  raise "Not handled: #{exp.inspect}"
323
363
  end
@@ -397,37 +437,99 @@ class Debride < MethodBasedSexpProcessor
397
437
  by_class.sort_by { |k,v| k }
398
438
  end
399
439
 
440
+ def missing_locations
441
+ focus = option[:focus]
442
+
443
+ missing.map { |klass, meths|
444
+ bad = meths.map { |meth|
445
+ location =
446
+ method_locations["#{klass}##{meth}"] ||
447
+ method_locations["#{klass}::#{meth}"]
448
+
449
+ if focus then
450
+ path = location[/(.+):\d+/, 1]
451
+
452
+ next unless File.fnmatch(focus, path)
453
+ end
454
+
455
+ [meth, location]
456
+ }.compact
457
+
458
+ [klass, bad]
459
+ }
460
+ .to_h
461
+ .reject { |k,v| v.empty? }
462
+ end
463
+
400
464
  ##
401
465
  # Print out a report of suspects.
402
466
 
403
- def report
467
+ def report io = $stdout
404
468
  focus = option[:focus]
469
+ type = option[:format] || :text
470
+
471
+ send "report_#{type}", io, focus, missing_locations
472
+ end
405
473
 
474
+ def report_text io, focus, missing
406
475
  if focus then
407
- puts "Focusing on #{focus}"
408
- puts
476
+ io.puts "Focusing on #{focus}"
477
+ io.puts
409
478
  end
410
479
 
411
- puts "These methods MIGHT not be called:"
480
+ io.puts "These methods MIGHT not be called:"
481
+
482
+ total = 0
412
483
 
413
484
  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]
485
+ bad = meths.map { |(meth, location)|
486
+ loc = if location then
487
+ l0, l1 = location.split(/:/).last.scan(/\d+/).flatten.map(&:to_i)
488
+ l1 ||= l0
489
+ l1 - l0 + 1
490
+ else
491
+ 1
492
+ end
493
+
494
+ next if option[:minimum] && loc < option[:minimum]
495
+
496
+ total += loc
419
497
 
420
- next if focus and not File.fnmatch(focus, path)
498
+ " %-35s %s (%d)" % [meth, location, loc]
499
+ }.compact
421
500
 
422
- " %-35s %s" % [meth, location]
423
- }
424
- bad.compact!
425
501
  next if bad.empty?
426
502
 
427
- puts
428
- puts klass
429
- puts bad.join "\n"
503
+ io.puts
504
+ io.puts klass
505
+ io.puts bad.join "\n"
430
506
  end
507
+ io.puts
508
+ io.puts "Total suspect LOC: %d" % [total]
509
+ end
510
+
511
+ def report_json io, focus, missing
512
+ require "json"
513
+
514
+ data = {
515
+ :missing => missing
516
+ }
517
+
518
+ data[:focus] = focus if focus
519
+
520
+ JSON.dump data, io
521
+ end
522
+
523
+ def report_yaml io, focus, missing
524
+ require "yaml"
525
+
526
+ data = {
527
+ :missing => missing
528
+ }
529
+
530
+ data[:focus] = focus if focus
531
+
532
+ YAML.dump data, io
431
533
  end
432
534
 
433
535
  ##
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.10.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-12-03 00:00:00.000000000 Z
33
33
  dependencies:
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: sexp_processor
@@ -93,20 +93,34 @@ dependencies:
93
93
  - - "<"
94
94
  - !ruby/object:Gem::Version
95
95
  version: '7'
96
+ - !ruby/object:Gem::Dependency
97
+ name: simplecov
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.21'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '0.21'
96
110
  - !ruby/object:Gem::Dependency
97
111
  name: hoe
98
112
  requirement: !ruby/object:Gem::Requirement
99
113
  requirements:
100
114
  - - "~>"
101
115
  - !ruby/object:Gem::Version
102
- version: '3.18'
116
+ version: '3.25'
103
117
  type: :development
104
118
  prerelease: false
105
119
  version_requirements: !ruby/object:Gem::Requirement
106
120
  requirements:
107
121
  - - "~>"
108
122
  - !ruby/object:Gem::Version
109
- version: '3.18'
123
+ version: '3.25'
110
124
  description: Analyze code for potentially uncalled / dead methods, now with auto-removal.
111
125
  email:
112
126
  - ryand-ruby@zenspider.com
@@ -133,8 +147,9 @@ files:
133
147
  homepage: https://github.com/seattlerb/debride
134
148
  licenses:
135
149
  - MIT
136
- metadata: {}
137
- post_install_message:
150
+ metadata:
151
+ homepage_uri: https://github.com/seattlerb/debride
152
+ post_install_message:
138
153
  rdoc_options:
139
154
  - "--main"
140
155
  - README.rdoc
@@ -151,8 +166,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
151
166
  - !ruby/object:Gem::Version
152
167
  version: '0'
153
168
  requirements: []
154
- rubygems_version: 3.0.6
155
- signing_key:
169
+ rubygems_version: 3.3.12
170
+ signing_key:
156
171
  specification_version: 4
157
172
  summary: Analyze code for potentially uncalled / dead methods, now with auto-removal.
158
173
  test_files: []
metadata.gz.sig CHANGED
Binary file