debride 1.8.2 → 1.10.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: 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