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 +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
|