metric_fu 2.0.0 → 2.0.1
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.
- data/HISTORY +13 -5
- data/README +2 -2
- data/Rakefile +1 -1
- data/TODO +3 -1
- data/lib/base/base_template.rb +16 -16
- data/lib/base/churn_analyzer.rb +3 -3
- data/lib/base/code_issue.rb +8 -8
- data/lib/base/configuration.rb +24 -22
- data/lib/base/flay_analyzer.rb +2 -2
- data/lib/base/flog_analyzer.rb +4 -4
- data/lib/base/generator.rb +21 -21
- data/lib/base/graph.rb +15 -10
- data/lib/base/line_numbers.rb +56 -55
- data/lib/base/location.rb +68 -66
- data/lib/base/metric_analyzer.rb +21 -21
- data/lib/base/ranking.rb +23 -22
- data/lib/base/rcov_analyzer.rb +3 -3
- data/lib/base/reek_analyzer.rb +12 -10
- data/lib/base/report.rb +9 -9
- data/lib/base/roodi_analyzer.rb +2 -2
- data/lib/base/saikuro_analyzer.rb +4 -4
- data/lib/base/scoring_strategies.rb +5 -5
- data/lib/base/stats_analyzer.rb +2 -2
- data/lib/base/table.rb +4 -4
- data/lib/generators/churn.rb +1 -1
- data/lib/generators/flay.rb +1 -1
- data/lib/generators/hotspots.rb +4 -4
- data/lib/generators/rails_best_practices.rb +1 -1
- data/lib/generators/rcov.rb +17 -17
- data/lib/generators/reek.rb +2 -2
- data/lib/generators/saikuro.rb +42 -42
- data/lib/generators/stats.rb +6 -6
- data/lib/graphs/engines/bluff.rb +1 -1
- data/lib/graphs/engines/gchart.rb +7 -7
- data/lib/graphs/flog_grapher.rb +3 -3
- data/lib/graphs/grapher.rb +1 -1
- data/lib/metric_fu.rb +2 -2
- data/lib/templates/awesome/churn.html.erb +1 -1
- data/lib/templates/awesome/css/integrity.css +0 -1
- data/lib/templates/awesome/flay.html.erb +2 -2
- data/lib/templates/awesome/flog.html.erb +2 -2
- data/lib/templates/awesome/hotspots.html.erb +4 -4
- data/lib/templates/awesome/index.html.erb +2 -2
- data/lib/templates/awesome/rails_best_practices.html.erb +1 -1
- data/lib/templates/awesome/rcov.html.erb +1 -1
- data/lib/templates/awesome/roodi.html.erb +1 -1
- data/lib/templates/awesome/saikuro.html.erb +3 -3
- data/lib/templates/awesome/stats.html.erb +1 -1
- data/lib/templates/standard/churn.html.erb +2 -2
- data/lib/templates/standard/default.css +4 -4
- data/lib/templates/standard/flay.html.erb +4 -4
- data/lib/templates/standard/flog.html.erb +1 -1
- data/lib/templates/standard/hotspots.html.erb +4 -4
- data/lib/templates/standard/index.html.erb +2 -2
- data/lib/templates/standard/rails_best_practices.html.erb +2 -2
- data/lib/templates/standard/rcov.html.erb +2 -2
- data/lib/templates/standard/reek.html.erb +1 -1
- data/lib/templates/standard/roodi.html.erb +2 -2
- data/lib/templates/standard/saikuro.html.erb +4 -4
- data/lib/templates/standard/stats.html.erb +2 -2
- data/spec/base/base_template_spec.rb +1 -1
- data/spec/base/configuration_spec.rb +36 -36
- data/spec/base/generator_spec.rb +10 -10
- data/spec/base/graph_spec.rb +41 -4
- data/spec/base/line_numbers_spec.rb +22 -22
- data/spec/base/report_spec.rb +9 -9
- data/spec/generators/churn_spec.rb +4 -4
- data/spec/generators/flay_spec.rb +31 -31
- data/spec/generators/flog_spec.rb +18 -18
- data/spec/generators/rails_best_practices_spec.rb +6 -6
- data/spec/generators/rcov_spec.rb +18 -18
- data/spec/generators/reek_spec.rb +10 -10
- data/spec/generators/roodi_spec.rb +2 -2
- data/spec/generators/saikuro_spec.rb +7 -7
- data/spec/generators/stats_spec.rb +6 -6
- data/spec/graphs/engines/gchart_spec.rb +8 -8
- data/spec/graphs/flog_grapher_spec.rb +8 -8
- data/spec/resources/line_numbers/foo.rb +7 -7
- data/spec/resources/line_numbers/module.rb +2 -2
- data/spec/resources/line_numbers/module_surrounds_class.rb +6 -6
- data/spec/resources/saikuro/index_cyclo.html +2 -2
- data/spec/resources/yml/20090630.yml +349 -349
- data/spec/resources/yml/metric_missing.yml +1 -1
- data/tasks/metric_fu.rake +4 -4
- metadata +4 -4
data/lib/generators/reek.rb
CHANGED
data/lib/generators/saikuro.rb
CHANGED
@@ -1,34 +1,34 @@
|
|
1
1
|
module MetricFu
|
2
|
-
|
2
|
+
|
3
3
|
class Saikuro < Generator
|
4
4
|
|
5
|
-
def emit
|
6
|
-
options_string = MetricFu.saikuro.inject("") do |options, option|
|
7
|
-
options + "--#{option.join(' ')} " unless option == :input_directory
|
8
|
-
end
|
9
|
-
|
10
|
-
MetricFu.saikuro[:input_directory].each do |input_dir|
|
11
|
-
options_string += "--input_directory #{input_dir} "
|
12
|
-
end
|
13
|
-
sh %{saikuro #{options_string}} do |ok, response|
|
14
|
-
unless ok
|
15
|
-
puts "Saikuro failed with exit status: #{response.exitstatus}"
|
16
|
-
exit 1
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
5
|
+
def emit
|
6
|
+
options_string = MetricFu.saikuro.inject("") do |options, option|
|
7
|
+
options + "--#{option.join(' ')} " unless option == :input_directory
|
8
|
+
end
|
9
|
+
|
10
|
+
MetricFu.saikuro[:input_directory].each do |input_dir|
|
11
|
+
options_string += "--input_directory #{input_dir} "
|
12
|
+
end
|
13
|
+
sh %{saikuro #{options_string}} do |ok, response|
|
14
|
+
unless ok
|
15
|
+
puts "Saikuro failed with exit status: #{response.exitstatus}"
|
16
|
+
exit 1
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
20
|
|
21
21
|
def format_directories
|
22
22
|
dirs = MetricFu.saikuro[:input_directory].join(" | ")
|
23
23
|
"\"#{dirs}\""
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def analyze
|
27
27
|
@files = sort_files(assemble_files)
|
28
28
|
@classes = sort_classes(assemble_classes(@files))
|
29
29
|
@meths = sort_methods(assemble_methods(@files))
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def to_h
|
33
33
|
files = @files.map do |file|
|
34
34
|
my_file = file.to_h
|
@@ -41,12 +41,12 @@ module MetricFu
|
|
41
41
|
}
|
42
42
|
}
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
private
|
46
46
|
def sort_methods(methods)
|
47
47
|
methods.sort_by {|method| method.complexity.to_i}.reverse
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
def assemble_methods(files)
|
51
51
|
methods = []
|
52
52
|
files.each do |file|
|
@@ -59,15 +59,15 @@ module MetricFu
|
|
59
59
|
end
|
60
60
|
methods
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
def sort_classes(classes)
|
64
64
|
classes.sort_by {|k| k.complexity.to_i}.reverse
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
def assemble_classes(files)
|
68
68
|
files.map {|f| f.elements}.flatten
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
def sort_files(files)
|
72
72
|
files.sort_by do |file|
|
73
73
|
file.elements.
|
@@ -75,7 +75,7 @@ module MetricFu
|
|
75
75
|
complexity.to_i
|
76
76
|
end.reverse
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
def assemble_files
|
80
80
|
files = []
|
81
81
|
Dir.glob("#{metric_directory}/**/*.html").each do |path|
|
@@ -88,11 +88,11 @@ module MetricFu
|
|
88
88
|
end
|
89
89
|
files
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
end
|
93
|
-
|
93
|
+
|
94
94
|
class Saikuro::SFile
|
95
|
-
|
95
|
+
|
96
96
|
attr_reader :elements
|
97
97
|
|
98
98
|
def initialize(path)
|
@@ -103,7 +103,7 @@ module MetricFu
|
|
103
103
|
ensure
|
104
104
|
@file_handle.close if @file_handle
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
def self.is_valid_text_file?(path)
|
108
108
|
File.open(path, "r") do |f|
|
109
109
|
if f.eof? || !f.readline.match(/--/)
|
@@ -113,16 +113,16 @@ module MetricFu
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
end
|
116
|
-
|
116
|
+
|
117
117
|
def filename
|
118
118
|
File.basename(@path, '_cyclo.html')
|
119
119
|
end
|
120
|
-
|
120
|
+
|
121
121
|
def to_h
|
122
122
|
merge_classes
|
123
123
|
{:classes => @elements}
|
124
124
|
end
|
125
|
-
|
125
|
+
|
126
126
|
def get_elements
|
127
127
|
begin
|
128
128
|
while (line = @file_handle.readline) do
|
@@ -146,8 +146,8 @@ module MetricFu
|
|
146
146
|
nil
|
147
147
|
end
|
148
148
|
end
|
149
|
-
|
150
|
-
|
149
|
+
|
150
|
+
|
151
151
|
def merge_classes
|
152
152
|
new_elements = []
|
153
153
|
get_class_names.each do |target_class|
|
@@ -160,7 +160,7 @@ module MetricFu
|
|
160
160
|
lines += el.lines.to_i
|
161
161
|
defns << el.defs
|
162
162
|
end
|
163
|
-
|
163
|
+
|
164
164
|
new_element = {:class_name => target_class,
|
165
165
|
:complexity => complexity,
|
166
166
|
:lines => lines,
|
@@ -168,12 +168,12 @@ module MetricFu
|
|
168
168
|
new_element[:methods] = new_element[:methods].
|
169
169
|
sort_by {|x| x[:complexity] }.
|
170
170
|
reverse
|
171
|
-
|
171
|
+
|
172
172
|
new_elements << new_element
|
173
173
|
end
|
174
174
|
@elements = new_elements if new_elements
|
175
175
|
end
|
176
|
-
|
176
|
+
|
177
177
|
def get_class_names
|
178
178
|
class_names = []
|
179
179
|
@elements.each do |element|
|
@@ -183,18 +183,18 @@ module MetricFu
|
|
183
183
|
end
|
184
184
|
class_names
|
185
185
|
end
|
186
|
-
|
186
|
+
|
187
187
|
end
|
188
|
-
|
188
|
+
|
189
189
|
class Saikuro::ParsingElement
|
190
190
|
TYPE_REGEX=/Type:(.*) Name/
|
191
191
|
NAME_REGEX=/Name:(.*) Complexity/
|
192
192
|
COMPLEXITY_REGEX=/Complexity:(.*) Lines/
|
193
193
|
LINES_REGEX=/Lines:(.*)/
|
194
|
-
|
194
|
+
|
195
195
|
attr_reader :complexity, :lines, :defs, :element_type
|
196
196
|
attr_accessor :name
|
197
|
-
|
197
|
+
|
198
198
|
def initialize(line)
|
199
199
|
@line = line
|
200
200
|
@element_type = line.match(TYPE_REGEX)[1].strip
|
@@ -203,11 +203,11 @@ module MetricFu
|
|
203
203
|
@lines = line.match(LINES_REGEX)[1].strip
|
204
204
|
@defs = []
|
205
205
|
end
|
206
|
-
|
206
|
+
|
207
207
|
def <<(line)
|
208
208
|
@defs << Saikuro::ParsingElement.new(line)
|
209
209
|
end
|
210
|
-
|
210
|
+
|
211
211
|
def to_h
|
212
212
|
base = {:name => @name, :complexity => @complexity.to_i, :lines => @lines.to_i}
|
213
213
|
unless @defs.empty?
|
data/lib/generators/stats.rb
CHANGED
@@ -11,7 +11,7 @@ module MetricFu
|
|
11
11
|
lines = remove_noise(output)
|
12
12
|
|
13
13
|
@stats = {}
|
14
|
-
|
14
|
+
|
15
15
|
set_global_stats(lines.pop)
|
16
16
|
set_granular_stats(lines)
|
17
17
|
|
@@ -21,9 +21,9 @@ module MetricFu
|
|
21
21
|
def to_h
|
22
22
|
{:stats => @stats}
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
private
|
26
|
-
|
26
|
+
|
27
27
|
def remove_noise(output)
|
28
28
|
lines = output.split("\n")
|
29
29
|
lines = lines.find_all {|line| line[0].chr != "+" }
|
@@ -31,14 +31,14 @@ module MetricFu
|
|
31
31
|
lines.shift
|
32
32
|
lines
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
def set_global_stats(totals)
|
36
36
|
totals = totals.split(" ").find_all {|el| ! el.empty? }
|
37
37
|
@stats[:codeLOC] = totals[0].match(/\d.*/)[0].to_i
|
38
38
|
@stats[:testLOC] = totals[1].match(/\d.*/)[0].to_i
|
39
39
|
@stats[:code_to_test_ratio] = totals[2].match(/1\:(\d.*)/)[1].to_f
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
def set_granular_stats(lines)
|
43
43
|
@stats[:lines] = lines.map do |line|
|
44
44
|
elements = line.split("|")
|
@@ -47,7 +47,7 @@ module MetricFu
|
|
47
47
|
info_line = {}
|
48
48
|
info_line[:name] = elements.shift
|
49
49
|
elements.map! {|el| el.to_i }
|
50
|
-
[:lines, :loc, :classes, :methods,
|
50
|
+
[:lines, :loc, :classes, :methods,
|
51
51
|
:methods_per_class, :loc_per_method].each do |sym|
|
52
52
|
info_line[sym] = elements.shift
|
53
53
|
end
|
data/lib/graphs/engines/bluff.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module MetricFu
|
2
2
|
module GchartGrapher
|
3
|
-
COLORS = %w{009999 FF7400 A60000 008500 E6399B 344AD7 00B860 D5CCB9}
|
3
|
+
COLORS = %w{009999 FF7400 A60000 008500 E6399B 344AD7 00B860 D5CCB9}
|
4
4
|
GCHART_GRAPH_SIZE = "945x317" # maximum permitted image size is 300000 pixels
|
5
|
-
|
5
|
+
|
6
6
|
NUMBER_OF_TICKS = 6
|
7
7
|
def determine_y_axis_scale(values)
|
8
8
|
values.collect! {|val| val || 0.0 }
|
@@ -18,10 +18,10 @@ module MetricFu
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
class Grapher
|
23
23
|
include MetricFu::GchartGrapher
|
24
|
-
|
24
|
+
|
25
25
|
def self.require_graphing_gem
|
26
26
|
require 'gchart' if MetricFu.graph_engine == :gchart
|
27
27
|
rescue LoadError
|
@@ -64,7 +64,7 @@ module MetricFu
|
|
64
64
|
:filename => File.join(MetricFu.output_directory, 'flog.png'))
|
65
65
|
end
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
class RcovGchartGrapher < RcovGrapher
|
69
69
|
def graph!
|
70
70
|
url = Gchart.line(
|
@@ -86,7 +86,7 @@ module MetricFu
|
|
86
86
|
values = []
|
87
87
|
legend = @reek_count.keys.sort
|
88
88
|
legend.collect {|k| values << @reek_count[k]}
|
89
|
-
|
89
|
+
|
90
90
|
url = Gchart.line(
|
91
91
|
:size => GCHART_GRAPH_SIZE,
|
92
92
|
:title => URI.escape("Reek: code smells"),
|
@@ -102,7 +102,7 @@ module MetricFu
|
|
102
102
|
:filename => File.join(MetricFu.output_directory, 'reek.png'))
|
103
103
|
end
|
104
104
|
end
|
105
|
-
|
105
|
+
|
106
106
|
class RoodiGchartGrapher < RoodiGrapher
|
107
107
|
def graph!
|
108
108
|
determine_y_axis_scale(@roodi_count)
|
data/lib/graphs/flog_grapher.rb
CHANGED
@@ -21,8 +21,8 @@ module MetricFu
|
|
21
21
|
|
22
22
|
def calc_top_five_percent_average(metrics)
|
23
23
|
return calc_top_five_percent_average_legacy(metrics) if metrics[:flog][:pages]
|
24
|
-
|
25
|
-
method_scores = metrics[:flog][:method_containers].inject([]) do |method_scores, container|
|
24
|
+
|
25
|
+
method_scores = metrics[:flog][:method_containers].inject([]) do |method_scores, container|
|
26
26
|
method_scores += container[:methods].values.map {|v| v[:score]}
|
27
27
|
end
|
28
28
|
method_scores.sort!.reverse!
|
@@ -37,7 +37,7 @@ module MetricFu
|
|
37
37
|
total_for_five_percent / number_of_methods_that_is_five_percent.to_f
|
38
38
|
end
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
def calc_top_five_percent_average_legacy(metrics)
|
42
42
|
methods = metrics[:flog][:pages].inject([]) {|methods, page| methods << page[:scanned_methods]}
|
43
43
|
methods.flatten!
|
data/lib/graphs/grapher.rb
CHANGED
data/lib/metric_fu.rb
CHANGED
@@ -3,7 +3,7 @@ require 'yaml'
|
|
3
3
|
begin
|
4
4
|
require 'active_support/core_ext/object/to_json'
|
5
5
|
require 'active_support/core_ext/object/blank'
|
6
|
-
rescue LoadError
|
6
|
+
rescue LoadError
|
7
7
|
require 'activesupport'
|
8
8
|
end
|
9
9
|
|
@@ -18,7 +18,7 @@ graph_dir = File.join(MetricFu::LIB_ROOT, 'graphs')
|
|
18
18
|
|
19
19
|
# We need to require these two things first because our other classes
|
20
20
|
# depend on them.
|
21
|
-
require File.join(base_dir, 'report')
|
21
|
+
require File.join(base_dir, 'report')
|
22
22
|
require File.join(base_dir, 'generator')
|
23
23
|
require File.join(base_dir, 'graph')
|
24
24
|
require File.join(base_dir, 'scoring_strategies')
|
@@ -16,7 +16,7 @@
|
|
16
16
|
<table>
|
17
17
|
<tr>
|
18
18
|
<th>Files</th>
|
19
|
-
<th>Matches</th>
|
19
|
+
<th>Matches</th>
|
20
20
|
</tr>
|
21
21
|
<% count = 0 %>
|
22
22
|
<% @flay[:matches].each do |match| %>
|
@@ -31,4 +31,4 @@
|
|
31
31
|
<% count += 1 %>
|
32
32
|
<% end %>
|
33
33
|
</table>
|
34
|
-
<p>Generated on <%= Time.now.localtime %></p>
|
34
|
+
<p>Generated on <%= Time.now.localtime %></p>
|
@@ -33,7 +33,7 @@
|
|
33
33
|
|
34
34
|
<% @flog[:method_containers].each do |method_container| %>
|
35
35
|
<h2 id="<%= method_container[:path].gsub(/[^a-z]+/, '_') %>"><%= link_to_filename(method_container[:path]) %></h2>
|
36
|
-
|
36
|
+
|
37
37
|
<% method_container[:methods].each do |full_method_name, method_info| %>
|
38
38
|
<% path, line = method_info[:path].split(":") if method_info[:path] %>
|
39
39
|
<p><%= link_to_filename(path, line, full_method_name) %></p>
|
@@ -52,4 +52,4 @@
|
|
52
52
|
</table>
|
53
53
|
<% end %>
|
54
54
|
<% end %>
|
55
|
-
<p>Generated on <%= Time.now.localtime %></p>
|
55
|
+
<p>Generated on <%= Time.now.localtime %></p>
|
@@ -9,8 +9,8 @@ No Hotspots were found.
|
|
9
9
|
<% granularities = [:files, :classes, :methods] %>
|
10
10
|
<table>
|
11
11
|
<tr valign="top">
|
12
|
-
<% granularities.each do |granularity| %>
|
13
|
-
<th width='33%'>
|
12
|
+
<% granularities.each do |granularity| %>
|
13
|
+
<th width='33%'>
|
14
14
|
<%= granularity.to_s.capitalize %></th>
|
15
15
|
<% end %>
|
16
16
|
</tr>
|
@@ -24,7 +24,7 @@ No Hotspots were found.
|
|
24
24
|
<% items_length = 0 %>
|
25
25
|
<% columns = [0, 1, 2] %>
|
26
26
|
<% while (items_length < items[0].length || items_length < items[1].length || items_length < items[2].length) do %>
|
27
|
-
<tr valign="top">
|
27
|
+
<tr valign="top">
|
28
28
|
<% columns.each do |column| %>
|
29
29
|
<% item = items[column].length >= items_length ? items[column][items_length] : nil %>
|
30
30
|
<% if item %>
|
@@ -51,4 +51,4 @@ No Hotspots were found.
|
|
51
51
|
<% end %>
|
52
52
|
|
53
53
|
|
54
|
-
<p>Generated on <%= Time.now.localtime %></p>
|
54
|
+
<p>Generated on <%= Time.now.localtime %></p>
|
@@ -23,7 +23,7 @@
|
|
23
23
|
<% end %>
|
24
24
|
<% if @stats %>
|
25
25
|
<li class='even failure'><a href="stats.html">Stats</a></li>
|
26
|
-
<% end %>
|
26
|
+
<% end %>
|
27
27
|
<% if @rails_best_practices %>
|
28
28
|
<li class='even failure'><a href="rails_best_practices.html">Rails Best Practices report</a></li>
|
29
29
|
<% end %>
|
@@ -31,4 +31,4 @@
|
|
31
31
|
<li class='even failure'><a href="hotspots.html">Hotspots</a></li>
|
32
32
|
<% end %>
|
33
33
|
</ul>
|
34
|
-
<p>Generated on <%= Time.now.localtime %></p>
|
34
|
+
<p>Generated on <%= Time.now.localtime %></p>
|