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.
Files changed (85) hide show
  1. data/HISTORY +13 -5
  2. data/README +2 -2
  3. data/Rakefile +1 -1
  4. data/TODO +3 -1
  5. data/lib/base/base_template.rb +16 -16
  6. data/lib/base/churn_analyzer.rb +3 -3
  7. data/lib/base/code_issue.rb +8 -8
  8. data/lib/base/configuration.rb +24 -22
  9. data/lib/base/flay_analyzer.rb +2 -2
  10. data/lib/base/flog_analyzer.rb +4 -4
  11. data/lib/base/generator.rb +21 -21
  12. data/lib/base/graph.rb +15 -10
  13. data/lib/base/line_numbers.rb +56 -55
  14. data/lib/base/location.rb +68 -66
  15. data/lib/base/metric_analyzer.rb +21 -21
  16. data/lib/base/ranking.rb +23 -22
  17. data/lib/base/rcov_analyzer.rb +3 -3
  18. data/lib/base/reek_analyzer.rb +12 -10
  19. data/lib/base/report.rb +9 -9
  20. data/lib/base/roodi_analyzer.rb +2 -2
  21. data/lib/base/saikuro_analyzer.rb +4 -4
  22. data/lib/base/scoring_strategies.rb +5 -5
  23. data/lib/base/stats_analyzer.rb +2 -2
  24. data/lib/base/table.rb +4 -4
  25. data/lib/generators/churn.rb +1 -1
  26. data/lib/generators/flay.rb +1 -1
  27. data/lib/generators/hotspots.rb +4 -4
  28. data/lib/generators/rails_best_practices.rb +1 -1
  29. data/lib/generators/rcov.rb +17 -17
  30. data/lib/generators/reek.rb +2 -2
  31. data/lib/generators/saikuro.rb +42 -42
  32. data/lib/generators/stats.rb +6 -6
  33. data/lib/graphs/engines/bluff.rb +1 -1
  34. data/lib/graphs/engines/gchart.rb +7 -7
  35. data/lib/graphs/flog_grapher.rb +3 -3
  36. data/lib/graphs/grapher.rb +1 -1
  37. data/lib/metric_fu.rb +2 -2
  38. data/lib/templates/awesome/churn.html.erb +1 -1
  39. data/lib/templates/awesome/css/integrity.css +0 -1
  40. data/lib/templates/awesome/flay.html.erb +2 -2
  41. data/lib/templates/awesome/flog.html.erb +2 -2
  42. data/lib/templates/awesome/hotspots.html.erb +4 -4
  43. data/lib/templates/awesome/index.html.erb +2 -2
  44. data/lib/templates/awesome/rails_best_practices.html.erb +1 -1
  45. data/lib/templates/awesome/rcov.html.erb +1 -1
  46. data/lib/templates/awesome/roodi.html.erb +1 -1
  47. data/lib/templates/awesome/saikuro.html.erb +3 -3
  48. data/lib/templates/awesome/stats.html.erb +1 -1
  49. data/lib/templates/standard/churn.html.erb +2 -2
  50. data/lib/templates/standard/default.css +4 -4
  51. data/lib/templates/standard/flay.html.erb +4 -4
  52. data/lib/templates/standard/flog.html.erb +1 -1
  53. data/lib/templates/standard/hotspots.html.erb +4 -4
  54. data/lib/templates/standard/index.html.erb +2 -2
  55. data/lib/templates/standard/rails_best_practices.html.erb +2 -2
  56. data/lib/templates/standard/rcov.html.erb +2 -2
  57. data/lib/templates/standard/reek.html.erb +1 -1
  58. data/lib/templates/standard/roodi.html.erb +2 -2
  59. data/lib/templates/standard/saikuro.html.erb +4 -4
  60. data/lib/templates/standard/stats.html.erb +2 -2
  61. data/spec/base/base_template_spec.rb +1 -1
  62. data/spec/base/configuration_spec.rb +36 -36
  63. data/spec/base/generator_spec.rb +10 -10
  64. data/spec/base/graph_spec.rb +41 -4
  65. data/spec/base/line_numbers_spec.rb +22 -22
  66. data/spec/base/report_spec.rb +9 -9
  67. data/spec/generators/churn_spec.rb +4 -4
  68. data/spec/generators/flay_spec.rb +31 -31
  69. data/spec/generators/flog_spec.rb +18 -18
  70. data/spec/generators/rails_best_practices_spec.rb +6 -6
  71. data/spec/generators/rcov_spec.rb +18 -18
  72. data/spec/generators/reek_spec.rb +10 -10
  73. data/spec/generators/roodi_spec.rb +2 -2
  74. data/spec/generators/saikuro_spec.rb +7 -7
  75. data/spec/generators/stats_spec.rb +6 -6
  76. data/spec/graphs/engines/gchart_spec.rb +8 -8
  77. data/spec/graphs/flog_grapher_spec.rb +8 -8
  78. data/spec/resources/line_numbers/foo.rb +7 -7
  79. data/spec/resources/line_numbers/module.rb +2 -2
  80. data/spec/resources/line_numbers/module_surrounds_class.rb +6 -6
  81. data/spec/resources/saikuro/index_cyclo.html +2 -2
  82. data/spec/resources/yml/20090630.yml +349 -349
  83. data/spec/resources/yml/metric_missing.yml +1 -1
  84. data/tasks/metric_fu.rake +4 -4
  85. metadata +4 -4
@@ -1,8 +1,8 @@
1
1
  module MetricFu
2
-
2
+
3
3
  class Reek < Generator
4
4
  REEK_REGEX = /^(\S+) (.*) \((.*)\)$/
5
-
5
+
6
6
  def emit
7
7
  files_to_reek = MetricFu.reek[:dirs_to_reek].map{|dir| Dir[File.join(dir, "**/*.rb")] }
8
8
  files = remove_excluded_files(files_to_reek.flatten)
@@ -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?
@@ -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
@@ -12,7 +12,7 @@ module MetricFu
12
12
  g.marker_font_size = "10px"
13
13
  EOS
14
14
  end
15
-
15
+
16
16
  class FlayBluffGrapher < FlayGrapher
17
17
  def graph!
18
18
  content = <<-EOS
@@ -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)
@@ -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!
@@ -3,7 +3,7 @@ module MetricFu
3
3
  def initialize
4
4
  self.class.require_graphing_gem
5
5
  end
6
-
6
+
7
7
  def self.require_graphing_gem
8
8
  # to be overridden by charting engines
9
9
  end
@@ -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')
@@ -55,4 +55,4 @@
55
55
 
56
56
 
57
57
 
58
- <p>Generated on <%= Time.now.localtime %></p>
58
+ <p>Generated on <%= Time.now.localtime %></p>
@@ -332,4 +332,3 @@ a.failed {
332
332
  text-align: right; }
333
333
  #footer strong {
334
334
  font-weight: bold; }
335
-
@@ -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>