debride 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.autotest +1 -0
- data/History.rdoc +18 -0
- data/README.rdoc +5 -0
- data/Rakefile +20 -2
- data/lib/debride.rb +68 -7
- data/test/test_debride.rb +130 -46
- metadata +2 -2
- metadata.gz.sig +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6fb60e6abb914cdca253c8f91a87ee9f29b9573
|
4
|
+
data.tar.gz: c277e27c75a4a571e22cc647fe4d98063f944256
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc8279ae3e71097d6b57ade1054d80c596b76e6b47878b8269fd931abca6b497da3780cf85cff3860563b307a2c01f727fe11f1bc03a11287242e3bd376c75d7
|
7
|
+
data.tar.gz: 560722e6f9d07d1dff4bab14e912cec2d9a019046ee4a5dcfc7a6394e98c9f933e0ff1c4c9dc9b85f2cdd1ad2093889acd2926fb05246bfc96c3bd89bbf477a7
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/.autotest
CHANGED
data/History.rdoc
CHANGED
@@ -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:
|
data/README.rdoc
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
data/lib/debride.rb
CHANGED
@@ -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.
|
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
|
101
|
+
def process_rb path_or_io
|
92
102
|
begin
|
93
|
-
|
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 #{
|
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
|
|
data/test/test_debride.rb
CHANGED
@@ -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
|
19
|
-
|
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
|
27
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
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],
|
36
|
-
assert_option %w[-e moot lib],
|
37
|
-
assert_option %w[-e moot,moot.rb lib],
|
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
|
-
|
56
|
-
|
85
|
+
ruby = <<-RUBY
|
86
|
+
class Seattle
|
87
|
+
def self.raining?
|
88
|
+
true
|
89
|
+
end
|
90
|
+
end
|
57
91
|
|
58
|
-
|
59
|
-
|
92
|
+
# Seattle.raining?
|
93
|
+
RUBY
|
60
94
|
|
61
|
-
|
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
|
-
|
66
|
-
|
103
|
+
ruby = <<-RUBY
|
104
|
+
class Seattle
|
105
|
+
def self.raining?
|
106
|
+
true
|
107
|
+
end
|
108
|
+
end
|
67
109
|
|
68
|
-
|
110
|
+
# Seattle.raining?
|
111
|
+
RUBY
|
69
112
|
|
70
|
-
|
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
|
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
|
-
|
170
|
+
assert_process exp, ruby, :rails => true
|
93
171
|
end
|
94
172
|
|
95
173
|
def test_method_send
|
96
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
211
|
+
assert_process [], ruby, :rails => true
|
212
|
+
end
|
144
213
|
|
145
|
-
|
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
|
-
|
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.
|
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-
|
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
|
-
|
1
|
+
��S��m=X��?t]���<�8R�I��B�KC?ʓ�g����ʯ���1
|