debride 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6abab211f7ada7517c61d2ed301cc1b9762d435d
4
+ data.tar.gz: c2b904f36e9275028ad3966b74ce9fb53ca9d639
5
+ SHA512:
6
+ metadata.gz: ba06f6b5951e6094f242191706c9f1fbe6de90ae609bdd869ce0560eb3d7c855f1164cdfc62602feb55e2c87d8596181469eb81c2761350ad65a94c85f08850d
7
+ data.tar.gz: df82696ec8ffcf55b1b2ad0985a31ab211909ec977ef983329d4cab824ce6164aa3f1b2834085c57f8ad8565868c53bfbdbcc6e5fa0cd83fe69f276a79531890
checksums.yaml.gz.sig ADDED
Binary file
data.tar.gz.sig ADDED
Binary file
data/.autotest ADDED
@@ -0,0 +1,26 @@
1
+ # -*- ruby -*-
2
+
3
+ require "autotest/restart"
4
+
5
+ Autotest.add_hook :initialize do |at|
6
+ at.testlib = "minitest/autorun"
7
+ at.add_exception "tmp"
8
+
9
+ # at.extra_files << "../some/external/dependency.rb"
10
+ #
11
+ # at.libs << ":../some/external"
12
+ #
13
+ # at.add_exception "vendor"
14
+ #
15
+ # at.add_mapping(/dependency.rb/) do |f, _|
16
+ # at.files_matching(/test_.*rb$/)
17
+ # end
18
+ #
19
+ # %w(TestA TestB).each do |klass|
20
+ # at.extra_class_map[klass] = "test/test_misc.rb"
21
+ # end
22
+ end
23
+
24
+ # Autotest.add_hook :run_command do |at|
25
+ # system "rake build"
26
+ # end
data/.gemtest ADDED
File without changes
data/History.rdoc ADDED
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2015-03-09
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
data/Manifest.txt ADDED
@@ -0,0 +1,8 @@
1
+ .autotest
2
+ History.rdoc
3
+ Manifest.txt
4
+ README.rdoc
5
+ Rakefile
6
+ bin/debride
7
+ lib/debride.rb
8
+ test/test_debride.rb
data/README.rdoc ADDED
@@ -0,0 +1,56 @@
1
+ = debride
2
+
3
+ home :: https://github.com/seattlerb/debride
4
+ rdoc :: http://docs.seattlerb.org/debride
5
+
6
+ == DESCRIPTION:
7
+
8
+ Analyze code for potentially uncalled / dead methods.
9
+
10
+ == FEATURES/PROBLEMS:
11
+
12
+ * Static analysis of code. Can be easily hooked up to a CI.
13
+ * As with all static analysis tools of dynamic languages, can't be 100%.
14
+
15
+ == SYNOPSIS:
16
+
17
+ % debride lib test
18
+
19
+ These methods MIGHT not be called:
20
+
21
+ MyClass
22
+ method! lib/some/file.rb:16
23
+ ...
24
+
25
+ == REQUIREMENTS:
26
+
27
+ * ruby 1.8+
28
+
29
+ == INSTALL:
30
+
31
+ * sudo gem install debride
32
+
33
+ == LICENSE:
34
+
35
+ (The MIT License)
36
+
37
+ Copyright (c) Ryan Davis, seattle.rb
38
+
39
+ Permission is hereby granted, free of charge, to any person obtaining
40
+ a copy of this software and associated documentation files (the
41
+ 'Software'), to deal in the Software without restriction, including
42
+ without limitation the rights to use, copy, modify, merge, publish,
43
+ distribute, sublicense, and/or sell copies of the Software, and to
44
+ permit persons to whom the Software is furnished to do so, subject to
45
+ the following conditions:
46
+
47
+ The above copyright notice and this permission notice shall be
48
+ included in all copies or substantial portions of the Software.
49
+
50
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
51
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
52
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
53
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
54
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
55
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
56
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ # -*- ruby -*-
2
+
3
+ require "rubygems"
4
+ require "hoe"
5
+
6
+ Hoe.plugin :isolate
7
+ Hoe.plugin :seattlerb
8
+ Hoe.plugin :rdoc
9
+
10
+ Hoe.spec "debride" do
11
+ developer "Ryan Davis", "ryand-ruby@zenspider.com"
12
+ license "MIT"
13
+
14
+ dependency "sexp_processor", "~> 4.4"
15
+ dependency "ruby_parser", "~> 3.6"
16
+ end
17
+
18
+ # vim: syntax=ruby
data/bin/debride ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "debride"
4
+
5
+ Debride.run(ARGV).report
data/lib/debride.rb ADDED
@@ -0,0 +1,167 @@
1
+ #!/usr/bin/ruby -w
2
+
3
+ $:.unshift "../../sexp_processor/dev/lib"
4
+
5
+ require "ruby_parser"
6
+ require "sexp_processor"
7
+ require "optparse"
8
+ require "set"
9
+
10
+ ##
11
+ # A static code analyzer that points out possible dead methods.
12
+
13
+ class Debride < MethodBasedSexpProcessor
14
+ VERSION = "1.0.0" # :nodoc:
15
+
16
+ ##
17
+ # Top level runner for bin/debride.
18
+
19
+ def self.run args
20
+ opt = parse_options args
21
+
22
+ callers = Debride.new opt
23
+
24
+ expand_dirs_to_files(args).each do |path|
25
+ warn "processing: #{path}" if opt[:verbose]
26
+ parser = RubyParser.new
27
+ callers.process parser.process File.read(path), path
28
+ end
29
+
30
+ callers
31
+ end
32
+
33
+ ##
34
+ # Parse command line options and return a hash of parsed option values.
35
+
36
+ def self.parse_options args
37
+ options = {}
38
+
39
+ OptionParser.new do |opts|
40
+ opts.banner = "debride [options] files_or_dirs"
41
+ opts.version = Debride::VERSION
42
+
43
+ opts.separator ""
44
+ opts.separator "Specific options:"
45
+ opts.separator ""
46
+
47
+ opts.on("-h", "--help", "Display this help.") do
48
+ puts opts
49
+ exit
50
+ end
51
+
52
+ # opts.on("-e", "--exclude FILE", String, "Exclude these messages.") do |s|
53
+ # options[:exclude] = s
54
+ # end
55
+
56
+ opts.on("-v", "--verbose", "Verbose. Show progress processing files.") do
57
+ options[:verbose] = true
58
+ end
59
+
60
+ opts.parse! args
61
+ end
62
+
63
+ options
64
+ end
65
+
66
+ ##
67
+ # A collection of know methods, mapping method name to implementing classes.
68
+
69
+ attr_accessor :known
70
+
71
+ ##
72
+ # A set of called method names.
73
+
74
+ attr_accessor :called
75
+
76
+ ##
77
+ # Command-line options.
78
+
79
+ attr_accessor :option
80
+ attr_accessor :map # :nodoc: # TODO: retire and use method_locations
81
+
82
+ ##
83
+ # Create a new Debride instance w/ +options+
84
+
85
+ def initialize options = {}
86
+ self.option = options
87
+ self.known = Hash.new { |h,k| h[k] = Set.new }
88
+ self.called = Set.new
89
+ self.map = Hash.new { |h,k| h[k] = {} }
90
+ super()
91
+ end
92
+
93
+ def klass_name # :nodoc:
94
+ super.to_s
95
+ end
96
+
97
+ def method_name # :nodoc:
98
+ super.to_s.sub(/^::|#/, "").to_sym
99
+ end
100
+
101
+ def process_defn sexp # :nodoc:
102
+ super do
103
+ map[klass_name][method_name] = signature
104
+ known[method_name] << klass_name
105
+ process_until_empty sexp
106
+ end
107
+ end
108
+
109
+ def process_defs sexp # :nodoc:
110
+ super do
111
+ map[klass_name][method_name] = signature
112
+ known[method_name] << klass_name
113
+ process_until_empty sexp
114
+ end
115
+ end
116
+
117
+ def process_call sexp # :nodoc:
118
+ method_name = sexp[2]
119
+ method_name = :initialize if method_name == :new
120
+
121
+ if method_name == :alias_method_chain
122
+ known[sexp[3]] << klass_name
123
+ end
124
+
125
+ called << method_name
126
+
127
+ process_until_empty sexp
128
+
129
+ sexp
130
+ end
131
+
132
+ ##
133
+ # Calculate the difference between known methods and called methods.
134
+
135
+ def missing
136
+ not_called = known.keys - called.to_a
137
+
138
+ by_class = Hash.new { |h,k| h[k] = [] }
139
+
140
+ not_called.each do |meth|
141
+ known[meth].each do |klass|
142
+ by_class[klass] << meth
143
+ end
144
+ end
145
+
146
+ by_class.each do |klass, meths|
147
+ by_class[klass] = meths.sort_by(&:to_s)
148
+ end
149
+
150
+ by_class.sort_by { |k,v| k }
151
+ end
152
+
153
+ ##
154
+ # Print out a report of suspects.
155
+
156
+ def report
157
+ puts "These methods MIGHT not be called:"
158
+
159
+ missing.each do |klass, meths|
160
+ puts
161
+ puts klass
162
+ meths.each do |meth|
163
+ puts " %-35s %s" % [meth, method_locations[map[klass][meth]]]
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,38 @@
1
+ require "minitest/autorun"
2
+ require "debride"
3
+
4
+ class TestDebride < Minitest::Test
5
+ def test_sanity
6
+ debride = nil
7
+
8
+ assert_silent do
9
+ debride = Debride.run %w[lib]
10
+ end
11
+
12
+ exp = [["Debride",
13
+ [:process_call, :process_defn, :process_defs, :report, :run]]]
14
+
15
+ assert_equal exp, debride.missing
16
+ end
17
+
18
+ def assert_option arg, rest, exp_opt
19
+ opt = Debride.parse_options arg
20
+
21
+ assert_equal exp_opt, opt
22
+ assert_equal rest, arg
23
+ end
24
+
25
+ def test_parse_options
26
+ assert_option %w[], %w[], {}
27
+
28
+ assert_option %w[--verbose], %w[], :verbose => true
29
+ assert_option %w[-v], %w[], :verbose => true
30
+ assert_option %w[-v woot.rb], %w[woot.rb], :verbose => true
31
+ end
32
+
33
+ def test_parse_options_exclude
34
+ skip "not yet"
35
+
36
+ assert_option %w[--exclude path], %w[], :exclude => "path"
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: debride
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Ryan Davis
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDPjCCAiagAwIBAgIBAjANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu
14
+ ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB
15
+ GRYDY29tMB4XDTE0MDkxNzIzMDcwN1oXDTE1MDkxNzIzMDcwN1owRTETMBEGA1UE
16
+ AwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS
17
+ JomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda
18
+ b9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx
19
+ taCPaLmfYIaFcHHCSY4hYDJijRQkLxPeB3xbOfzfLoBDbjvx5JxgJxUjmGa7xhcT
20
+ oOvjtt5P8+GSK9zLzxQP0gVLS/D0FmoE44XuDr3iQkVS2ujU5zZL84mMNqNB1znh
21
+ GiadM9GHRaDiaxuX0cIUBj19T01mVE2iymf9I6bEsiayK/n6QujtyCbTWsAS9Rqt
22
+ qhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV
23
+ gBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw
24
+ HQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBBQUAA4IB
25
+ AQAFoDJRokCQdxFfOrmsKX41KOFlU/zjrbDVM9hgB/Ur999M6OXGSi8FitXNtMwY
26
+ FVjsiAPeU7HaWVVcZkj6IhINelTkXsxgGz/qCzjHy3iUMuZWw36cS0fiWJ5rvH+e
27
+ hD7uXxJSFuyf1riDGI1aeWbQ74WMwvNstOxLUMiV5a1fzBhlxPqb537ubDjq/M/h
28
+ zPUFPVYeL5KjDHLCqI2FwIk2sEMOQgjpXHzl+3NlD2LUgUhHDMevmgVua0e2GT1B
29
+ xJcC6UN6NHMOVMyAXsr2HR0gRRx4ofN1LoP2KhXzSr8UMvQYlwPmE0N5GQv1b5AO
30
+ VpzF30vNaJK6ZT7xlIsIlwmH
31
+ -----END CERTIFICATE-----
32
+ date: 2015-03-09 00:00:00.000000000 Z
33
+ dependencies:
34
+ - !ruby/object:Gem::Dependency
35
+ name: sexp_processor
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '4.4'
41
+ type: :runtime
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '4.4'
48
+ - !ruby/object:Gem::Dependency
49
+ name: ruby_parser
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '3.6'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.6'
62
+ - !ruby/object:Gem::Dependency
63
+ name: minitest
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '5.5'
69
+ type: :development
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '5.5'
76
+ - !ruby/object:Gem::Dependency
77
+ name: rdoc
78
+ requirement: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '4.0'
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '4.0'
90
+ - !ruby/object:Gem::Dependency
91
+ name: hoe
92
+ requirement: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '3.13'
97
+ type: :development
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '3.13'
104
+ description: Analyze code for potentially uncalled / dead methods.
105
+ email:
106
+ - ryand-ruby@zenspider.com
107
+ executables:
108
+ - debride
109
+ extensions: []
110
+ extra_rdoc_files:
111
+ - History.rdoc
112
+ - Manifest.txt
113
+ - README.rdoc
114
+ files:
115
+ - .autotest
116
+ - .gemtest
117
+ - History.rdoc
118
+ - Manifest.txt
119
+ - README.rdoc
120
+ - Rakefile
121
+ - bin/debride
122
+ - lib/debride.rb
123
+ - test/test_debride.rb
124
+ homepage: https://github.com/seattlerb/debride
125
+ licenses:
126
+ - MIT
127
+ metadata: {}
128
+ post_install_message:
129
+ rdoc_options:
130
+ - --main
131
+ - README.rdoc
132
+ require_paths:
133
+ - lib
134
+ required_ruby_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ requirements: []
145
+ rubyforge_project:
146
+ rubygems_version: 2.4.5
147
+ signing_key:
148
+ specification_version: 4
149
+ summary: Analyze code for potentially uncalled / dead methods.
150
+ test_files: []
metadata.gz.sig ADDED
Binary file