jscruggs-metric_fu 0.8.0 → 0.8.9

Sign up to get free protection for your applications and to get access to all the features.
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>