jscruggs-metric_fu 0.8.0 → 0.8.9

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 (53) hide show
  1. data/{History.txt → HISTORY} +12 -0
  2. data/MIT-LICENSE +1 -1
  3. data/Manifest.txt +3 -6
  4. data/README +66 -16
  5. data/Rakefile +11 -0
  6. data/TODO +13 -0
  7. data/lib/metric_fu/base.rb +159 -0
  8. data/lib/metric_fu/churn.rb +88 -0
  9. data/lib/metric_fu/flay.rb +17 -0
  10. data/lib/metric_fu/flog.rb +129 -0
  11. data/lib/metric_fu/md5_tracker.rb +6 -6
  12. data/lib/metric_fu/reek.rb +17 -0
  13. data/lib/metric_fu/roodi.rb +17 -0
  14. data/lib/metric_fu.rb +3 -7
  15. data/lib/tasks/churn.rake +4 -106
  16. data/lib/tasks/coverage.rake +25 -9
  17. data/lib/tasks/flay.rake +6 -0
  18. data/lib/tasks/flog.rake +28 -21
  19. data/lib/tasks/metric_fu.rake +21 -8
  20. data/lib/tasks/metric_fu.rb +1 -1
  21. data/lib/tasks/railroad.rake +36 -0
  22. data/lib/tasks/reek.rake +6 -0
  23. data/lib/tasks/roodi.rake +7 -0
  24. data/lib/tasks/saikuro.rake +20 -19
  25. data/lib/tasks/stats.rake +3 -3
  26. data/lib/templates/churn.html.erb +22 -0
  27. data/lib/templates/default.css +45 -0
  28. data/lib/templates/flay.html.erb +30 -0
  29. data/lib/templates/flog.html.erb +31 -0
  30. data/lib/templates/flog_page.html.erb +25 -0
  31. data/lib/templates/reek.html.erb +30 -0
  32. data/lib/templates/roodi.html.erb +26 -0
  33. data/spec/base_spec.rb +57 -0
  34. data/spec/churn_spec.rb +117 -0
  35. data/spec/config_spec.rb +110 -0
  36. data/spec/flay_spec.rb +19 -0
  37. data/spec/flog_spec.rb +208 -0
  38. data/spec/md5_tracker_spec.rb +57 -0
  39. data/spec/reek_spec.rb +26 -0
  40. data/spec/spec_helper.rb +11 -0
  41. metadata +76 -27
  42. data/TODO.txt +0 -9
  43. data/lib/metric_fu/flog_reporter/base.rb +0 -58
  44. data/lib/metric_fu/flog_reporter/flog_reporter.css +0 -39
  45. data/lib/metric_fu/flog_reporter/generator.rb +0 -71
  46. data/lib/metric_fu/flog_reporter/operator.rb +0 -10
  47. data/lib/metric_fu/flog_reporter/page.rb +0 -36
  48. data/lib/metric_fu/flog_reporter/scanned_method.rb +0 -28
  49. data/lib/metric_fu/flog_reporter.rb +0 -5
  50. data/lib/metric_fu/saikuro/SAIKURO_README +0 -142
  51. data/metric_fu.gemspec +0 -16
  52. data/test/test_helper.rb +0 -4
  53. data/test/test_md5_tracker.rb +0 -59
@@ -0,0 +1,17 @@
1
+ module MetricFu
2
+
3
+ def self.generate_roodi_report
4
+ MetricFu::Roodi.generate_report
5
+ system("open #{Roodi.metric_dir}/index.html") if open_in_browser?
6
+ end
7
+
8
+ class Roodi < Base::Generator
9
+
10
+ def analyze
11
+ files_to_analyze = MetricFu.roodi[:dirs_to_roodi].map{|dir| Dir[File.join(dir, "**/*.rb")] }
12
+ output = `roodi #{files_to_analyze.join(" ")}`
13
+ @matches = output.chomp.split("\n").map{|m| m.split(" - ") }
14
+ end
15
+
16
+ end
17
+ end
data/lib/metric_fu.rb CHANGED
@@ -1,7 +1,3 @@
1
- module MetricFu
2
- BASE_DIRECTORY = ENV['CC_BUILD_ARTIFACTS'] || 'tmp/metric_fu'
3
- end
4
-
5
- require File.join(File.dirname(__FILE__), 'metric_fu', 'md5_tracker')
6
- require File.join(File.dirname(__FILE__), 'metric_fu', 'flog_reporter')
7
- require File.join(File.dirname(__FILE__), 'tasks', 'metric_fu')
1
+ require File.join(File.dirname(__FILE__), 'metric_fu', 'base') #require first because of dependecies
2
+ require File.join(File.dirname(__FILE__), 'tasks', 'metric_fu')
3
+ Dir[File.join(File.dirname(__FILE__), 'metric_fu/*.rb')].each{|l| require l }
data/lib/tasks/churn.rake CHANGED
@@ -1,111 +1,9 @@
1
+ require File.join(File.dirname(__FILE__), '../metric_fu/churn')
2
+
1
3
  namespace :metrics do
2
- CHURN_DIR = File.join(MetricFu::BASE_DIRECTORY, 'churn')
3
-
4
+
4
5
  desc "Which files change the most"
5
6
  task :churn do
6
- date_range, minimum_churn_count, scm = churn_options()
7
-
8
- changes = {}
9
- if scm == :git
10
- git_logs = `git log #{date_range} --name-only --pretty=format:`.split(/\n/)
11
- git_logs.reject!{|line| line == ""}
12
-
13
- git_logs.each do |line|
14
- changes[line] ? changes[line] += 1 : changes[line] = 1
15
- end
16
- else
17
- svn_logs = `svn log #{date_range} --verbose`.split(/\n/).select {|line| line.strip =~ /^[A,M]/}
18
-
19
- svn_logs.each do |line|
20
- line.strip =~ /^[A,M] (.*)/
21
- changes[$1] ? changes[$1] += 1 : changes[$1] = 1
22
- end
23
- end
24
- write_churn_file(changes.reject {|file, change_count| change_count < minimum_churn_count})
25
- system("open #{CHURN_DIR}/index.html") if PLATFORM['darwin']
7
+ MetricFu.generate_churn_report
26
8
  end
27
-
28
- def churn_options
29
- raise "CHURN_OPTIONS is now MetricFu::CHURN_OPTIONS" if defined?(CHURN_OPTIONS)
30
- options = defined?(MetricFu::CHURN_OPTIONS) ? MetricFu::CHURN_OPTIONS : {}
31
- if options[:start_date]
32
- require RAILS_ROOT + '/config/environment'
33
- if options[:scm] == :git
34
- date_range = "--after=#{options[:start_date].call.strftime('%Y-%m-%d')}"
35
- else
36
- date_range = "--revision {#{options[:start_date].call.strftime('%Y-%m-%d')}}:{#{Time.now.strftime('%Y-%m-%d')}}"
37
- end
38
- else
39
- date_range = ""
40
- end
41
- minimum_churn_count = options[:minimum_churn_count] ? options[:minimum_churn_count] : 5
42
- scm = options[:scm] == :git ? :git : :svn
43
- return date_range, minimum_churn_count, scm
44
- end
45
-
46
- def write_churn_file changes
47
- FileUtils.mkdir_p(CHURN_DIR, :verbose => false) unless File.directory?(CHURN_DIR)
48
- File.open("#{CHURN_DIR}/index.html", "w+") do |file|
49
- file << CHURN_FILE_BEGINING
50
- changes.to_a.sort {|x,y| y[1] <=> x[1]}.each do |change|
51
- file << "<tr><td>#{change[0]}</td><td class='warning'>#{change[1]}</td></tr>\n"
52
- end
53
- file << CHURN_FILE_END
54
- end
55
- end
56
-
57
- CHURN_FILE_BEGINING = <<-EOS
58
- <html><head><title>Source Control Churn Results</title></head>
59
- <style>
60
- body {
61
- margin: 20px;
62
- padding: 0;
63
- font-size: 12px;
64
- font-family: bitstream vera sans, verdana, arial, sans serif;
65
- background-color: #efefef;
66
- }
67
-
68
- table {
69
- border-collapse: collapse;
70
- /*border-spacing: 0;*/
71
- border: 1px solid #666;
72
- background-color: #fff;
73
- margin-bottom: 20px;
74
- }
75
-
76
- table, th, th+th, td, td+td {
77
- border: 1px solid #ccc;
78
- }
79
-
80
- table th {
81
- font-size: 12px;
82
- color: #fc0;
83
- padding: 4px 0;
84
- background-color: #336;
85
- }
86
-
87
- th, td {
88
- padding: 4px 10px;
89
- }
90
-
91
- td {
92
- font-size: 13px;
93
- }
94
-
95
- .warning {
96
- background-color: yellow;
97
- }
98
- </style>
99
-
100
- <body>
101
- <h1>Source Control Churn Results</h1>
102
- <table width="100%" border="1">
103
- <tr><th>File Path</th><th>Times Changed</th></tr>
104
- EOS
105
-
106
- CHURN_FILE_END = <<-EOS
107
- </table>
108
- </body>
109
- </html>
110
- EOS
111
9
  end
@@ -1,32 +1,47 @@
1
1
  require 'fileutils'
2
-
2
+
3
3
  begin
4
4
  require 'rcov'
5
5
  require 'rcov/rcovtask'
6
-
6
+ require 'spec/rake/spectask'
7
+
7
8
  namespace :metrics do
8
-
9
+
9
10
  COVERAGE_DIR = File.join(MetricFu::BASE_DIRECTORY, 'coverage')
10
11
  COVERAGE_DATA_FILE = File.join(MetricFu::BASE_DIRECTORY, 'coverage.data')
11
-
12
+ SPEC_HTML_FILE = File.join(MetricFu::BASE_DIRECTORY, 'specs.html')
13
+
12
14
  namespace :coverage do
13
15
  rcov_output = COVERAGE_DIR
14
-
16
+
15
17
  desc "Delete aggregate coverage data."
16
18
  task(:clean) { rm_f("rcov_tmp", :verbose => false) }
17
-
19
+
18
20
  desc "RCov task to generate report"
19
21
  Rcov::RcovTask.new(:do => :clean) do |t|
20
22
  FileUtils.mkdir_p(MetricFu::BASE_DIRECTORY) unless File.directory?(MetricFu::BASE_DIRECTORY)
21
- t.test_files = FileList['test/**/*_test.rb', 'spec/**/*_spec.rb']
23
+ t.test_files = FileList[*MetricFu.coverage[:test_files]]
22
24
  t.rcov_opts = ["--sort coverage", "--html", "--rails", "--exclude /gems/,/Library/"]
23
25
  t.output_dir = COVERAGE_DIR
26
+ # this line is a fix for Rails 2.1 relative loading issues
27
+ t.libs << 'test'
24
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
25
40
  end
26
-
41
+
27
42
  desc "Generate and open coverage report"
28
43
  task :coverage => ['coverage:do'] do
29
- system("open #{COVERAGE_DIR}/index.html") if PLATFORM['darwin']
44
+ system("open #{COVERAGE_DIR}/index.html") if MetricFu.open_in_browser?
30
45
  end
31
46
  end
32
47
  rescue LoadError
@@ -34,5 +49,6 @@ rescue LoadError
34
49
  puts 'running in jruby - rcov tasks not available'
35
50
  else
36
51
  puts 'sudo gem install rcov # if you want the rcov tasks'
52
+
37
53
  end
38
54
  end
@@ -0,0 +1,6 @@
1
+ namespace :metrics do
2
+ desc "Generate code duplication report with flay"
3
+ task :flay do
4
+ MetricFu.generate_flay_report
5
+ end
6
+ end
data/lib/tasks/flog.rake CHANGED
@@ -1,55 +1,62 @@
1
1
  begin
2
- FLOG_DIR = File.join(MetricFu::BASE_DIRECTORY, 'flog')
3
2
 
4
3
  def flog(output, directory)
4
+ metric_dir = MetricFu::Flog::Generator.metric_dir
5
5
  Dir.glob("#{directory}/**/*.rb").each do |filename|
6
- output_dir = "#{FLOG_DIR}/#{filename.split("/")[0..-2].join("/")}"
6
+ output_dir = "#{metric_dir}/#{filename.split("/")[0..-2].join("/")}"
7
7
  mkdir_p(output_dir, :verbose => false) unless File.directory?(output_dir)
8
- `flog #{filename} > #{FLOG_DIR}/#{filename.split('.')[0]}.txt` if MetricFu::MD5Tracker.file_changed?(filename, FLOG_DIR)
8
+ if MetricFu::MD5Tracker.file_changed?(filename, metric_dir)
9
+ `flog #{filename} > #{metric_dir}/#{filename.split('.')[0]}.txt`
10
+ end
9
11
  end
10
12
  end
11
13
 
12
14
  namespace :metrics do
13
-
15
+
14
16
  task :flog => ['flog:all'] do
15
17
  end
16
-
18
+
17
19
  namespace :flog do
18
20
  desc "Delete aggregate flog data."
19
- task(:clean) { rm_rf(FLOG_DIR, :verbose => false) }
20
-
21
+ task(:clean) { rm_rf(MetricFu::Flog.metric_dir, :verbose => false) }
22
+
21
23
  desc "Flog code in app/models"
22
24
  task :models do
23
25
  flog "models", "app/models"
24
26
  end
25
27
 
26
- desc "Flog code in app/controllers"
28
+ desc "Flog code in app/controllers"
27
29
  task :controllers do
28
30
  flog "controllers", "app/controllers"
29
31
  end
30
32
 
31
- desc "Flog code in app/helpers"
33
+ desc "Flog code in app/helpers"
32
34
  task :helpers do
33
35
  flog "helpers", "app/helpers"
34
36
  end
35
37
 
36
- desc "Flog code in lib"
38
+ desc "Flog code in lib"
37
39
  task :lib do
38
40
  flog "lib", "lib"
39
- end
40
-
41
- desc "Generate and open flog report"
42
- task :all => [:models, :controllers, :helpers, :lib] do
43
- MetricFu::FlogReporter::Generator.generate_report(FLOG_DIR)
44
- system("open #{FLOG_DIR}/index.html") if PLATFORM['darwin']
45
41
  end
46
-
42
+
47
43
  desc "Generate a flog report from specified directories"
48
44
  task :custom do
49
- raise "You must define MetricFu::DIRECTORIES_TO_FLOG in your Rakefile" unless defined?(MetricFu::DIRECTORIES_TO_FLOG)
50
- MetricFu::DIRECTORIES_TO_FLOG.each { |directory| flog(directory, directory) }
51
- MetricFu::FlogReporter::Generator.generate_report(FLOG_DIR)
52
- end
45
+ MetricFu::flog[:dirs_to_flog].each { |directory| flog(directory, directory) }
46
+ MetricFu.generate_flog_report
47
+ end
48
+
49
+ desc "Generate and open flog report"
50
+ if MetricFu::RAILS
51
+ task :all => [:models, :controllers, :helpers, :lib] do
52
+ MetricFu.generate_flog_report
53
+ end
54
+ else
55
+ task :all => [:custom] do
56
+ MetricFu.generate_flog_report
57
+ end
58
+ end
59
+
53
60
  end
54
61
 
55
62
  end
@@ -1,11 +1,24 @@
1
+ # only load configured metrics
2
+ MetricFu.metrics.each { |task| import "#{File.dirname(__FILE__)}/#{task}.rake" }
3
+
1
4
  namespace :metrics do
2
- task :prepare do
3
- RAILS_ENV = 'test'
5
+ if MetricFu::RAILS
6
+
7
+ desc "Generate coverage, cyclomatic complexity, flog, flay, railroad, reek, roodi, stats and churn reports"
8
+ task :all => MetricFu.metrics
9
+
10
+ task :set_testing_env do
11
+ RAILS_ENV = 'test'
12
+ end
13
+
14
+ desc "Generate metrics after migrating (for continuous integration)"
15
+ task :all_with_migrate => [:set_testing_env, "db:migrate", :all]
16
+
17
+ else
18
+
19
+ desc "Generate coverage, cyclomatic complexity, flog, flay, railroad and churn reports"
20
+ task :all => MetricFu.metrics
21
+
4
22
  end
5
-
6
- desc "Useful for continuous integration"
7
- task :all_with_migrate => [:prepare, "db:migrate", :all]
8
-
9
- desc "Generate coverage, cyclomatic complexity (saikuro), flog, stats, and churn reports"
10
- task :all => [:coverage, :saikuro, :flog, :churn, :stats]
23
+
11
24
  end
@@ -3,4 +3,4 @@ require 'rubygems'
3
3
  require 'rake'
4
4
 
5
5
  # Load rake files
6
- Dir["#{File.dirname(__FILE__)}/*.rake"].each { |ext| load ext }
6
+ import "#{File.dirname(__FILE__)}/metric_fu.rake"
@@ -0,0 +1,36 @@
1
+ namespace :metrics do
2
+
3
+ RAILROAD_DIR = File.join(MetricFu::BASE_DIRECTORY, 'railroad')
4
+ RAILROAD_INDEX = File.join(RAILROAD_DIR, 'index.html')
5
+
6
+ task :railroad => ['railroad:all'] do
7
+ end
8
+
9
+ namespace :railroad do
10
+
11
+ desc "Create all railroad reports"
12
+ task :all => [:models, :controllers, :aasm] do
13
+ #system("open #{RAILROAD_INDEX}") if PLATFORM['darwin']
14
+ end
15
+
16
+ desc "Create a railroad models report"
17
+ task :models do
18
+ mkdir_p(RAILROAD_DIR) unless File.directory?(RAILROAD_DIR)
19
+ `railroad -M -a -m -l -v | neato -Tpng > #{File.join(RAILROAD_DIR,'models.png')}`
20
+ end
21
+
22
+ desc "Create a railroad controllers report"
23
+ task :controllers do
24
+ mkdir_p(RAILROAD_DIR) unless File.directory?(RAILROAD_DIR)
25
+ `railroad -C -l -v | neato -Tpng > #{File.join(RAILROAD_DIR,'controllers.png')}`
26
+ end
27
+
28
+ desc "Create a railroad acts_as_state_machine report"
29
+ task :aasm do
30
+ mkdir_p(RAILROAD_DIR) unless File.directory?(RAILROAD_DIR)
31
+ `railroad -A -l -v | neato -Tpng > #{File.join(RAILROAD_DIR,'aasm.png')}`
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,6 @@
1
+ namespace :metrics do
2
+ desc "A code smell report using Reek"
3
+ task :reek do
4
+ MetricFu.generate_reek_report
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ namespace :metrics do
2
+
3
+ desc "A Ruby coding standards report using Roodi"
4
+ task :roodi do
5
+ MetricFu.generate_roodi_report
6
+ end
7
+ end
@@ -1,23 +1,24 @@
1
+ require 'fileutils'
2
+
1
3
  namespace :metrics do
2
-
3
- SAIKURO_DIR = File.join(MetricFu::BASE_DIRECTORY, 'saikuro')
4
-
4
+
5
5
  desc "A cyclomatic complexity report using Saikuro"
6
6
  task :saikuro do
7
+ SAIKURO_DIR = File.join(MetricFu::BASE_DIRECTORY, 'saikuro')
8
+ SAIKURO = File.expand_path(File.join(File.dirname(__FILE__), '..', 'metric_fu', 'saikuro', 'saikuro.rb'))
9
+
7
10
  raise "SAIKURO_OPTIONS is now MetricFu::SAIKURO_OPTIONS" if defined?(SAIKURO_OPTIONS)
8
- default_options = {"--output_directory" => SAIKURO_DIR,
9
- "--input_directory" => "app",
10
- "--cyclo" => "",
11
- "--filter_cyclo" => "0",
12
- "--warn_cyclo" => "5",
13
- "--error_cyclo" => "7"}
14
-
15
- default_options.merge!(MetricFu::SAIKURO_OPTIONS) if defined?(MetricFu::SAIKURO_OPTIONS)
16
- options = ""
17
- default_options.each_pair { |key, value| options << "#{key} #{value} " }
18
-
19
- sh "ruby \"#{File.expand_path(File.join(File.dirname(__FILE__), '..', 'metric_fu', 'saikuro'))}/saikuro.rb\" " +
20
- "#{options}" do |ok, response|
11
+ options = { :output_directory => SAIKURO_DIR,
12
+ :input_directory => MetricFu::CODE_DIRS,
13
+ :cyclo => "",
14
+ :filter_cyclo => "0",
15
+ :warn_cyclo => "5",
16
+ :error_cyclo => "7"}
17
+
18
+ options.merge!(MetricFu::SAIKURO_OPTIONS) if defined?(MetricFu::SAIKURO_OPTIONS)
19
+ options_string = options.inject(""){ |o, h| o + "--#{h.join(' ')} " }
20
+
21
+ sh %{ruby "#{SAIKURO}" #{options_string}} do |ok, response|
21
22
  unless ok
22
23
  puts "Saikuro failed with exit status: #{response.exitstatus}"
23
24
  exit 1
@@ -25,10 +26,10 @@ namespace :metrics do
25
26
  end
26
27
 
27
28
  if File.exist? "#{SAIKURO_DIR}/index_cyclo.html"
28
- mv "#{SAIKURO_DIR}/index_cyclo.html",
29
+ mv "#{SAIKURO_DIR}/index_cyclo.html",
29
30
  "#{SAIKURO_DIR}/index.html"
30
31
  end
31
-
32
- system("open #{SAIKURO_DIR}/index.html") if PLATFORM['darwin']
32
+
33
+ system("open #{SAIKURO_DIR}/index.html") if MetricFu.open_in_browser?
33
34
  end
34
35
  end
data/lib/tasks/stats.rake CHANGED
@@ -1,14 +1,14 @@
1
1
  namespace :metrics do
2
-
2
+
3
3
  STATS_DIR = File.join(MetricFu::BASE_DIRECTORY, 'stats')
4
4
  STATS_FILE = File.join(STATS_DIR, 'index.html')
5
-
5
+
6
6
  desc "A stats report"
7
7
  task :stats do
8
8
  mkdir_p(STATS_DIR) unless File.directory?(STATS_DIR)
9
9
  `echo '<pre>' > #{STATS_FILE}`
10
10
  `rake stats >> #{STATS_FILE}`
11
11
  `echo '</pre>' >> #{STATS_FILE}`
12
- system("open #{STATS_FILE}") if PLATFORM['darwin']
12
+ system("open #{STATS_FILE}") if MetricFu.open_in_browser?
13
13
  end
14
14
  end
@@ -0,0 +1,22 @@
1
+ <html>
2
+ <head>
3
+ <title>Source Control Churn Results</title>
4
+ <style>
5
+ <%= inline_css("default.css") %>
6
+ </style>
7
+ </head>
8
+
9
+ <body>
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>
15
+ <tr><th>File Path</th><th>Times Changed</th></tr>
16
+ <% @changes.to_a.sort {|x,y| y[1] <=> x[1]}.each do |change| %>
17
+ <tr><td><%= change[0] %></td><td class='warning'><%= change[1] %></td></tr>
18
+ <% end %>
19
+ </table>
20
+ <p>Generated on <%= Time.now.localtime %></p>
21
+ </body>
22
+ </html>
@@ -0,0 +1,45 @@
1
+ body {
2
+ background-color: #efefef;
3
+ margin: 20px;
4
+ padding: 0;
5
+ font: 12px verdana, arial, helvetica;
6
+ }
7
+
8
+ table {
9
+ border-collapse: collapse;
10
+ border: 1px solid #666;
11
+ background: #fff;
12
+ margin-bottom: 20px;
13
+ }
14
+
15
+ table tr.light {
16
+ background: #fff;
17
+ }
18
+
19
+ table tr.dark {
20
+ background: #f9f9f9;
21
+ }
22
+
23
+ table td, table th {
24
+ padding: 4px 10px;
25
+ font-size: 13px;
26
+ }
27
+ table th {
28
+ text-align: center;
29
+ color: #fc0;
30
+ background: #336;
31
+ font-weight: bold;
32
+ border: #d0d0d0 1px solid;
33
+ }
34
+
35
+ table td {
36
+ border: #d0d0d0 1px solid;
37
+ }
38
+
39
+ table td.score {
40
+ text-align: right;
41
+ }
42
+
43
+ .warning {
44
+ background: yellow;
45
+ }
@@ -0,0 +1,30 @@
1
+ <html>
2
+ <head>
3
+ <title>Flay Results</title>
4
+ <style>
5
+ <%= inline_css("default.css") %>
6
+ </style>
7
+ </head>
8
+
9
+ <body>
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>
26
+ <% end %>
27
+ </table>
28
+ <p>Generated on <%= Time.now.localtime %></p>
29
+ </body>
30
+ </html>
@@ -0,0 +1,31 @@
1
+ <html>
2
+ <head>
3
+ <title>Flog Reporter</title>
4
+ <style>
5
+ <%= inline_css("default.css") %>
6
+ </style>
7
+ </head>
8
+ <body>
9
+ <h1>Flog Results</h1>
10
+ <p><a href='http://ruby.sadi.st/Flog.html'>Flog</a> measures code complexity.</p>
11
+ <table>
12
+ <tr>
13
+ <th>File</th>
14
+ <th>Total score</th>
15
+ <th>Methods</th>
16
+ <th>Average score</th>
17
+ <th>Highest score</th>
18
+ </tr>
19
+ <% pages.sort {|x,y| y.highest_score <=> x.highest_score }.each_with_index do |page, count| %>
20
+ <tr class='<%= cycle("light", "dark", count) %>'>
21
+ <td><a href='<%= page.path %>'><%= page.path.sub('.html', '.rb') %></a></td>
22
+ <td class='score'><%= sprintf(SCORE_FORMAT, page.score) %></td>
23
+ <td class='score'><%= page.scanned_methods.length %></td>
24
+ <td class='score'><%= sprintf(SCORE_FORMAT, page.average_score) %></td>
25
+ <td class='score'><%= sprintf(SCORE_FORMAT, page.highest_score) %></td>
26
+ </tr>
27
+ <% end %>
28
+ </table>
29
+ <p>Generated on <%= Time.now.localtime %></p>
30
+ </body>
31
+ </html>
@@ -0,0 +1,25 @@
1
+ <html>
2
+ <head>
3
+ <style>
4
+ <%= inline_css("default.css") %>
5
+ </style>
6
+ </head>
7
+ <body>
8
+ <p>Score: <%= score %></p>
9
+ <% scanned_methods.each do |sm| %>
10
+ <p><strong><%= sm.name %> (<%= sm.score %>)</strong></p>
11
+ <table>
12
+ <tr>
13
+ <th>Score</th>
14
+ <th>Operator</th>
15
+ </tr>
16
+ <% sm.operators.each_with_index do |operator, count| %>
17
+ <tr class='<%= cycle("light", "dark", count) %>'>
18
+ <td class='score'><%= sprintf(SCORE_FORMAT, operator.score) %></td>
19
+ <td class='score'><%= operator.operator %></td>
20
+ </tr>
21
+ <% end %>
22
+ </table>
23
+ <% end %>
24
+ </body>
25
+ </html>
@@ -0,0 +1,30 @@
1
+ <html>
2
+ <head>
3
+ <title>Reek Results</title>
4
+ <style>
5
+ <%= inline_css("default.css") %>
6
+ </style>
7
+ </head>
8
+
9
+ <body>
10
+ <h1>Reek Results</h1>
11
+ <p><a href="http://reek.rubyforge.org/">Reek</a> detects common code smells in ruby code.</p>
12
+ <table>
13
+ <tr>
14
+ <th>File Path</th>
15
+ <th>Code Smell</th>
16
+ </tr>
17
+ <% @matches.each_with_index do |match, count| %>
18
+ <tr class='<%= cycle("light", "dark", count) %>'>
19
+ <td><%= match.first %></td>
20
+ <td>
21
+ <% match[1..-1].each do |line| %>
22
+ <%= line %><br>
23
+ <% end %>
24
+ </td>
25
+ </tr>
26
+ <% end %>
27
+ </table>
28
+ <p>Generated on <%= Time.now.localtime %></p>
29
+ </body>
30
+ </html>