metric_fu 4.4.4 → 4.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. checksums.yaml +14 -6
  2. checksums.yaml.gz.sig +3 -0
  3. data.tar.gz.sig +0 -0
  4. data/.gitignore +1 -0
  5. data/.metrics +0 -3
  6. data/.travis.yml +1 -1
  7. data/.yardopts +0 -1
  8. data/CONTRIBUTING.md +1 -0
  9. data/CONTRIBUTORS +61 -2
  10. data/Gemfile +14 -11
  11. data/Gemfile.devtools +40 -0
  12. data/Guardfile +30 -0
  13. data/HISTORY.md +54 -1
  14. data/README.md +86 -56
  15. data/bin/mf-cane +8 -6
  16. data/bin/mf-churn +8 -7
  17. data/bin/mf-flay +8 -7
  18. data/bin/mf-reek +8 -7
  19. data/bin/mf-roodi +8 -7
  20. data/bin/mf-saikuro +8 -6
  21. data/certs/bf4.pem +22 -0
  22. data/checksum/metric_fu-4.4.4.gem.sha512 +1 -0
  23. data/checksum/metric_fu-4.5.0.gem.sha512 +1 -0
  24. data/etc/README.md +16 -0
  25. data/etc/erd.dot +173 -0
  26. data/etc/erd.png +0 -0
  27. data/lib/metric_fu.rb +56 -12
  28. data/lib/metric_fu/cli/helper.rb +8 -2
  29. data/lib/metric_fu/cli/parser.rb +86 -50
  30. data/lib/metric_fu/configuration.rb +4 -31
  31. data/lib/metric_fu/environment.rb +1 -1
  32. data/lib/metric_fu/formatter/html.rb +5 -5
  33. data/lib/metric_fu/gem_run.rb +68 -0
  34. data/lib/metric_fu/gem_version.rb +57 -0
  35. data/lib/metric_fu/io.rb +1 -1
  36. data/lib/metric_fu/load_files.rb +3 -5
  37. data/lib/metric_fu/loader.rb +31 -2
  38. data/lib/metric_fu/logging/mf_debugger.rb +1 -0
  39. data/lib/metric_fu/metric.rb +23 -1
  40. data/lib/metric_fu/metrics/cane/cane.rb +7 -3
  41. data/lib/metric_fu/metrics/cane/cane_grapher.rb +19 -0
  42. data/lib/metric_fu/metrics/cane/template_awesome/cane.html.erb +0 -4
  43. data/lib/metric_fu/metrics/churn/churn.rb +6 -7
  44. data/lib/metric_fu/metrics/flay/flay.rb +2 -4
  45. data/lib/metric_fu/metrics/flay/flay_grapher.rb +19 -0
  46. data/lib/metric_fu/metrics/flay/template_awesome/flay.html.erb +0 -4
  47. data/lib/metric_fu/metrics/flog/flog.rb +0 -2
  48. data/lib/metric_fu/metrics/flog/flog_grapher.rb +19 -0
  49. data/lib/metric_fu/metrics/flog/template_awesome/flog.html.erb +0 -4
  50. data/lib/metric_fu/metrics/generator.rb +34 -24
  51. data/lib/metric_fu/metrics/graph.rb +8 -14
  52. data/lib/metric_fu/metrics/hotspots/hotspot.rb +7 -5
  53. data/lib/metric_fu/metrics/hotspots/template_awesome/hotspots.html.erb +4 -6
  54. data/lib/metric_fu/metrics/rails_best_practices/rails_best_practices.rb +0 -2
  55. data/lib/metric_fu/metrics/rails_best_practices/rails_best_practices_grapher.rb +19 -0
  56. data/lib/metric_fu/metrics/rails_best_practices/template_awesome/rails_best_practices.html.erb +0 -4
  57. data/lib/metric_fu/metrics/rcov/rcov_grapher.rb +19 -0
  58. data/lib/metric_fu/metrics/rcov/template_awesome/rcov.html.erb +0 -4
  59. data/lib/metric_fu/metrics/reek/init.rb +1 -1
  60. data/lib/metric_fu/metrics/reek/reek.rb +12 -8
  61. data/lib/metric_fu/metrics/reek/reek_grapher.rb +19 -0
  62. data/lib/metric_fu/metrics/reek/template_awesome/reek.html.erb +0 -4
  63. data/lib/metric_fu/metrics/roodi/roodi.rb +2 -3
  64. data/lib/metric_fu/metrics/roodi/roodi_grapher.rb +19 -0
  65. data/lib/metric_fu/metrics/roodi/template_awesome/roodi.html.erb +0 -4
  66. data/lib/metric_fu/metrics/saikuro/saikuro.rb +69 -33
  67. data/lib/metric_fu/metrics/saikuro/scratch_file.rb +8 -9
  68. data/lib/metric_fu/metrics/stats/stats_grapher.rb +20 -0
  69. data/lib/metric_fu/metrics/stats/template_awesome/stats.html.erb +0 -4
  70. data/lib/metric_fu/reporting/graphs/grapher.rb +69 -3
  71. data/lib/metric_fu/reporting/result.rb +5 -1
  72. data/lib/metric_fu/reporting/templates/awesome/awesome_template.rb +7 -3
  73. data/lib/metric_fu/run.rb +13 -7
  74. data/lib/metric_fu/tasks/metric_fu.rake +50 -3
  75. data/lib/metric_fu/utility.rb +10 -0
  76. data/lib/metric_fu/version.rb +1 -1
  77. data/metric_fu.gemspec +7 -4
  78. data/spec/dummy/.gitignore +1 -0
  79. data/spec/dummy/.gitkeep +0 -0
  80. data/spec/dummy/.metrics +4 -0
  81. data/spec/dummy/lib/.gitkeep +0 -0
  82. data/spec/dummy/spec/.gitkeep +0 -0
  83. data/spec/{resources/yml → fixtures}/20090630.yml +1 -1
  84. data/spec/{resources/yml → fixtures}/hotspots/flog.yml +0 -0
  85. data/spec/{resources/yml → fixtures}/hotspots/generator.yml +0 -0
  86. data/spec/{resources/yml → fixtures}/hotspots/generator_analysis.yml +0 -0
  87. data/spec/{resources/yml → fixtures}/hotspots/reek.yml +0 -0
  88. data/spec/{resources/yml → fixtures}/hotspots/roodi.yml +0 -0
  89. data/spec/{resources/yml → fixtures}/hotspots/saikuro.yml +0 -0
  90. data/spec/{resources/yml → fixtures}/hotspots/several_metrics.yml +0 -0
  91. data/spec/{resources/yml → fixtures}/hotspots/stats.yml +0 -0
  92. data/spec/{resources/yml → fixtures}/hotspots/three_metrics_on_same_file.yml +0 -0
  93. data/spec/{resources → fixtures}/line_numbers/foo.rb +0 -0
  94. data/spec/{resources → fixtures}/line_numbers/module.rb +0 -0
  95. data/spec/{resources → fixtures}/line_numbers/module_surrounds_class.rb +0 -0
  96. data/spec/{resources → fixtures}/line_numbers/two_classes.rb +0 -0
  97. data/spec/{resources/yml → fixtures}/metric_missing.yml +0 -0
  98. data/spec/{resources → fixtures}/saikuro/app/controllers/sessions_controller.rb_cyclo.html +0 -0
  99. data/spec/{resources → fixtures}/saikuro/app/controllers/users_controller.rb_cyclo.html +0 -0
  100. data/spec/{resources → fixtures}/saikuro/index_cyclo.html +0 -0
  101. data/spec/{resources → fixtures}/saikuro_sfiles/thing.rb_cyclo.html +0 -0
  102. data/spec/metric_fu/configuration_spec.rb +1 -1
  103. data/spec/metric_fu/data_structures/line_numbers_spec.rb +13 -11
  104. data/spec/metric_fu/formatter/html_spec.rb +2 -2
  105. data/spec/metric_fu/gem_version_spec.rb +14 -0
  106. data/spec/metric_fu/loader_spec.rb +12 -0
  107. data/spec/metric_fu/metrics/base_template_spec.rb +9 -7
  108. data/spec/metric_fu/metrics/cane/cane_spec.rb +7 -7
  109. data/spec/metric_fu/metrics/churn/churn_spec.rb +1 -1
  110. data/spec/metric_fu/metrics/flay/flay_grapher_spec.rb +2 -2
  111. data/spec/metric_fu/metrics/flay/flay_spec.rb +2 -2
  112. data/spec/metric_fu/metrics/flog/flog_grapher_spec.rb +3 -3
  113. data/spec/metric_fu/metrics/generator_spec.rb +1 -35
  114. data/spec/metric_fu/metrics/graph_spec.rb +7 -24
  115. data/spec/metric_fu/metrics/hotspots/analysis/analyzed_problems_spec.rb +2 -2
  116. data/spec/metric_fu/metrics/hotspots/analysis/analyzer_tables_spec.rb +2 -2
  117. data/spec/metric_fu/metrics/hotspots/analysis/rankings_spec.rb +5 -5
  118. data/spec/metric_fu/metrics/hotspots/hotspots_spec.rb +2 -3
  119. data/spec/metric_fu/metrics/rails_best_practices/rails_best_practices_grapher_spec.rb +2 -2
  120. data/spec/metric_fu/metrics/rails_best_practices/rails_best_practices_spec.rb +1 -1
  121. data/spec/metric_fu/metrics/rcov/rcov_grapher_spec.rb +2 -2
  122. data/spec/metric_fu/metrics/rcov/rcov_spec.rb +1 -4
  123. data/spec/metric_fu/metrics/reek/reek_grapher_spec.rb +2 -2
  124. data/spec/metric_fu/metrics/reek/reek_spec.rb +1 -1
  125. data/spec/metric_fu/metrics/roodi/roodi_grapher_spec.rb +2 -2
  126. data/spec/metric_fu/metrics/roodi/roodi_spec.rb +3 -3
  127. data/spec/metric_fu/metrics/saikuro/saikuro_spec.rb +14 -10
  128. data/spec/metric_fu/metrics/stats/stats_grapher_spec.rb +2 -2
  129. data/spec/metric_fu/reporting/graphs/{engines/bluff_spec.rb → grapher_spec.rb} +8 -2
  130. data/spec/{run_spec.rb → metric_fu/run_spec.rb} +8 -13
  131. data/spec/spec_helper.rb +30 -5
  132. data/spec/support/deferred_garbaged_collection.rb +34 -0
  133. data/spec/support/helper_methods.rb +1 -15
  134. data/spec/support/suite.rb +4 -24
  135. data/spec/support/test_fixtures.rb +39 -0
  136. data/spec/support/timeout.rb +7 -0
  137. metadata +129 -104
  138. metadata.gz.sig +1 -0
  139. data/lib/metric_fu/metrics/cane/cane_bluff_grapher.rb +0 -16
  140. data/lib/metric_fu/metrics/cane/cane_gchart_grapher.rb +0 -25
  141. data/lib/metric_fu/metrics/flay/flay_bluff_grapher.rb +0 -16
  142. data/lib/metric_fu/metrics/flay/flay_gchart_grapher.rb +0 -20
  143. data/lib/metric_fu/metrics/flog/flog_bluff_grapher.rb +0 -17
  144. data/lib/metric_fu/metrics/flog/flog_gchart_grapher.rb +0 -28
  145. data/lib/metric_fu/metrics/rails_best_practices/rails_best_practices_bluff_grapher.rb +0 -16
  146. data/lib/metric_fu/metrics/rails_best_practices/rails_best_practices_gchart_grapher.rb +0 -27
  147. data/lib/metric_fu/metrics/rcov/rcov_bluff_grapher.rb +0 -16
  148. data/lib/metric_fu/metrics/rcov/rcov_gchart_grapher.rb +0 -22
  149. data/lib/metric_fu/metrics/reek/reek_bluff_grapher.rb +0 -16
  150. data/lib/metric_fu/metrics/reek/reek_gchart_grapher.rb +0 -30
  151. data/lib/metric_fu/metrics/roodi/roodi_bluff_grapher.rb +0 -16
  152. data/lib/metric_fu/metrics/roodi/roodi_gchart_grapher.rb +0 -20
  153. data/lib/metric_fu/metrics/stats/stats_bluff_grapher.rb +0 -17
  154. data/lib/metric_fu/metrics/stats/stats_gchart_grapher.rb +0 -27
  155. data/lib/metric_fu/reporting/graphs/engines/bluff.rb +0 -33
  156. data/lib/metric_fu/reporting/graphs/engines/gchart.rb +0 -72
  157. data/lib/metric_fu/reporting/graphs/engines/init.rb +0 -19
  158. data/lib/metric_fu_requires.rb +0 -63
  159. data/spec/metric_fu/reporting/graphs/engines/gchart_spec.rb +0 -161
@@ -34,11 +34,9 @@ module MetricFu
34
34
  @rails_best_practices_results[:problems].each do |problem|
35
35
  next if problem[:file] == '' || problem[:problem].nil?
36
36
 
37
- out[problem[:file]] ||= {}
38
37
 
39
38
  lines = problem[:line].split(/\s*,\s*/)
40
39
  lines.each do |line|
41
- out[problem[:file]][line] ||= []
42
40
  out[problem[:file]][line] << {:type => :rails_best_practices, :description => problem[:problem]}
43
41
  end
44
42
  end
@@ -3,6 +3,10 @@ module MetricFu
3
3
  class RailsBestPracticesGrapher < Grapher
4
4
  attr_accessor :rails_best_practices_count, :labels
5
5
 
6
+ def self.metric
7
+ :rails_best_practices
8
+ end
9
+
6
10
  def initialize
7
11
  super
8
12
  @rails_best_practices_count = []
@@ -16,5 +20,20 @@ module MetricFu
16
20
  @labels.update( { @labels.size => date })
17
21
  end
18
22
  end
23
+
24
+ def title
25
+ 'Rails Best Practices: design problems'
26
+ end
27
+
28
+ def data
29
+ [
30
+ ['rails_best_practices', @rails_best_practices_count.join(',')]
31
+ ]
32
+ end
33
+
34
+ def output_filename
35
+ 'rails_best_practices.js'
36
+ end
37
+
19
38
  end
20
39
  end
@@ -3,12 +3,8 @@
3
3
  <p><a href="http://github.com/railsbp/rails_best_practices">rails_best_practices</a> is a code metric tool for rails projects.</p>
4
4
 
5
5
  <% graph_name = 'rails_best_practices' %>
6
- <% if MetricFu.configuration.graph_engine == :gchart %>
7
- <img src="<%= graph_name %>.png?<%= Time.now.to_i %>" />
8
- <% else %>
9
6
  <canvas id="graph"></canvas>
10
7
  <script language="javascript" src="<%= graph_name %>.js?<%= Time.now.to_i %>" type="text/javascript"></script>
11
- <% end %>
12
8
 
13
9
  <table>
14
10
  <tr>
@@ -3,6 +3,10 @@ module MetricFu
3
3
  class RcovGrapher < Grapher
4
4
  attr_accessor :rcov_percent, :labels
5
5
 
6
+ def self.metric
7
+ :rcov
8
+ end
9
+
6
10
  def initialize
7
11
  super
8
12
  self.rcov_percent = []
@@ -15,5 +19,20 @@ module MetricFu
15
19
  self.labels.update( { self.labels.size => date })
16
20
  end
17
21
  end
22
+
23
+ def title
24
+ 'Rcov: code coverage'
25
+ end
26
+
27
+ def data
28
+ [
29
+ ['rcov', @rcov_percent.join(',')]
30
+ ]
31
+ end
32
+
33
+ def output_filename
34
+ 'rcov.js'
35
+ end
36
+
18
37
  end
19
38
  end
@@ -3,12 +3,8 @@
3
3
  <p>C0 code coverage information.</p>
4
4
 
5
5
  <% graph_name = 'rcov' %>
6
- <% if MetricFu.configuration.graph_engine == :gchart %>
7
- <img src="<%= graph_name %>.png?<%= Time.now.to_i %>" />
8
- <% else %>
9
6
  <canvas id="graph"></canvas>
10
7
  <script language="javascript" src="<%= graph_name %>.js?<%= Time.now.to_i %>" type="text/javascript"></script>
11
- <% end %>
12
8
 
13
9
  <p>Total Coverage: <%= @rcov.delete(:global_percent_run) %>% </p>
14
10
  <table>
@@ -7,7 +7,7 @@ module MetricFu
7
7
 
8
8
  def default_run_options
9
9
  { :dirs_to_reek => MetricFu::Io::FileSystem.directory('code_dirs'),
10
- :config_file_pattern => nil}
10
+ :config_file_pattern => 'config/*.reek'}
11
11
  end
12
12
 
13
13
  def has_graph?
@@ -13,9 +13,8 @@ module MetricFu
13
13
  mf_log "Skipping Reek, no files found to analyze"
14
14
  @output = ""
15
15
  else
16
- command = %Q(mf-reek #{cli_options(files)})
17
- mf_debug "** #{command}"
18
- @output = `#{command}`
16
+ args = cli_options(files)
17
+ @output = run!(args)
19
18
  @output = massage_for_reek_12 if reek_12?
20
19
  end
21
20
  end
@@ -46,17 +45,15 @@ module MetricFu
46
45
  file_path = file_data[:file_path]
47
46
  next if File.extname(file_path) =~ /\.erb|\.html|\.haml/
48
47
  begin
49
- line_numbers = MetricFu::LineNumbers.new(File.open(file_path, 'r').read,file_path)
48
+ line_numbers = MetricFu::LineNumbers.new(File.read(file_path),file_path)
50
49
  rescue StandardError => e
51
50
  raise e unless e.message =~ /you shouldn't be able to get here/
52
51
  mf_log "ruby_parser blew up while trying to parse #{file_path}. You won't have method level reek information for this file."
53
52
  next
54
53
  end
55
54
 
56
- out[file_data[:file_path]] ||= {}
57
55
  file_data[:code_smells].each do |smell_data|
58
56
  line = line_numbers.start_line_for_method(smell_data[:method])
59
- out[file_data[:file_path]][line.to_s] ||= []
60
57
  out[file_data[:file_path]][line.to_s] << {:type => :reek,
61
58
  :description => "#{smell_data[:type]} - #{smell_data[:message]}"}
62
59
  end
@@ -97,8 +94,15 @@ module MetricFu
97
94
  end
98
95
 
99
96
  def cli_options(files)
100
- config_file_param = options[:config_file_pattern] ? "--config #{options[:config_file_pattern]}" : ''
101
- cli_options = "#{config_file_param} #{files.join(' ')}"
97
+ '--line-number ' <<
98
+ config_option(options[:config_file_pattern]) << ' ' <<
99
+ files.join(' ')
100
+ end
101
+
102
+ def config_option(location)
103
+ return '' if location.to_s.empty?
104
+ option = "--config #{location}"
105
+ '--config .reek ' << option unless location == '.reek'
102
106
  end
103
107
 
104
108
  end
@@ -3,6 +3,10 @@ module MetricFu
3
3
  class ReekGrapher < Grapher
4
4
  attr_accessor :reek_count, :labels
5
5
 
6
+ def self.metric
7
+ :reek
8
+ end
9
+
6
10
  def initialize
7
11
  super
8
12
  @reek_count = {}
@@ -27,5 +31,20 @@ module MetricFu
27
31
  end
28
32
  end
29
33
  end
34
+
35
+ def title
36
+ 'Reek: code smells'
37
+ end
38
+
39
+ def data
40
+ @reek_count.map do |name, count|
41
+ [name, count.join(',')]
42
+ end
43
+ end
44
+
45
+ def output_filename
46
+ 'reek.js'
47
+ end
48
+
30
49
  end
31
50
  end
@@ -3,12 +3,8 @@
3
3
  <p><a href="http://github.com/troessner/reek">Reek</a> detects common code smells in ruby code.</p>
4
4
 
5
5
  <% graph_name = 'reek' %>
6
- <% if MetricFu.configuration.graph_engine == :gchart %>
7
- <img src="<%= graph_name %>.png?<%= Time.now.to_i %>" />
8
- <% else %>
9
6
  <canvas id="graph"></canvas>
10
7
  <script language="javascript" src="<%= graph_name %>.js?<%= Time.now.to_i %>" type="text/javascript"></script>
11
- <% end %>
12
8
 
13
9
  <table>
14
10
  <tr>
@@ -9,9 +9,8 @@ module MetricFu
9
9
  files_to_analyze = options[:dirs_to_roodi].map{|dir| Dir[File.join(dir, "**/*.rb")] }
10
10
  files = remove_excluded_files(files_to_analyze.flatten)
11
11
  config = options[:roodi_config] ? "-config=#{options[:roodi_config]}" : ""
12
- command = %Q(mf-roodi #{config} #{files.join(" ")})
13
- mf_debug "** #{command}"
14
- @output = `#{command}`
12
+ args = "#{config} #{files.join(" ")}"
13
+ @output = run!(args)
15
14
  end
16
15
 
17
16
  def analyze
@@ -3,6 +3,10 @@ module MetricFu
3
3
  class RoodiGrapher < Grapher
4
4
  attr_accessor :roodi_count, :labels
5
5
 
6
+ def self.metric
7
+ :roodi
8
+ end
9
+
6
10
  def initialize
7
11
  super
8
12
  @roodi_count = []
@@ -15,5 +19,20 @@ module MetricFu
15
19
  @labels.update( { @labels.size => date })
16
20
  end
17
21
  end
22
+
23
+ def title
24
+ 'Roodi: design problems'
25
+ end
26
+
27
+ def data
28
+ [
29
+ ['roodi', @roodi_count.join(',')]
30
+ ]
31
+ end
32
+
33
+ def output_filename
34
+ 'roodi.js'
35
+ end
36
+
18
37
  end
19
38
  end
@@ -3,12 +3,8 @@
3
3
  <p><a href="http://roodi.rubyforge.org/">Roodi</a> parses your Ruby code and warns you about design issues you have based on the checks that is has configured.</p>
4
4
 
5
5
  <% graph_name = 'roodi' %>
6
- <% if MetricFu.configuration.graph_engine == :gchart %>
7
- <img src="<%= graph_name %>.png?<%= Time.now.to_i %>" />
8
- <% else %>
9
6
  <canvas id="graph"></canvas>
10
7
  <script language="javascript" src="<%= graph_name %>.js?<%= Time.now.to_i %>" type="text/javascript"></script>
11
- <% end %>
12
8
 
13
9
  <table>
14
10
  <tr>
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+ MetricFu.lib_require { 'utility' }
1
3
  MetricFu.metrics_require { 'saikuro/scratch_file' }
2
4
  MetricFu.metrics_require { 'saikuro/parsing_element' }
3
5
  module MetricFu
@@ -17,9 +19,7 @@ module MetricFu
17
19
  options_string += "--input_directory #{input_dir} "
18
20
  end
19
21
 
20
- command = %Q(mf-saikuro #{options_string})
21
- mf_debug "** #{command}"
22
- `#{command}`
22
+ @output = run!(options_string)
23
23
  end
24
24
 
25
25
  def analyze
@@ -29,47 +29,65 @@ module MetricFu
29
29
  end
30
30
 
31
31
  def to_h
32
- files = @files.map do |file|
33
- my_file = file.to_h
34
-
35
- f = file.filepath
36
- f.gsub!(%r{^#{metric_directory}/}, '')
37
- f << "/#{file.filename}"
38
-
39
- my_file[:filename] = f
40
- my_file
41
- end
42
- @saikuro_data = {:files => files,
43
- :classes => @classes.map {|c| c.to_h},
44
- :methods => @meths.map {|m| m.to_h}
45
- }
32
+ @saikuro_data = {
33
+ files: files_with_relative_paths(@files),
34
+ classes: @classes.map { |c| c.to_h },
35
+ methods: @meths.map { |m| m.to_h },
36
+ }
37
+ clear_scratch_files!
46
38
  {:saikuro => @saikuro_data}
47
39
  end
48
40
 
49
41
  def per_file_info(out)
50
42
  @saikuro_data[:files].each do |file_data|
51
- next if File.extname(file_data[:filename]) == '.erb' || !File.exists?(file_data[:filename])
52
- begin
53
- line_numbers = MetricFu::LineNumbers.new(File.open(file_data[:filename], 'r').read)
54
- rescue StandardError => e
55
- raise e unless e.message =~ /you shouldn't be able to get here/
56
- mf_log "ruby_parser blew up while trying to parse #{file_path}. You won't have method level Saikuro information for this file."
57
- next
58
- end
43
+ filename = file_data[:filename]
44
+ next if erb_file?(filename) || file_not_exists?(filename)
45
+ next unless line_numbers = line_numbers_from_file(filename)
59
46
 
60
- out[file_data[:filename]] ||= {}
61
- file_data[:classes].each do |class_data|
62
- class_data[:methods].each do |method_data|
63
- line = line_numbers.start_line_for_method(method_data[:name])
64
- out[file_data[:filename]][line.to_s] ||= []
65
- out[file_data[:filename]][line.to_s] << {:type => :saikuro,
66
- :description => "Complexity #{method_data[:complexity]}"}
67
- end
47
+ build_output_from_line_numbers(out, line_numbers, file_data)
48
+ end
49
+ end
50
+
51
+ def build_output_from_line_numbers(out, line_numbers, file_data)
52
+ filename = file_data[:filename]
53
+ output = out[filename]
54
+ method_data_for_file_data(file_data) do |method_data|
55
+ line = line_numbers.start_line_for_method(method_data[:name]).to_s
56
+ result = {
57
+ :type => :saikuro,
58
+ :description => "Complexity #{method_data[:complexity]}"
59
+ }
60
+ output[line] << result
61
+ end
62
+ out
63
+ end
64
+
65
+ def line_numbers_from_file(filename)
66
+ MetricFu::LineNumbers.new(File.read(filename))
67
+ rescue StandardError => e
68
+ raise e unless e.message =~ /you shouldn't be able to get here/
69
+ mf_log "ruby_parser blew up while trying to parse #{file_path}. You won't have method level Saikuro information for this file."
70
+ end
71
+
72
+ def method_data_for_file_data(file_data, &block)
73
+ return unless block_given?
74
+ file_data[:classes].each do |class_data|
75
+ class_data[:methods].each do |method_data|
76
+ yield method_data
68
77
  end
69
78
  end
70
79
  end
71
80
 
72
81
  private
82
+
83
+ def erb_file?(filename)
84
+ File.extname(filename) == '.erb'
85
+ end
86
+
87
+ def file_not_exists?(filename)
88
+ !File.exists?(filename)
89
+ end
90
+
73
91
  def sort_methods(methods)
74
92
  methods.sort_by {|method| method.complexity.to_i}.reverse
75
93
  end
@@ -107,6 +125,24 @@ module MetricFu
107
125
  SaikuroScratchFile.assemble_files( Dir.glob("#{metric_directory}/**/*.html") )
108
126
  end
109
127
 
128
+ def files_with_relative_paths(files)
129
+ files.map do |file|
130
+ file_hash = file.to_h
131
+ file_hash[:filename] = file_relative_path(file)
132
+ file_hash
133
+ end.to_a
134
+ end
135
+
136
+ def file_relative_path(file)
137
+ filepath = file.filepath
138
+ path = filepath.gsub(/^#{metric_directory}\//, '')
139
+ "#{path}/#{file.filename}"
140
+ end
141
+
142
+ def clear_scratch_files!
143
+ MetricFu::Utility.rm_rf(metric_directory)
144
+ end
145
+
110
146
  end
111
147
 
112
148
  end
@@ -19,16 +19,15 @@ module MetricFu
19
19
 
20
20
  def initialize(path)
21
21
  @path = path
22
- @file_handle = File.open(@path, "r")
23
22
  @elements = []
24
- get_elements
25
- ensure
26
- @file_handle.close if @file_handle
23
+ File.open(@path, "r") do |file|
24
+ get_elements(file)
25
+ end
27
26
  end
28
27
 
29
28
  def self.is_valid_text_file?(path)
30
- File.open(path, "r") do |f|
31
- if f.eof? || !f.readline.match(/--/)
29
+ File.open(path, "r") do |file|
30
+ if file.eof? || !file.readline.match(/--/)
32
31
  return false
33
32
  else
34
33
  return true
@@ -49,9 +48,9 @@ module MetricFu
49
48
  {:classes => @elements}
50
49
  end
51
50
 
52
- def get_elements
51
+ def get_elements(io)
53
52
  begin
54
- while (line = @file_handle.readline) do
53
+ while (line = io.readline) do
55
54
  return [] if line.nil? || line !~ /\S/
56
55
  element ||= nil
57
56
  if line.match(/START/)
@@ -59,7 +58,7 @@ module MetricFu
59
58
  @elements << element
60
59
  element = nil
61
60
  end
62
- line = @file_handle.readline
61
+ line = io.readline
63
62
  element = MetricFu::SaikuroParsingElement.new(line)
64
63
  elsif line.match(/END/)
65
64
  @elements << element if element
@@ -3,6 +3,10 @@ module MetricFu
3
3
  class StatsGrapher < Grapher
4
4
  attr_accessor :loc_counts, :lot_counts, :labels
5
5
 
6
+ def self.metric
7
+ :stats
8
+ end
9
+
6
10
  def initialize
7
11
  super
8
12
  self.loc_counts = []
@@ -17,5 +21,21 @@ module MetricFu
17
21
  self.labels.update( { self.labels.size => date })
18
22
  end
19
23
  end
24
+
25
+ def title
26
+ 'Stats: LOC & LOT'
27
+ end
28
+
29
+ def data
30
+ [
31
+ ['LOC', @loc_counts.join(',')],
32
+ ['LOT', @lot_counts.join(',')],
33
+ ]
34
+ end
35
+
36
+ def output_filename
37
+ 'stats.js'
38
+ end
39
+
20
40
  end
21
41
  end