p8-metric_fu 0.8.0.16 → 0.8.2

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 (47) hide show
  1. data/README +17 -63
  2. data/Rakefile +1 -1
  3. data/lib/metric_fu/base.rb +8 -114
  4. data/lib/metric_fu/churn.rb +7 -8
  5. data/lib/metric_fu/flay_reporter.rb +17 -0
  6. data/lib/metric_fu/flog_reporter/base.rb +49 -0
  7. data/lib/metric_fu/flog_reporter/generator.rb +39 -0
  8. data/lib/metric_fu/flog_reporter/operator.rb +10 -0
  9. data/lib/metric_fu/flog_reporter/page.rb +33 -0
  10. data/lib/metric_fu/flog_reporter/scanned_method.rb +28 -0
  11. data/lib/metric_fu/flog_reporter.rb +5 -0
  12. data/lib/tasks/churn.rake +3 -1
  13. data/lib/tasks/coverage.rake +35 -49
  14. data/lib/tasks/flay.rake +4 -1
  15. data/lib/tasks/flog.rake +10 -10
  16. data/lib/tasks/metric_fu.rake +4 -8
  17. data/lib/tasks/metric_fu.rb +1 -1
  18. data/lib/tasks/saikuro.rake +1 -1
  19. data/lib/tasks/stats.rake +1 -1
  20. data/lib/templates/churn.css +38 -0
  21. data/lib/templates/churn.html.erb +3 -6
  22. data/lib/templates/flay.css +38 -0
  23. data/lib/templates/flay.html.erb +10 -17
  24. data/lib/templates/flog.css +39 -0
  25. data/lib/templates/flog.html.erb +14 -19
  26. data/lib/templates/flog_page.html.erb +3 -15
  27. data/spec/base_spec.rb +8 -30
  28. data/spec/churn_spec.rb +3 -10
  29. data/spec/{flay_spec.rb → flay_reporter_spec.rb} +2 -9
  30. data/spec/flog_reporter/base_spec.rb +69 -0
  31. data/spec/md5_tracker_spec.rb +3 -1
  32. data/spec/spec_helper.rb +3 -7
  33. metadata +17 -41
  34. data/Manifest.txt +0 -25
  35. data/lib/metric_fu/flay.rb +0 -17
  36. data/lib/metric_fu/flog.rb +0 -139
  37. data/lib/metric_fu/reek.rb +0 -17
  38. data/lib/metric_fu/roodi.rb +0 -17
  39. data/lib/tasks/railroad.rake +0 -36
  40. data/lib/tasks/reek.rake +0 -6
  41. data/lib/tasks/roodi.rake +0 -7
  42. data/lib/templates/default.css +0 -45
  43. data/lib/templates/reek.html.erb +0 -30
  44. data/lib/templates/roodi.html.erb +0 -26
  45. data/spec/config_spec.rb +0 -110
  46. data/spec/flog_spec.rb +0 -147
  47. data/spec/reek_spec.rb +0 -26
@@ -0,0 +1,33 @@
1
+ module MetricFu::FlogReporter
2
+ class Page < MetricFu::Base::Generator
3
+ attr_accessor :score, :scanned_methods
4
+
5
+ def initialize(score, scanned_methods = [])
6
+ @score = score.to_f
7
+ @scanned_methods = scanned_methods
8
+ end
9
+
10
+ def to_html
11
+ ERB.new(File.read(template_file)).result(binding)
12
+ end
13
+
14
+ def average_score
15
+ sum = 0
16
+ scanned_methods.each do |m|
17
+ sum += m.score
18
+ end
19
+ sum / scanned_methods.length
20
+ end
21
+
22
+ def highest_score
23
+ scanned_methods.inject(0) do |highest, m|
24
+ m.score > highest ? m.score : highest
25
+ end
26
+ end
27
+
28
+ # should be dynamically read from the class
29
+ def template_name
30
+ 'flog_page'
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ module MetricFu::FlogReporter
2
+ class ScannedMethod
3
+ attr_accessor :name, :score, :operators
4
+
5
+ def initialize(name, score, operators = [])
6
+ @name = name
7
+ @score = score.to_f
8
+ @operators = operators
9
+ end
10
+
11
+ def to_html
12
+ output = "<p><strong>#{name} (#{score})</strong></p>\n"
13
+ output << "<table>\n"
14
+ output << "<tr><th>Score</th><th>Operator</th></tr>\n"
15
+ count = 0
16
+ operators.each do |operator|
17
+ output << <<-EOF
18
+ <tr class='#{Base.cycle("light", "dark", count)}'>
19
+ <td class='score'>#{sprintf(SCORE_FORMAT, operator.score)}</td>
20
+ <td class='score'>#{operator.operator}</td>
21
+ </tr>
22
+ EOF
23
+ count += 1
24
+ end
25
+ output << "</table>\n\n"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ require File.join(File.dirname(__FILE__), 'flog_reporter', 'base')
2
+ require File.join(File.dirname(__FILE__), 'flog_reporter', 'page')
3
+ require File.join(File.dirname(__FILE__), 'flog_reporter', 'scanned_method')
4
+ require File.join(File.dirname(__FILE__), 'flog_reporter', 'operator')
5
+ require File.join(File.dirname(__FILE__), 'flog_reporter', 'generator')
data/lib/tasks/churn.rake CHANGED
@@ -4,6 +4,8 @@ namespace :metrics do
4
4
 
5
5
  desc "Which files change the most"
6
6
  task :churn do
7
- MetricFu.generate_churn_report
7
+ churn_dir = File.join(MetricFu::BASE_DIRECTORY, 'churn')
8
+ MetricFu::Churn.generate_report(churn_dir, defined?(MetricFu::CHURN_OPTIONS) ? MetricFu::CHURN_OPTIONS : {} )
9
+ system("open #{churn_dir}/index.html") if PLATFORM['darwin']
8
10
  end
9
11
  end
@@ -1,54 +1,40 @@
1
1
  require 'fileutils'
2
-
3
- begin
4
- require 'rcov'
5
- require 'rcov/rcovtask'
6
- require 'spec/rake/spectask'
7
-
8
- namespace :metrics do
9
-
10
- COVERAGE_DIR = File.join(MetricFu::BASE_DIRECTORY, 'coverage')
11
- COVERAGE_DATA_FILE = File.join(MetricFu::BASE_DIRECTORY, 'coverage.data')
12
- SPEC_HTML_FILE = File.join(MetricFu::BASE_DIRECTORY, 'specs.html')
13
-
14
- namespace :coverage do
15
- rcov_output = COVERAGE_DIR
16
-
17
- desc "Delete aggregate coverage data."
18
- task(:clean) { rm_f("rcov_tmp", :verbose => false) }
19
-
20
- desc "RCov task to generate report"
21
- Rcov::RcovTask.new(:do => :clean) do |t|
22
- FileUtils.mkdir_p(MetricFu::BASE_DIRECTORY) unless File.directory?(MetricFu::BASE_DIRECTORY)
23
- t.test_files = FileList[*MetricFu.coverage[:test_files]]
24
- t.rcov_opts = ["--sort coverage", "--html", "--rails", "--exclude /gems/,/Library/"]
25
- t.output_dir = COVERAGE_DIR
26
- # this line is a fix for Rails 2.1 relative loading issues
27
- t.libs << 'test'
28
- end
29
- # TODO not sure what this improves but it requires the diff-lcs gem
30
- # http://github.com/indirect/metric_fu/commit/b9c1cf75f09d5b531b388cd01661eb16b5126968#diff-1
31
- # Spec::Rake::SpecTask.new(:do => :clean) do |t|
32
- # FileUtils.mkdir_p(MetricFu::BASE_DIRECTORY) unless File.directory?(MetricFu::BASE_DIRECTORY)
33
- # t.ruby_opts = ['-rtest/unit']
34
- # t.spec_files = FileList['test/**/*_test.rb', 'spec/**/*spec.rb']
35
- # t.spec_opts = ["--format", "html:#{SPEC_HTML_FILE}", "--diff"]
36
- # t.rcov = true
37
- # t.rcov_opts = ["--sort coverage", "--html", "--rails", "--exclude /gems/,/Library/"]
38
- # t.rcov_dir = COVERAGE_DIR
39
- # end
2
+ require 'spec/rake/spectask'
3
+ require 'spec/rake/verify_rcov'
4
+
5
+ namespace :metrics do
6
+
7
+ COVERAGE_DIR = File.join(MetricFu::BASE_DIRECTORY, 'coverage')
8
+ COVERAGE_DATA_FILE = File.join(MetricFu::BASE_DIRECTORY, 'coverage.data')
9
+ SPEC_HTML_FILE = File.join(MetricFu::BASE_DIRECTORY, 'specs.html')
10
+
11
+ namespace :coverage do
12
+ rcov_output = COVERAGE_DIR
13
+
14
+ desc "Delete aggregate coverage data."
15
+ task(:clean) { rm_f("rcov_tmp", :verbose => false) }
16
+
17
+ desc "RCov task to generate report"
18
+ Spec::Rake::SpecTask.new(:do => :clean) do |t|
19
+ FileUtils.mkdir_p(MetricFu::BASE_DIRECTORY) unless File.directory?(MetricFu::BASE_DIRECTORY)
20
+ t.ruby_opts = ['-rtest/unit']
21
+ t.spec_files = FileList['test/**/*_test.rb', 'spec/**/*spec.rb']
22
+ t.spec_opts = ["--format", "html:#{SPEC_HTML_FILE}", "--diff"]
23
+ t.rcov = true
24
+ t.rcov_opts = ["--sort coverage", "--html", "--rails", "--exclude /gems/,/Library/"]
25
+ t.rcov_dir = COVERAGE_DIR
40
26
  end
41
-
42
- desc "Generate and open coverage report"
43
- task :coverage => ['coverage:do'] do
44
- system("open #{COVERAGE_DIR}/index.html") if MetricFu.open_in_browser?
27
+
28
+ RCov::VerifyTask.new(:verify => :do) do |t|
29
+ t.threshold = ( ENV['THRESHOLD'] ? ENV['THRESHOLD'].to_f : 100.0 )
30
+ t.index_html = File.join(COVERAGE_DIR, 'index.html')
45
31
  end
46
32
  end
47
- rescue LoadError
48
- if RUBY_PLATFORM =~ /java/
49
- puts 'running in jruby - rcov tasks not available'
50
- else
51
- puts 'sudo gem install rcov # if you want the rcov tasks'
52
-
33
+
53
34
  end
54
- end
35
+
36
+ desc "Generate and open coverage report"
37
+ task :coverage => ['coverage:do'] do
38
+ system("open #{COVERAGE_DIR}/index.html") if PLATFORM['darwin']
39
+ end
40
+ end
data/lib/tasks/flay.rake CHANGED
@@ -1,6 +1,9 @@
1
+ FLAY_DIR = File.join(MetricFu::BASE_DIRECTORY, 'flay')
2
+
1
3
  namespace :metrics do
2
4
  desc "Generate code duplication report with flay"
3
5
  task :flay do
4
- MetricFu.generate_flay_report
6
+ MetricFu::FlayReporter.generate_report(FLAY_DIR)
7
+ system("open #{FLAY_DIR}/index.html") if PLATFORM['darwin']
5
8
  end
6
9
  end
data/lib/tasks/flog.rake CHANGED
@@ -1,13 +1,11 @@
1
1
  begin
2
+ FLOG_DIR = File.join(MetricFu::BASE_DIRECTORY, 'flog')
2
3
 
3
4
  def flog(output, directory)
4
- metric_dir = MetricFu::Flog::Generator.metric_dir
5
5
  Dir.glob("#{directory}/**/*.rb").each do |filename|
6
- output_dir = "#{metric_dir}/#{filename.split("/")[0..-2].join("/")}"
6
+ output_dir = "#{FLOG_DIR}/#{filename.split("/")[0..-2].join("/")}"
7
7
  mkdir_p(output_dir, :verbose => false) unless File.directory?(output_dir)
8
- if MetricFu::MD5Tracker.file_changed?(filename, metric_dir)
9
- `flog #{filename} > #{metric_dir}/#{filename.split('.')[0]}.txt`
10
- end
8
+ `flog #{filename} > #{FLOG_DIR}/#{filename.split('.')[0]}.txt` if MetricFu::MD5Tracker.file_changed?(filename, FLOG_DIR)
11
9
  end
12
10
  end
13
11
 
@@ -18,7 +16,7 @@ begin
18
16
 
19
17
  namespace :flog do
20
18
  desc "Delete aggregate flog data."
21
- task(:clean) { rm_rf(MetricFu::Flog.metric_dir, :verbose => false) }
19
+ task(:clean) { rm_rf(FLOG_DIR, :verbose => false) }
22
20
 
23
21
  desc "Flog code in app/models"
24
22
  task :models do
@@ -42,18 +40,20 @@ begin
42
40
 
43
41
  desc "Generate a flog report from specified directories"
44
42
  task :custom do
45
- MetricFu::flog[:dirs_to_flog].each { |directory| flog(directory, directory) }
46
- MetricFu.generate_flog_report
43
+ MetricFu::CODE_DIRS.each { |directory| flog(directory, directory) }
44
+ MetricFu::FlogReporter::Generator.generate_report(FLOG_DIR)
47
45
  end
48
46
 
49
47
  desc "Generate and open flog report"
50
48
  if MetricFu::RAILS
51
49
  task :all => [:models, :controllers, :helpers, :lib] do
52
- MetricFu.generate_flog_report
50
+ MetricFu::FlogReporter::Generator.generate_report(FLOG_DIR)
51
+ system("open #{FLOG_DIR}/index.html") if PLATFORM['darwin']
53
52
  end
54
53
  else
55
54
  task :all => [:custom] do
56
- MetricFu.generate_flog_report
55
+ MetricFu::FlogReporter::Generator.generate_report(FLOG_DIR)
56
+ system("open #{FLOG_DIR}/index.html") if PLATFORM['darwin']
57
57
  end
58
58
  end
59
59
 
@@ -1,11 +1,8 @@
1
- # only load configured metrics
2
- MetricFu.metrics.each { |task| import "#{File.dirname(__FILE__)}/#{task}.rake" }
3
-
4
1
  namespace :metrics do
5
2
  if MetricFu::RAILS
6
3
 
7
- desc "Generate coverage, cyclomatic complexity, flog, flay, railroad, reek, roodi, stats and churn reports"
8
- task :all => MetricFu.metrics
4
+ desc "Generate coverage, cyclomatic complexity, flog, stats, duplication and churn reports"
5
+ task :all => [:coverage, :stats, :saikuro, :churn, :flog, :flay]
9
6
 
10
7
  task :set_testing_env do
11
8
  RAILS_ENV = 'test'
@@ -16,9 +13,8 @@ namespace :metrics do
16
13
 
17
14
  else
18
15
 
19
- desc "Generate coverage, cyclomatic complexity, flog, flay, railroad and churn reports"
20
- task :all => MetricFu.metrics
16
+ desc "Generate coverage, cyclomatic complexity, flog, duplication and churn reports"
17
+ task :all => [:coverage, :saikuro, :churn, :flog, :flay]
21
18
 
22
19
  end
23
-
24
20
  end
@@ -3,4 +3,4 @@ require 'rubygems'
3
3
  require 'rake'
4
4
 
5
5
  # Load rake files
6
- import "#{File.dirname(__FILE__)}/metric_fu.rake"
6
+ Dir["#{File.dirname(__FILE__)}/*.rake"].each { |ext| load ext }
@@ -30,6 +30,6 @@ namespace :metrics do
30
30
  "#{SAIKURO_DIR}/index.html"
31
31
  end
32
32
 
33
- system("open #{SAIKURO_DIR}/index.html") if MetricFu.open_in_browser?
33
+ system("open #{SAIKURO_DIR}/index.html") if PLATFORM['darwin']
34
34
  end
35
35
  end
data/lib/tasks/stats.rake CHANGED
@@ -9,6 +9,6 @@ namespace :metrics do
9
9
  `echo '<pre>' > #{STATS_FILE}`
10
10
  `rake stats >> #{STATS_FILE}`
11
11
  `echo '</pre>' >> #{STATS_FILE}`
12
- system("open #{STATS_FILE}") if MetricFu.open_in_browser?
12
+ system("open #{STATS_FILE}") if PLATFORM['darwin']
13
13
  end
14
14
  end
@@ -0,0 +1,38 @@
1
+ body {
2
+ margin: 20px;
3
+ padding: 0;
4
+ font-size: 12px;
5
+ font-family: bitstream vera sans, verdana, arial, sans serif;
6
+ background-color: #efefef;
7
+ }
8
+
9
+ table {
10
+ border-collapse: collapse;
11
+ /*border-spacing: 0;*/
12
+ border: 1px solid #666;
13
+ background-color: #fff;
14
+ margin-bottom: 20px;
15
+ }
16
+
17
+ table, th, th+th, td, td+td {
18
+ border: 1px solid #ccc;
19
+ }
20
+
21
+ table th {
22
+ font-size: 12px;
23
+ color: #fc0;
24
+ padding: 4px 0;
25
+ background-color: #336;
26
+ }
27
+
28
+ th, td {
29
+ padding: 4px 10px;
30
+ }
31
+
32
+ td {
33
+ font-size: 13px;
34
+ }
35
+
36
+ .warning {
37
+ background-color: yellow;
38
+ }
@@ -2,21 +2,18 @@
2
2
  <head>
3
3
  <title>Source Control Churn Results</title>
4
4
  <style>
5
- <%= inline_css("default.css") %>
5
+ <%= open(File.join(MetricFu::TEMPLATE_DIR, "#{template_name}.css")) { |f| f.read } %>
6
6
  </style>
7
7
  </head>
8
8
 
9
9
  <body>
10
10
  <h1>Source Control Churn Results</h1>
11
- <p>Files that change a lot in your project may be bad a sign.
12
- This task uses your source control log to identify those files.
13
- </p>
14
- <table>
11
+ <table width="100%" border="1">
15
12
  <tr><th>File Path</th><th>Times Changed</th></tr>
16
13
  <% @changes.to_a.sort {|x,y| y[1] <=> x[1]}.each do |change| %>
17
14
  <tr><td><%= change[0] %></td><td class='warning'><%= change[1] %></td></tr>
18
15
  <% end %>
16
+
19
17
  </table>
20
- <p>Generated on <%= Time.now.localtime %></p>
21
18
  </body>
22
19
  </html>
@@ -0,0 +1,38 @@
1
+ body {
2
+ margin: 20px;
3
+ padding: 0;
4
+ font-size: 12px;
5
+ font-family: bitstream vera sans, verdana, arial, sans serif;
6
+ background-color: #efefef;
7
+ }
8
+
9
+ table {
10
+ border-collapse: collapse;
11
+ /*border-spacing: 0;*/
12
+ border: 1px solid #666;
13
+ background-color: #fff;
14
+ margin-bottom: 10px;
15
+ }
16
+
17
+ table, th, th+th, td, td+td {
18
+ border: 1px solid #ccc;
19
+ }
20
+
21
+ table th {
22
+ font-size: 14px;
23
+ color: #fc0;
24
+ background-color: #336;
25
+ text-align: left;
26
+ }
27
+
28
+ th, td {
29
+ padding: 4px 10px;
30
+ }
31
+
32
+ td {
33
+ font-size: 13px;
34
+ }
35
+
36
+ .warning {
37
+ background-color: yellow;
38
+ }
@@ -2,29 +2,22 @@
2
2
  <head>
3
3
  <title>Flay Results</title>
4
4
  <style>
5
- <%= inline_css("default.css") %>
5
+ <%= open(File.join(MetricFu::TEMPLATE_DIR, "#{template_name}.css")) { |f| f.read } %>
6
6
  </style>
7
7
  </head>
8
8
 
9
9
  <body>
10
10
  <h1>Flay Results</h1>
11
- <p><a href='http://ruby.sadi.st/Flay.html'>Flay</a> analyzes ruby code for structural similarities.</p>
12
- <table>
13
- <tr>
14
- <th>Files</th>
15
- <th>Matches</th>
16
- </tr>
17
- <% @matches.each_with_index do |match, count| %>
18
- <tr class='<%= cycle("light", "dark", count) %>'>
19
- <td>
20
- <% match[1..-1].each do |filename| %>
21
- <%= link_to_filename(*filename.split(":")) %><br>
22
- <% end %>
23
- </td>
24
- <td><%= match.first %></td>
25
- </tr>
11
+
12
+ <% @matches.each do |match| %>
13
+ <table width="80%" border="1">
14
+ <tr><th><%= match.first %></th></tr>
15
+ <tr><td>
16
+ <% match[1..-1].each do |filename| %>
17
+ <%= link_to_filename(*filename.split(":")) %><br>
18
+ <% end %>
19
+ </td></tr>
26
20
  <% end %>
27
21
  </table>
28
- <p>Generated on <%= Time.now.localtime %></p>
29
22
  </body>
30
23
  </html>
@@ -0,0 +1,39 @@
1
+ body {
2
+ background-color: rgb(240, 240, 245);
3
+ font-family: verdana, arial, helvetica;
4
+ }
5
+
6
+ table {
7
+ border-collapse: collapse;
8
+ }
9
+
10
+ table.report {
11
+ width: 100%;
12
+ }
13
+
14
+ table th {
15
+ text-align: center;
16
+ }
17
+
18
+ table td.score {
19
+ text-align: right;
20
+ }
21
+
22
+ table th {
23
+ background: #dcecff;
24
+ border: #d0d0d0 1px solid;
25
+ font-weight: bold;
26
+ }
27
+
28
+ table td {
29
+ border: #d0d0d0 1px solid;
30
+ }
31
+
32
+ table tr.light {
33
+ background-color: rgb(240, 240, 245);
34
+ }
35
+
36
+ table tr.dark {
37
+ background-color: rgb(230, 230, 235);
38
+ }
39
+