debride 1.3.0 → 1.4.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
  SHA1:
3
- metadata.gz: 5a723b84c9a06468449e24ec4cf6f8911f1cfbc1
4
- data.tar.gz: 7a135fd947b6cbd2905f4d4196aa526966f465e6
3
+ metadata.gz: a6fb60e6abb914cdca253c8f91a87ee9f29b9573
4
+ data.tar.gz: c277e27c75a4a571e22cc647fe4d98063f944256
5
5
  SHA512:
6
- metadata.gz: 6b43c1951aac3602c0ec3bbf1bb28e9aa14d976bb6cc4af7073000795dea551e78d58a20b924396cb2e09f5d422eb9af519d394b413964c541a17ddc46d23ac0
7
- data.tar.gz: eae873a00409532767de144cea3d1f31249d4083a0823bb96ee38f89db7f4321bd4cbf54a977e4b494a55c4b66f531674a22f98bafdae7e51dbb1220207a7997
6
+ metadata.gz: dc8279ae3e71097d6b57ade1054d80c596b76e6b47878b8269fd931abca6b497da3780cf85cff3860563b307a2c01f727fe11f1bc03a11287242e3bd376c75d7
7
+ data.tar.gz: 560722e6f9d07d1dff4bab14e912cec2d9a019046ee4a5dcfc7a6394e98c9f933e0ff1c4c9dc9b85f2cdd1ad2093889acd2926fb05246bfc96c3bd89bbf477a7
Binary file
data.tar.gz.sig CHANGED
Binary file
data/.autotest CHANGED
@@ -1,6 +1,7 @@
1
1
  # -*- ruby -*-
2
2
 
3
3
  require "autotest/restart"
4
+ require "autotest/isolate"
4
5
 
5
6
  Autotest.add_hook :initialize do |at|
6
7
  at.testlib = "minitest/autorun"
@@ -1,3 +1,21 @@
1
+ === 1.4.0 / 2015-05-27
2
+
3
+ * 1 major enhancement:
4
+
5
+ * Added support for analyzing potentially unused constants.
6
+
7
+ * 5 minor enhancements:
8
+
9
+ * Extended process_rb to work with IO/StringIO.
10
+ * Print file being processed if --verbose.
11
+ * Print help and exit if no files/dirs specified. (phiggins)
12
+ * Rescue RubyParser parse errors, warn, and skip.
13
+ * Use RubyParser.for_current_ruby.
14
+
15
+ * 1 bug fix:
16
+
17
+ * Debride.new will default to proper options.
18
+
1
19
  === 1.3.0 / 2015-04-13
2
20
 
3
21
  * 4 minor enhancements:
@@ -38,6 +38,11 @@ API), then you can whitelist it:
38
38
 
39
39
  You can also use regexps in your whitelist by delimiting them with //'s.
40
40
 
41
+ == PLUGINS:
42
+
43
+ debride-erb :: Extends debride to analyze erb files (via erubis ala rails).
44
+ debride-haml :: Plugin to allow debride to parse Haml files.
45
+
41
46
  == REQUIREMENTS:
42
47
 
43
48
  * ruby 1.8+
data/Rakefile CHANGED
@@ -15,10 +15,28 @@ Hoe.spec "debride" do
15
15
  dependency "ruby_parser", "~> 3.6"
16
16
  end
17
17
 
18
- task :rails do
18
+ def run dir, wl
19
19
  ENV["GEM_HOME"] = "tmp/isolate/ruby-2.0.0"
20
20
  ENV["GEM_PATH"] = "../../debride-erb/dev/tmp/isolate/ruby-2.0.0"
21
- ruby "-Ilib:../../debride-erb/dev/lib bin/debride --rails ~/Work/git/seattlerb.org/{app,lib} --whitelist ~/Work/git/seattlerb.org/whitelist.txt"
21
+
22
+ abort "Specify dir to scan with D=<path>" unless dir
23
+ wl = "--whitelist #{wl}" if wl
24
+
25
+ ruby "-Ilib:../../debride-erb/dev/lib bin/debride --rails #{dir} #{wl}"
26
+ end
27
+
28
+ task :run do
29
+ run ENV["D"], ENV["W"]
30
+ end
31
+
32
+ task :rails do
33
+ d = "~/Work/git/seattlerb.org"
34
+ run "#{d}/{app,lib,config}", "#{d}/whitelist.txt"
35
+ end
36
+
37
+ task :debug do
38
+ f = ENV["F"]
39
+ run f, nil
22
40
  end
23
41
 
24
42
  # vim: syntax=ruby
@@ -5,11 +5,21 @@ require "sexp_processor"
5
5
  require "optparse"
6
6
  require "set"
7
7
 
8
+ # :stopdoc:
9
+ class File
10
+ RUBY19 = "<3".respond_to? :encoding unless defined? RUBY19 # :nodoc:
11
+
12
+ class << self
13
+ alias :binread :read unless RUBY19
14
+ end
15
+ end
16
+ # :startdoc:
17
+
8
18
  ##
9
19
  # A static code analyzer that points out possible dead methods.
10
20
 
11
21
  class Debride < MethodBasedSexpProcessor
12
- VERSION = "1.3.0" # :nodoc:
22
+ VERSION = "1.4.0" # :nodoc:
13
23
  PROJECT = "debride"
14
24
 
15
25
  def self.expand_dirs_to_files *dirs # TODO: push back up to sexp_processor
@@ -88,11 +98,25 @@ class Debride < MethodBasedSexpProcessor
88
98
  end
89
99
  end
90
100
 
91
- def process_rb file
101
+ def process_rb path_or_io
92
102
  begin
93
- RubyParser.new.process(File.binread(file), file, option[:timeout])
103
+ warn "processing: #{path}" if option[:verbose]
104
+
105
+ case path_or_io
106
+ when String then
107
+ path, file = path_or_io, File.binread(path_or_io)
108
+ when IO, StringIO then
109
+ path, file = "(io)", path_or_io.read
110
+ else
111
+ raise "Unhandled type: #{path_or_io.class}:#{path_or_io.inspect}"
112
+ end
113
+
114
+ RubyParser.for_current_ruby.process(file, path, option[:timeout])
115
+ rescue Racc::ParseError => e
116
+ warn "Parse Error parsing #{path}. Skipping."
117
+ warn " #{e.message}"
94
118
  rescue Timeout::Error
95
- warn "TIMEOUT parsing #{file}. Skipping."
119
+ warn "TIMEOUT parsing #{path}. Skipping."
96
120
  end
97
121
  end
98
122
 
@@ -102,7 +126,7 @@ class Debride < MethodBasedSexpProcessor
102
126
  def self.parse_options args
103
127
  options = {:whitelist => []}
104
128
 
105
- OptionParser.new do |opts|
129
+ op = OptionParser.new do |opts|
106
130
  opts.banner = "debride [options] files_or_dirs"
107
131
  opts.version = Debride::VERSION
108
132
 
@@ -134,6 +158,8 @@ class Debride < MethodBasedSexpProcessor
134
158
  opts.parse! args
135
159
  end
136
160
 
161
+ abort op.to_s if args.empty?
162
+
137
163
  options
138
164
  end
139
165
 
@@ -157,7 +183,7 @@ class Debride < MethodBasedSexpProcessor
157
183
  # Create a new Debride instance w/ +options+
158
184
 
159
185
  def initialize options = {}
160
- self.option = options
186
+ self.option = { :whitelist => [] }.merge options
161
187
  self.known = Hash.new { |h,k| h[k] = Set.new }
162
188
  self.called = Set.new
163
189
  self.map = Hash.new { |h,k| h[k] = {} }
@@ -172,6 +198,41 @@ class Debride < MethodBasedSexpProcessor
172
198
  super.to_s.sub(/^::|#/, "").to_sym
173
199
  end
174
200
 
201
+ def process_cdecl exp # :nodoc:
202
+ _, name, val = exp
203
+ process val
204
+
205
+ map[klass_name][name] = "#{klass_name}::#{name}"
206
+ known[name] << klass_name
207
+
208
+ exp
209
+ end
210
+
211
+ def process_colon2 exp # :nodoc:
212
+ _, lhs, name = exp
213
+ process lhs
214
+
215
+ called << name
216
+
217
+ exp
218
+ end
219
+
220
+ def process_colon3 exp # :nodoc:
221
+ _, name = exp
222
+
223
+ called << name
224
+
225
+ exp
226
+ end
227
+
228
+ def process_const exp # :nodoc:
229
+ _, name = exp
230
+
231
+ called << name
232
+
233
+ exp
234
+ end
235
+
175
236
  def process_defn sexp # :nodoc:
176
237
  super do
177
238
  map[klass_name][method_name] = signature
@@ -256,7 +317,7 @@ class Debride < MethodBasedSexpProcessor
256
317
 
257
318
  whitelist_regexp = Regexp.union whitelist_regexps
258
319
 
259
- not_called.reject! { |s| whitelist_regexp =~ s }
320
+ not_called.reject! { |s| whitelist_regexp =~ s.to_s }
260
321
 
261
322
  by_class = Hash.new { |h,k| h[k] = [] }
262
323
 
@@ -1,8 +1,33 @@
1
1
  require "minitest/autorun"
2
2
  require "debride"
3
3
 
4
+ class SafeDebride < Debride
5
+ def self.abort s
6
+ raise s
7
+ end
8
+ end
9
+
4
10
  class TestDebride < Minitest::Test
11
+ def assert_option arg, exp_arg, exp_opt
12
+ opt = SafeDebride.parse_options arg
13
+
14
+ exp_opt = {:whitelist => []}.merge exp_opt
15
+ assert_equal exp_opt, opt
16
+ assert_equal exp_arg, arg
17
+ end
18
+
19
+ def assert_process exp, ruby, opts = {}
20
+ io = StringIO.new ruby
21
+
22
+ debride = Debride.new opts
23
+ debride.process debride.process_rb io
24
+
25
+ assert_equal exp, debride.missing
26
+ end
27
+
5
28
  def test_sanity
29
+ skip "This is slow" unless ENV["SLOW"]
30
+
6
31
  debride = nil
7
32
 
8
33
  assert_silent do
@@ -15,34 +40,39 @@ class TestDebride < Minitest::Test
15
40
  assert_equal exp, debride.missing
16
41
  end
17
42
 
18
- def assert_option arg, rest, exp_opt
19
- opt = Debride.parse_options arg
20
-
21
- exp_opt = {:whitelist => []}.merge exp_opt
22
- assert_equal exp_opt, opt
23
- assert_equal rest, arg
43
+ def test_parse_options
44
+ assert_option %w[--verbose woot.rb], %w[woot.rb], :verbose => true
45
+ assert_option %w[-v woot.rb], %w[woot.rb], :verbose => true
24
46
  end
25
47
 
26
- def test_parse_options
27
- assert_option %w[], %w[], {}
48
+ def test_parse_options_empty
49
+ e = assert_raises RuntimeError do
50
+ assert_option %w[], %w[], {}
51
+ end
52
+
53
+ assert_includes e.message, "debride [options] files_or_dirs"
28
54
 
29
- assert_option %w[--verbose], %w[], :verbose => true
30
- assert_option %w[-v], %w[], :verbose => true
31
- assert_option %w[-v woot.rb], %w[woot.rb], :verbose => true
55
+ e = assert_raises RuntimeError do
56
+ assert_option %w[-v], %w[], :verbose => true
57
+ end
58
+
59
+ assert_includes e.message, "debride [options] files_or_dirs"
32
60
  end
33
61
 
34
62
  def test_parse_options_exclude
35
- assert_option %w[--exclude moot.rb], %w[], :exclude => %w[moot.rb]
36
- assert_option %w[-e moot lib], %w[lib], :exclude => %w[moot]
37
- assert_option %w[-e moot,moot.rb lib], %w[lib], :exclude => %w[moot moot.rb]
63
+ assert_option %w[--exclude moot.rb lib], %w[lib], :exclude => %w[moot.rb]
64
+ assert_option %w[-e moot lib], %w[lib], :exclude => %w[moot]
65
+ assert_option %w[-e moot,moot.rb lib], %w[lib], :exclude => %w[moot moot.rb]
38
66
  end
39
67
 
40
68
  def test_parse_options_whitelist
41
69
  exp = File.readlines("Manifest.txt").map(&:chomp) # omg dumb
42
- assert_option %w[--whitelist Manifest.txt], %w[], :whitelist => exp
70
+ assert_option %w[--whitelist Manifest.txt lib], %w[lib], :whitelist => exp
43
71
  end
44
72
 
45
73
  def test_exclude_files
74
+ skip "This is slow" unless ENV["SLOW"]
75
+
46
76
  debride = Debride.run %w[--exclude test lib]
47
77
 
48
78
  exp = [["Debride",
@@ -52,28 +82,80 @@ class TestDebride < Minitest::Test
52
82
  end
53
83
 
54
84
  def test_whitelist
55
- debride = Debride.run %w[lib]
56
- debride.option[:whitelist] = %w[process_defn]
85
+ ruby = <<-RUBY
86
+ class Seattle
87
+ def self.raining?
88
+ true
89
+ end
90
+ end
57
91
 
58
- exp = [["Debride",
59
- [:process_call, :process_defs, :process_rb, :report]]]
92
+ # Seattle.raining?
93
+ RUBY
60
94
 
61
- assert_equal exp, debride.missing
95
+ exp = [["Seattle", [:raining?]]]
96
+ assert_process exp, ruby
97
+
98
+ exp = []
99
+ assert_process exp, ruby, :whitelist => %w[raining?]
62
100
  end
63
101
 
64
102
  def test_whitelist_regexp
65
- debride = Debride.run %w[lib]
66
- debride.option[:whitelist] = %w[/^process_/ run]
103
+ ruby = <<-RUBY
104
+ class Seattle
105
+ def self.raining?
106
+ true
107
+ end
108
+ end
67
109
 
68
- exp = [["Debride", [:report]]]
110
+ # Seattle.raining?
111
+ RUBY
69
112
 
70
- assert_equal exp, debride.missing
113
+ exp = [["Seattle", [:raining?]]]
114
+ assert_process exp, ruby
115
+
116
+ exp = []
117
+ assert_process exp, ruby, :whitelist => %w[/raining/]
71
118
  end
72
119
 
73
- def test_alias_method_chain
120
+ def test_process_rb_path
74
121
  file = Tempfile.new ["debride_test", ".rb"]
75
122
 
76
123
  file.write <<-RUBY.strip
124
+ class Seattle
125
+ def self.raining?
126
+ true
127
+ end
128
+ end
129
+
130
+ Seattle.raining?
131
+ RUBY
132
+
133
+ file.flush
134
+
135
+ debride = Debride.new
136
+ debride.process_rb file.path
137
+
138
+ exp = []
139
+
140
+ assert_equal exp, debride.missing
141
+ end
142
+
143
+ def test_process_rb_io
144
+ s = <<-RUBY.strip
145
+ class Seattle
146
+ def self.raining?
147
+ true
148
+ end
149
+ end
150
+
151
+ Seattle.raining?
152
+ RUBY
153
+
154
+ assert_process [], s
155
+ end
156
+
157
+ def test_alias_method_chain
158
+ ruby = <<-RUBY.strip
77
159
  class QuarterPounder
78
160
  def royale_with_cheese
79
161
  1+1
@@ -83,19 +165,13 @@ class TestDebride < Minitest::Test
83
165
  end
84
166
  RUBY
85
167
 
86
- file.flush
87
-
88
- debride = Debride.run [file.path, "--rails"]
89
-
90
168
  exp = [["QuarterPounder", [:royale, :royale_with_cheese]]]
91
169
 
92
- assert_equal exp, debride.missing
170
+ assert_process exp, ruby, :rails => true
93
171
  end
94
172
 
95
173
  def test_method_send
96
- file = Tempfile.new ["debride_test", ".rb"]
97
-
98
- file.write <<-RUBY.strip
174
+ ruby = <<-RUBY.strip
99
175
  class Seattle
100
176
  def self.raining?
101
177
  true
@@ -111,19 +187,11 @@ class TestDebride < Minitest::Test
111
187
  Seattle.send "\#{foo}_bar"
112
188
  RUBY
113
189
 
114
- file.flush
115
-
116
- debride = Debride.run [file.path]
117
-
118
- exp = []
119
-
120
- assert_equal exp, debride.missing
190
+ assert_process [], ruby
121
191
  end
122
192
 
123
193
  def test_rails_dsl_methods
124
- file = Tempfile.new ["debride_test", ".rb"]
125
-
126
- file.write <<-RUBY.strip
194
+ ruby = <<-RUBY.strip
127
195
  class RailsThing
128
196
  def save_callback ; 1 ; end
129
197
  def action_filter ; 1 ; end
@@ -140,10 +208,26 @@ class TestDebride < Minitest::Test
140
208
  end
141
209
  RUBY
142
210
 
143
- file.flush
211
+ assert_process [], ruby, :rails => true
212
+ end
144
213
 
145
- debride = Debride.run [file.path, "--rails"]
214
+ def test_constants
215
+ ruby = <<-RUBY.strip
216
+ class Constants
217
+ USED = 42
218
+ ALSO = 314
219
+ UNUSED = 24
220
+
221
+ def something
222
+ p USED
223
+ end
224
+ end
225
+
226
+ something
227
+ Constants::ALSO
228
+ ::Constants::ALSO
229
+ RUBY
146
230
 
147
- assert_equal [], debride.missing.sort
231
+ assert_process [["Constants", [:UNUSED]]], ruby
148
232
  end
149
233
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: debride
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Davis
@@ -29,7 +29,7 @@ cert_chain:
29
29
  xJcC6UN6NHMOVMyAXsr2HR0gRRx4ofN1LoP2KhXzSr8UMvQYlwPmE0N5GQv1b5AO
30
30
  VpzF30vNaJK6ZT7xlIsIlwmH
31
31
  -----END CERTIFICATE-----
32
- date: 2015-04-13 00:00:00.000000000 Z
32
+ date: 2015-05-27 00:00:00.000000000 Z
33
33
  dependencies:
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: sexp_processor
metadata.gz.sig CHANGED
@@ -1 +1 @@
1
- i�y��`2æ;kd葅��*�籃�W�O��)���/s�5�g�6�=�qbwb]E*���c)μ� VRƼE״����|~�0&�ͦ�ʮ�W��H3Z�yh��0βs�F35»c�̦ϕ_L6֜�|��r��S ���)X3B}*N��6��M(a���휹�dQ�℀Ik���L%��uBKҀ���~NHz�󺣞�c�D(���?������g�C���S�P�#>80�NOH�B�V�K����-xl��
1
+ ��S��m=X��?t]���<�8R�I��BKC?ʓ�g����ʯ���1