flog 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/History.txt +5 -0
  2. data/Manifest.txt +5 -0
  3. data/README.txt +57 -0
  4. data/Rakefile +15 -0
  5. data/bin/flog +211 -0
  6. metadata +61 -0
@@ -0,0 +1,5 @@
1
+ == 1.0.0 / 2007-08-01
2
+
3
+ * 1 major enhancement
4
+ * Birthday!
5
+
@@ -0,0 +1,5 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/flog
@@ -0,0 +1,57 @@
1
+ flog
2
+ by Ryan Davis, Seattle.rb
3
+ http://seattlerb.rubyforge.org/
4
+ http://rubyforge.org/projects/seattlerb
5
+
6
+ == DESCRIPTION:
7
+
8
+ Flog reports the most tortured code in an easy to read pain
9
+ report. The higher the score, the more pain the code is in.
10
+
11
+ == FEATURES/PROBLEMS:
12
+
13
+ * Rough around the edges.
14
+
15
+ == SYNOPSIS:
16
+
17
+ % ./bin/flog bin/flog
18
+ Total score = 128.7
19
+
20
+ Flog#report: (21)
21
+ 4: puts
22
+ 2: sort_by
23
+ ...
24
+
25
+ == REQUIREMENTS:
26
+
27
+ * ruby2ruby
28
+ * parse_tree
29
+
30
+ == INSTALL:
31
+
32
+ * sudo gem install -y flog
33
+
34
+ == LICENSE:
35
+
36
+ (The MIT License)
37
+
38
+ Copyright (c) 2007 Ryan Davis, Seattle.rb
39
+
40
+ Permission is hereby granted, free of charge, to any person obtaining
41
+ a copy of this software and associated documentation files (the
42
+ 'Software'), to deal in the Software without restriction, including
43
+ without limitation the rights to use, copy, modify, merge, publish,
44
+ distribute, sublicense, and/or sell copies of the Software, and to
45
+ permit persons to whom the Software is furnished to do so, subject to
46
+ the following conditions:
47
+
48
+ The above copyright notice and this permission notice shall be
49
+ included in all copies or substantial portions of the Software.
50
+
51
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
52
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
53
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
54
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
55
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
56
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
57
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,15 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ load './bin/flog'
6
+
7
+ Hoe.new('flog', Flog::VERSION) do |p|
8
+ p.rubyforge_name = 'seattlerb'
9
+ p.summary = p.paragraphs_of('README.txt', 2).first
10
+ p.description = p.paragraphs_of('README.txt', 2, 6).join("\n\n")
11
+ p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/).last.strip
12
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
13
+ end
14
+
15
+ # vim: syntax=Ruby
@@ -0,0 +1,211 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ require 'rubygems'
4
+ require 'parse_tree'
5
+ require 'sexp_processor'
6
+ require 'unified_ruby'
7
+
8
+ class Flog < SexpProcessor
9
+ VERSION = '1.0.0'
10
+
11
+ include UnifiedRuby
12
+
13
+ THRESHOLD = 0.60
14
+
15
+ SCORES = Hash.new(1)
16
+
17
+ SCORES.merge!(:define_method => 5,
18
+ :eval => 5,
19
+ :module_eval => 5,
20
+ :class_eval => 5,
21
+ :instance_eval => 5)
22
+
23
+ SCORES.merge!(:alias_method => 2,
24
+ :include => 2,
25
+ :extend => 2,
26
+ :instance_method => 2,
27
+ :instance_methods => 2,
28
+ :method_added => 2,
29
+ :method_defined? => 2,
30
+ :method_removed => 2,
31
+ :method_undefined => 2,
32
+ :private_class_method => 2,
33
+ :private_instance_methods => 2,
34
+ :private_method_defined? => 2,
35
+ :protected_instance_methods => 2,
36
+ :protected_method_defined? => 2,
37
+ :public_class_method => 2,
38
+ :public_instance_methods => 2,
39
+ :public_method_defined? => 2,
40
+ :remove_method => 2,
41
+ :undef_method => 2)
42
+
43
+ @@no_class = :none
44
+ @@no_method = :none
45
+
46
+ def initialize
47
+ super
48
+ @pt = ParseTree.new(false)
49
+ @klass_name, @method_name = @@no_class, @@no_method
50
+ self.auto_shift_type = true
51
+ self.require_empty = false # HACK
52
+ @totals = Hash.new 0
53
+ @multiplier = 1.0
54
+
55
+ @calls = Hash.new { |h,k| h[k] = Hash.new 0 }
56
+ end
57
+
58
+ def process_files *files
59
+ files.flatten.each do |file|
60
+ next unless File.file? file or file == "-"
61
+ ruby = file == "-" ? $stdin.read : File.read(file)
62
+ sexp = @pt.parse_tree_for_string(ruby, file)
63
+ process Sexp.from_array(sexp)
64
+ end
65
+ end
66
+
67
+ def report
68
+ total_score = @totals.values.inject(0) { |sum,n| sum + n }
69
+ max = total_score * THRESHOLD
70
+ current = 0
71
+
72
+ puts "Total score = #{total_score}"
73
+ puts
74
+
75
+ @calls.sort_by { |k,v| -@totals[k] }.each do |klass_method, calls|
76
+ total = @totals[klass_method]
77
+ puts "%s: (%d)" % [klass_method, total]
78
+ calls.sort_by { |k,v| -v }.each do |call, count|
79
+ puts " %4d: %s" % [count, call]
80
+ end
81
+
82
+ current += total
83
+ break if current >= max
84
+ end
85
+ rescue
86
+ # do nothing
87
+ end
88
+
89
+ def add_to_score(name, score)
90
+ @totals["#{@klass_name}##{@method_name}"] += score * @multiplier
91
+ @calls["#{@klass_name}##{@method_name}"][name] += score * @multiplier
92
+ end
93
+
94
+ def bad_dog! bonus
95
+ @multiplier += bonus
96
+ yield
97
+ @multiplier -= bonus
98
+ end
99
+
100
+ ############################################################
101
+ # Process Methods:
102
+
103
+ def process_alias(exp)
104
+ process exp.shift
105
+ process exp.shift
106
+ add_to_score :alias, 2
107
+ s()
108
+ end
109
+
110
+ # [:block_pass, [:lit, :blah], [:fcall, :foo]]
111
+ def process_block_pass(exp)
112
+ arg = exp.shift
113
+ call = exp.shift
114
+
115
+ case arg.first
116
+ when :iter then
117
+ add_to_score :to_proc_iter_wtf?, 6
118
+ when :lit, :call, :iter then
119
+ add_to_score :to_proc, 3
120
+ when :lvar, :dvar, :ivar, :nil then
121
+ # do nothing
122
+ else
123
+ raise({:block_pass => [call, arg]}.inspect)
124
+ end
125
+
126
+ call = process call
127
+ s()
128
+ end
129
+
130
+ def process_call(exp)
131
+ bad_dog! 0.2 do
132
+ recv = process exp.shift
133
+ end
134
+ name = exp.shift
135
+ bad_dog! 0.2 do
136
+ args = process exp.shift
137
+ end
138
+
139
+ score = SCORES[name]
140
+ add_to_score name, score
141
+
142
+ s()
143
+ end
144
+
145
+ def process_class(exp)
146
+ @klass_name = exp.shift
147
+ bad_dog! 1.0 do
148
+ supr = process exp.shift
149
+ end
150
+ until exp.empty?
151
+ process exp.shift
152
+ end
153
+ @klass_name = @@no_class
154
+ s()
155
+ end
156
+
157
+ def process_defn(exp)
158
+ @method_name = exp.shift
159
+ process exp.shift until exp.empty?
160
+ @method_name = @@no_method
161
+ s()
162
+ end
163
+
164
+ def process_defs(exp)
165
+ process exp.shift
166
+ @method_name = exp.shift
167
+ process exp.shift until exp.empty?
168
+ @method_name = @@no_method
169
+ s()
170
+ end
171
+
172
+ def process_lit(exp)
173
+ value = exp.shift
174
+ case value
175
+ when 0, -1 then
176
+ # ignore those because they're used as array indicies instead of first/last
177
+ when Integer then
178
+ add_to_score :lit_fixnum, 0.25
179
+ when Float, Symbol, Regexp, Range then
180
+ # do nothing
181
+ else
182
+ raise value.inspect
183
+ end
184
+ s()
185
+ end
186
+
187
+ def process_module(exp)
188
+ @klass_name = exp.shift
189
+ until exp.empty?
190
+ process exp.shift
191
+ end
192
+ @klass_name = @@no_class
193
+ s()
194
+ end
195
+
196
+ def process_sclass(exp)
197
+ bad_dog! 0.5 do
198
+ recv = process exp.shift
199
+ process exp.shift until exp.empty?
200
+ end
201
+
202
+ add_to_score :sclass, 5
203
+ s()
204
+ end
205
+ end
206
+
207
+ if $0 == __FILE__ then
208
+ flogger = Flog.new
209
+ flogger.process_files ARGV
210
+ flogger.report
211
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: flog
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2007-08-01 00:00:00 -07:00
8
+ summary: Flog reports the most tortured code in an easy to read pain report. The higher the score, the more pain the code is in.
9
+ require_paths:
10
+ - lib
11
+ email: ryand-ruby@zenspider.com
12
+ homepage: http://rubyforge.org/projects/seattlerb
13
+ rubyforge_project: seattlerb
14
+ description: "Flog reports the most tortured code in an easy to read pain report. The higher the score, the more pain the code is in. % ./bin/flog bin/flog Total score = 128.7 Flog#report: (21) 4: puts 2: sort_by ..."
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Ryan Davis
31
+ files:
32
+ - History.txt
33
+ - Manifest.txt
34
+ - README.txt
35
+ - Rakefile
36
+ - bin/flog
37
+ test_files: []
38
+
39
+ rdoc_options:
40
+ - --main
41
+ - README.txt
42
+ extra_rdoc_files:
43
+ - History.txt
44
+ - Manifest.txt
45
+ - README.txt
46
+ executables:
47
+ - flog
48
+ extensions: []
49
+
50
+ requirements: []
51
+
52
+ dependencies:
53
+ - !ruby/object:Gem::Dependency
54
+ name: hoe
55
+ version_requirement:
56
+ version_requirements: !ruby/object:Gem::Version::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 1.2.2
61
+ version: