metric_fu 2.1.1 → 2.1.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. data/.gitignore +20 -0
  2. data/.travis.yml +5 -0
  3. data/Gemfile +5 -0
  4. data/HISTORY +21 -1
  5. data/Manifest.txt +25 -0
  6. data/README.md +61 -0
  7. data/Rakefile +15 -9
  8. data/TODO +2 -0
  9. data/bin/metric_fu +4 -0
  10. data/config/roodi_config.yml +22 -0
  11. data/home_page/back_all.jpg +0 -0
  12. data/home_page/churn.gif +0 -0
  13. data/home_page/flay.gif +0 -0
  14. data/home_page/flog.gif +0 -0
  15. data/home_page/footer.gif +0 -0
  16. data/home_page/header.jpg +0 -0
  17. data/home_page/hotspot.gif +0 -0
  18. data/home_page/img09.gif +0 -0
  19. data/home_page/index.html +305 -0
  20. data/home_page/rcov.gif +0 -0
  21. data/home_page/reek.gif +0 -0
  22. data/home_page/roodi.gif +0 -0
  23. data/home_page/saikuro.gif +0 -0
  24. data/home_page/stats.gif +0 -0
  25. data/home_page/styles.css +245 -0
  26. data/home_page/title.gif +0 -0
  27. data/home_page/title_back.gif +0 -0
  28. data/lib/{base/configuration.rb → configuration.rb} +45 -17
  29. data/lib/data_structures/careful_array.rb +9 -0
  30. data/lib/{base → data_structures}/code_issue.rb +17 -16
  31. data/lib/data_structures/grouping.rb +40 -0
  32. data/lib/{base → data_structures}/line_numbers.rb +23 -14
  33. data/lib/{base → data_structures}/location.rb +3 -1
  34. data/lib/{base → data_structures}/ranking.rb +0 -0
  35. data/lib/data_structures/record.rb +43 -0
  36. data/lib/{base → data_structures}/table.rb +6 -2
  37. data/lib/errors/analysis_error.rb +1 -0
  38. data/lib/initial_requires.rb +25 -0
  39. data/lib/load_files.rb +39 -0
  40. data/lib/logging/mf_debugger.rb +24 -0
  41. data/lib/{base/md5_tracker.rb → md5_tracker.rb} +0 -0
  42. data/lib/metric_fu.rb +55 -37
  43. data/lib/{base → metrics}/base_template.rb +47 -16
  44. data/lib/{generators → metrics/churn}/churn.rb +0 -0
  45. data/lib/{base → metrics/churn}/churn_analyzer.rb +0 -0
  46. data/lib/{templates/awesome → metrics/churn/template_awesome}/churn.html.erb +0 -0
  47. data/lib/{templates/standard → metrics/churn/template_standard}/churn.html.erb +0 -0
  48. data/lib/{generators → metrics/flay}/flay.rb +0 -0
  49. data/lib/{base → metrics/flay}/flay_analyzer.rb +0 -0
  50. data/lib/{graphs → metrics/flay}/flay_grapher.rb +0 -0
  51. data/lib/{templates/awesome → metrics/flay/template_awesome}/flay.html.erb +0 -0
  52. data/lib/{templates/standard → metrics/flay/template_standard}/flay.html.erb +0 -0
  53. data/lib/{generators → metrics/flog}/flog.rb +2 -0
  54. data/lib/{base → metrics/flog}/flog_analyzer.rb +0 -0
  55. data/lib/{graphs → metrics/flog}/flog_grapher.rb +0 -0
  56. data/lib/{templates/awesome → metrics/flog/template_awesome}/flog.html.erb +0 -0
  57. data/lib/{templates/standard → metrics/flog/template_standard}/flog.html.erb +0 -0
  58. data/lib/{base → metrics}/generator.rb +0 -0
  59. data/lib/{base → metrics}/graph.rb +0 -0
  60. data/lib/{generators → metrics/hotspots}/hotspots.rb +0 -0
  61. data/lib/{templates/awesome → metrics/hotspots/template_awesome}/hotspots.html.erb +0 -0
  62. data/lib/{templates/standard → metrics/hotspots/template_standard}/hotspots.html.erb +0 -0
  63. data/lib/{base → metrics}/metric_analyzer.rb +4 -80
  64. data/lib/{generators → metrics/rails_best_practices}/rails_best_practices.rb +0 -0
  65. data/lib/{graphs → metrics/rails_best_practices}/rails_best_practices_grapher.rb +0 -0
  66. data/lib/{templates/awesome → metrics/rails_best_practices/template_awesome}/rails_best_practices.html.erb +1 -1
  67. data/lib/{templates/standard → metrics/rails_best_practices/template_standard}/rails_best_practices.html.erb +1 -1
  68. data/lib/{generators → metrics/rcov}/rcov.rb +5 -3
  69. data/lib/{base → metrics/rcov}/rcov_analyzer.rb +1 -1
  70. data/lib/{graphs → metrics/rcov}/rcov_grapher.rb +0 -0
  71. data/lib/{templates/awesome → metrics/rcov/template_awesome}/rcov.html.erb +0 -0
  72. data/lib/{templates/standard → metrics/rcov/template_standard}/rcov.html.erb +0 -0
  73. data/lib/{generators → metrics/reek}/reek.rb +3 -2
  74. data/lib/{base → metrics/reek}/reek_analyzer.rb +1 -0
  75. data/lib/{graphs → metrics/reek}/reek_grapher.rb +0 -0
  76. data/lib/{templates/awesome → metrics/reek/template_awesome}/reek.html.erb +0 -0
  77. data/lib/{templates/standard → metrics/reek/template_standard}/reek.html.erb +0 -0
  78. data/lib/{generators → metrics/roodi}/roodi.rb +0 -0
  79. data/lib/{base → metrics/roodi}/roodi_analyzer.rb +0 -0
  80. data/lib/{graphs → metrics/roodi}/roodi_grapher.rb +0 -0
  81. data/lib/{templates/awesome → metrics/roodi/template_awesome}/roodi.html.erb +0 -0
  82. data/lib/{templates/standard → metrics/roodi/template_standard}/roodi.html.erb +0 -0
  83. data/lib/{generators → metrics/saikuro}/saikuro.rb +4 -2
  84. data/lib/{base → metrics/saikuro}/saikuro_analyzer.rb +0 -0
  85. data/lib/{templates/awesome → metrics/saikuro/template_awesome}/saikuro.html.erb +0 -0
  86. data/lib/{templates/standard → metrics/saikuro/template_standard}/saikuro.html.erb +0 -0
  87. data/lib/{generators → metrics/stats}/stats.rb +0 -0
  88. data/lib/{base → metrics/stats}/stats_analyzer.rb +0 -0
  89. data/lib/{graphs → metrics/stats}/stats_grapher.rb +0 -0
  90. data/lib/{templates/awesome → metrics/stats/template_awesome}/stats.html.erb +0 -0
  91. data/lib/{templates/standard → metrics/stats/template_standard}/stats.html.erb +0 -0
  92. data/lib/{graphs → reporting/graphs}/engines/bluff.rb +0 -0
  93. data/lib/{graphs → reporting/graphs}/engines/gchart.rb +0 -0
  94. data/lib/{graphs → reporting/graphs}/grapher.rb +0 -0
  95. data/lib/{base → reporting}/report.rb +2 -0
  96. data/lib/{templates → reporting/templates}/awesome/awesome_template.rb +28 -7
  97. data/lib/{templates → reporting/templates}/awesome/css/buttons.css +0 -0
  98. data/lib/{templates → reporting/templates}/awesome/css/default.css +0 -0
  99. data/lib/{templates → reporting/templates}/awesome/css/integrity.css +0 -0
  100. data/lib/{templates → reporting/templates}/awesome/css/reset.css +0 -0
  101. data/lib/{templates → reporting/templates}/awesome/css/syntax.css +0 -0
  102. data/lib/{templates → reporting/templates}/awesome/index.html.erb +0 -0
  103. data/lib/{templates → reporting/templates}/awesome/layout.html.erb +0 -0
  104. data/lib/{templates → reporting/templates}/javascripts/bluff-min.js +0 -0
  105. data/lib/{templates → reporting/templates}/javascripts/excanvas.js +0 -0
  106. data/lib/{templates → reporting/templates}/javascripts/js-class.js +0 -0
  107. data/lib/{templates → reporting/templates}/standard/default.css +0 -0
  108. data/lib/{templates → reporting/templates}/standard/index.html.erb +0 -0
  109. data/lib/{templates → reporting/templates}/standard/standard_template.rb +3 -3
  110. data/lib/{base/scoring_strategies.rb → scoring_strategies.rb} +0 -0
  111. data/lib/tasks/metric_fu.rake +36 -0
  112. data/lib/version.rb +3 -0
  113. data/metric_fu.gemspec +65 -0
  114. data/spec/base/base_template_spec.rb +19 -2
  115. data/spec/base/configuration_spec.rb +4 -3
  116. data/spec/base/generator_spec.rb +2 -2
  117. data/spec/base/line_numbers_spec.rb +2 -2
  118. data/spec/base/location_spec.rb +127 -0
  119. data/spec/base/metric_analyzer_spec.rb +452 -0
  120. data/spec/base/ranking_spec.rb +42 -0
  121. data/spec/base/report_spec.rb +1 -1
  122. data/spec/base/table_spec.rb +36 -0
  123. data/spec/generators/hotspots_spec.rb +88 -0
  124. data/spec/generators/rails_best_practices_spec.rb +1 -1
  125. data/spec/generators/rcov_spec.rb +3 -3
  126. data/spec/generators/stats_spec.rb +1 -1
  127. data/spec/spec_helper.rb +4 -1
  128. metadata +466 -309
  129. data/README +0 -29
  130. data/tasks/metric_fu.rake +0 -22
File without changes
File without changes
File without changes
@@ -15,6 +15,8 @@ module MetricFu
15
15
  files += dir_files
16
16
  end
17
17
  options = ::Flog.parse_options ["--all", "--details"]
18
+ # TODO determine if flogging should continue despite errors
19
+ # options = ::Flog.parse_options ["--all", "--details", "--continue"]
18
20
 
19
21
  @flogger = ::Flog.new options
20
22
  @flogger.flog files
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,4 +1,6 @@
1
- class AnalysisError < RuntimeError; end;
1
+ %w(record grouping).each do |path|
2
+ MetricFu.data_structures_require { path }
3
+ end
2
4
 
3
5
  class MetricAnalyzer
4
6
 
@@ -107,7 +109,7 @@ class MetricAnalyzer
107
109
 
108
110
  def get_grouping(table, opts)
109
111
  #Ruport::Data::Grouping.new(table, opts)
110
- Grouping.new(table, opts)
112
+ MetricFu::Grouping.new(table, opts)
111
113
  #@grouping_cache ||= {}
112
114
  #@grouping_cache.fetch(grouping_key(table,opts)) do
113
115
  # @grouping_cache[grouping_key(table,opts)] = Ruport::Data::Grouping.new(table, opts)
@@ -323,82 +325,4 @@ class MetricAnalyzer
323
325
 
324
326
  end
325
327
 
326
- class Record
327
-
328
- attr_reader :data
329
-
330
- def initialize(data, columns)
331
- @data = data
332
- @columns = columns
333
- end
334
-
335
- def method_missing(name, *args, &block)
336
- key = name.to_s
337
- if @data.has_key?(key)
338
- @data[key]
339
- elsif @columns.member?(key)
340
- nil
341
- else
342
- super(name, *args, &block)
343
- end
344
- end
345
-
346
- def []=(key, value)
347
- @data[key]=value
348
- end
349
-
350
- def [](key)
351
- @data[key]
352
- end
353
-
354
- def keys
355
- @data.keys
356
- end
357
-
358
- def has_key?(key)
359
- @data.has_key?(key)
360
- end
361
-
362
- def attributes
363
- @columns
364
- end
365
-
366
- end
367
-
368
- class Grouping
369
-
370
- def initialize(table, opts)
371
- column_name = opts.fetch(:by)
372
- order = opts.fetch(:order) { nil }
373
- hash = {}
374
- if column_name.to_sym == :metric # special optimized case
375
- hash = table.group_by_metric
376
- else
377
- table.each do |row|
378
- hash[row[column_name]] ||= Table.new(:column_names => row.attributes)
379
- hash[row[column_name]] << row
380
- end
381
- end
382
- if order
383
- @arr = hash.sort_by &order
384
- else
385
- @arr = hash.to_a
386
- end
387
- end
388
-
389
- def [](key)
390
- @arr.each do |group_key, table|
391
- return table if group_key == key
392
- end
393
- return nil
394
- end
395
-
396
- def each
397
- @arr.each do |value, rows|
398
- yield value, rows
399
- end
400
- end
401
-
402
- end
403
-
404
328
 
@@ -1,6 +1,6 @@
1
1
  <h3>Rails Best Practices Results</h3>
2
2
 
3
- <p><a href="http://github.com/flyerhzm/rails_best_practices">rails_best_practices</a> is a code metric tool for rails projects.</p>
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
6
  <% if MetricFu.configuration.graph_engine == :gchart %>
@@ -9,7 +9,7 @@
9
9
  <body>
10
10
  <h1>Rails Best Practices Results</h1>
11
11
  <a href="index.html">back to menu</a>
12
- <p><a href="http://github.com/flyerhzm/rails_best_practices">rails_best_practices</a> checks quality of rails app files according to ihower’s presentation from Kungfu RailsConf in Shanghai China.</p>
12
+ <p><a href="http://github.com/railsbp/rails_best_practices">rails_best_practices</a> checks quality of rails app files according to ihower’s presentation from Kungfu RailsConf in Shanghai China.</p>
13
13
  <table>
14
14
  <tr>
15
15
  <th>File Path</th>
@@ -25,8 +25,10 @@ module MetricFu
25
25
  test_files = FileList[*MetricFu.rcov[:test_files]].join(' ')
26
26
  rcov_opts = MetricFu.rcov[:rcov_opts].join(' ')
27
27
  output = ">> #{MetricFu::Rcov.metric_directory}/rcov.txt"
28
- puts "** Running the specs/tests in the [#{MetricFu.rcov[:environment]}] environment"
29
- `RAILS_ENV=#{MetricFu.rcov[:environment]} rcov #{test_files} #{rcov_opts} #{output}`
28
+ mf_debug "** Running the specs/tests in the [#{MetricFu.rcov[:environment]}] environment"
29
+ command = %Q(RAILS_ENV=#{MetricFu.rcov[:environment]} rcov #{test_files} #{rcov_opts} #{output})
30
+ mf_debug "** #{command}"
31
+ `#{command}`
30
32
  end
31
33
  end
32
34
 
@@ -68,7 +70,7 @@ module MetricFu
68
70
  line_numbers = MetricFu::LineNumbers.new(file_contents)
69
71
  rescue StandardError => e
70
72
  raise e unless e.message =~ /you shouldn't be able to get here/
71
- puts "ruby_parser blew up while trying to parse #{file_path}. You won't have method level Rcov information for this file."
73
+ STDOUT.puts "ruby_parser blew up while trying to parse #{file_path}. You won't have method level Rcov information for this file."
72
74
  next
73
75
  end
74
76
 
@@ -40,4 +40,4 @@ class RcovAnalyzer
40
40
  end
41
41
  end
42
42
 
43
- end
43
+ end
File without changes
@@ -58,9 +58,10 @@ module MetricFu
58
58
 
59
59
  def per_file_info(out)
60
60
  @matches.each do |file_data|
61
- next if File.extname(file_data[:file_path]) == '.erb'
61
+ file_path = file_data[:file_path]
62
+ next if File.extname(file_path) =~ /\.erb|\.html|\.haml/
62
63
  begin
63
- line_numbers = MetricFu::LineNumbers.new(File.open(file_data[:file_path], 'r').read)
64
+ line_numbers = MetricFu::LineNumbers.new(File.open(file_path, 'r').read,file_path)
64
65
  rescue StandardError => e
65
66
  raise e unless e.message =~ /you shouldn't be able to get here/
66
67
  puts "ruby_parser blew up while trying to parse #{file_path}. You won't have method level reek information for this file."
@@ -152,6 +152,7 @@ class ReekAnalyzer
152
152
  end
153
153
 
154
154
  def parse_value(message)
155
+ # mf_debug "parsing #{message}"
155
156
  match = message.match(/\d+/)
156
157
  if(match)
157
158
  match[0].to_i
File without changes
File without changes
File without changes
File without changes
@@ -1,6 +1,7 @@
1
1
  module MetricFu
2
2
 
3
3
  class Saikuro < Generator
4
+ include Rake::DSL if defined?(Rake::DSL) # rake 0.8.7 and 0.9.2 compatible
4
5
 
5
6
  def emit
6
7
  options_string = MetricFu.saikuro.inject("") do |options, option|
@@ -10,10 +11,11 @@ module MetricFu
10
11
  MetricFu.saikuro[:input_directory].each do |input_dir|
11
12
  options_string += "--input_directory #{input_dir} "
12
13
  end
13
- sh %{saikuro #{options_string}} do |ok, response|
14
+
15
+ saikuro_bin= $:.map{|d| d+'/../bin/saikuro'}.select{|f| File.exists? f}.first || 'saikuro'
16
+ sh %{#{saikuro_bin} #{options_string}} do |ok, response|
14
17
  unless ok
15
18
  puts "Saikuro failed with exit status: #{response.exitstatus}"
16
- exit 1
17
19
  end
18
20
  end
19
21
  end
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -54,7 +54,9 @@ module MetricFu
54
54
  # @param report_type Hash
55
55
  # The hash to add to the aggregate report_hash
56
56
  def add(report_type)
57
+ mf_debug "report requested #{report_type}"
57
58
  clazz = MetricFu.const_get(report_type.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase })
59
+ mf_debug "report class found #{clazz}"
58
60
  inst = clazz.new
59
61
 
60
62
  report_hash.merge!(inst.generate_report)
@@ -1,14 +1,16 @@
1
1
  require 'fileutils'
2
- require 'syntax/convertors/html'
2
+ require 'coderay'
3
+ MetricFu.metrics_require { 'base_template' }
3
4
 
4
5
  class AwesomeTemplate < MetricFu::Template
5
6
 
6
7
  def write
7
8
  # Getting rid of the crap before and after the project name from integrity
8
- @name = File.basename(Dir.pwd).gsub(/^\w+-|-\w+$/, "")
9
+ # @name = File.basename(Dir.pwd).gsub(/^\w+-|-\w+$/, "")
10
+ @name = Pathname.new(Dir.pwd).basename
9
11
 
10
12
  # Copy Bluff javascripts to output directory
11
- Dir[File.join(this_directory, '..', 'javascripts', '*')].each do |f|
13
+ Dir[File.join(template_directory, '..', 'javascripts', '*')].each do |f|
12
14
  FileUtils.copy(f, File.join(MetricFu.output_directory, File.basename(f)))
13
15
  end
14
16
 
@@ -20,6 +22,8 @@ class AwesomeTemplate < MetricFu::Template
20
22
  html = erbify('layout')
21
23
  fn = output_filename(section)
22
24
  MetricFu.report.save_output(html, MetricFu.output_directory, fn)
25
+ else
26
+ mf_debug "no template for section #{section} with #{template(section)} for report #{report.class}"
23
27
  end
24
28
  end
25
29
 
@@ -29,13 +33,31 @@ class AwesomeTemplate < MetricFu::Template
29
33
  html = erbify('layout')
30
34
  fn = output_filename('index')
31
35
  MetricFu.report.save_output(html, MetricFu.output_directory, fn)
36
+ else
37
+ mf_debug "no template for section index for report #{report.class}"
32
38
  end
33
39
 
34
40
  write_file_data
35
41
  end
36
42
 
43
+ def convert_ruby_to_html(ruby_text)
44
+ # convertor = Syntax::Convertors::HTML.for_syntax('ruby')
45
+ # convertor.convert(ruby_text)
46
+ tokens = CodeRay.scan(ruby_text, :ruby)
47
+ tokens.div( :line_numbers => :table, :css => :class, :style => :alpha )
48
+ # :tab_width – tabulation width in spaces. Default: 8
49
+ # :css – how to include the styles (:class и :style). Default: :class)
50
+ #
51
+ # :wrap – wrap result in html tag :page, :div, :span or not to wrap (nil)
52
+ #
53
+ # :line_numbers – how render line numbers (:table, :inline, :list or nil)
54
+ #
55
+ # :line_number_start – first line number
56
+ #
57
+ # :bold_every – make every n-th line number bold. Default: 10
58
+ # CodeRay, as Syntax may be used to analyze source code, because object Tokens is a list of tokens with specified types.
59
+ end
37
60
  def write_file_data
38
- convertor = Syntax::Convertors::HTML.for_syntax('ruby')
39
61
 
40
62
  per_file_data.each_pair do |file, lines|
41
63
  data = File.open(file, 'r').readlines
@@ -56,7 +78,7 @@ class AwesomeTemplate < MetricFu::Template
56
78
  out << "&nbsp;"
57
79
  end
58
80
  out << "</td>"
59
- line_for_display = MetricFu.configuration.syntax_highlighting ? convertor.convert(line) : line
81
+ line_for_display = MetricFu.configuration.syntax_highlighting ? convert_ruby_to_html(line) : line
60
82
  out << "<td valign='top'><a name='line#{idx + 1}'>#{line_for_display}</a></td>"
61
83
  out << "</tr>"
62
84
  end
@@ -65,8 +87,7 @@ class AwesomeTemplate < MetricFu::Template
65
87
  MetricFu.report.save_output(out, MetricFu.output_directory, fn)
66
88
  end
67
89
  end
68
-
69
- def this_directory
90
+ def template_directory
70
91
  File.dirname(__FILE__)
71
92
  end
72
93
  end
@@ -3,6 +3,7 @@ class StandardTemplate < MetricFu::Template
3
3
 
4
4
  def write
5
5
  report.each_pair do |section, contents|
6
+ mf_debug section
6
7
  if template_exists?(section)
7
8
  create_instance_var(section, contents)
8
9
  html = erbify(section)
@@ -18,9 +19,8 @@ class StandardTemplate < MetricFu::Template
18
19
  MetricFu.report.save_output(html, MetricFu.output_directory, fn)
19
20
  end
20
21
  end
21
-
22
- def this_directory
22
+ def template_directory
23
23
  File.dirname(__FILE__)
24
24
  end
25
- end
26
25
 
26
+ end
@@ -0,0 +1,36 @@
1
+ require 'rake'
2
+ namespace :metrics do
3
+ desc "Generate all metrics reports"
4
+ task :all do
5
+ STDOUT.sync = true
6
+ MetricFu::Configuration.run {}
7
+ MetricFu.metrics.each {|metric|
8
+ mf_debug "** STARTING METRIC #{metric}"
9
+ MetricFu.report.add(metric)
10
+ mf_debug "** ENDING METRIC #{metric}"
11
+ }
12
+ mf_debug "** SAVING REPORT YAML OUTPUT TO #{MetricFu.base_directory}"
13
+ MetricFu.report.save_output(MetricFu.report.to_yaml,
14
+ MetricFu.base_directory,
15
+ "report.yml")
16
+ mf_debug "** SAVING REPORT DATA OUTPUT TO #{MetricFu.data_directory}"
17
+ MetricFu.report.save_output(MetricFu.report.to_yaml,
18
+ MetricFu.data_directory,
19
+ "#{Time.now.strftime("%Y%m%d")}.yml")
20
+ mf_debug "** SAVING TEMPLATIZED REPORT"
21
+ MetricFu.report.save_templatized_report
22
+
23
+ mf_debug "** PREPARING TO GRAPH"
24
+ MetricFu.graphs.each {|graph|
25
+ mf_debug "** Graphing #{graph} with #{MetricFu.graph_engine}"
26
+ MetricFu.graph.add(graph, MetricFu.graph_engine)
27
+ }
28
+ mf_debug "** GENERATING GRAPH"
29
+ MetricFu.graph.generate
30
+
31
+ if MetricFu.report.open_in_browser?
32
+ mf_debug "** OPENING IN BROWSER FROM #{MetricFu.output_directory}"
33
+ MetricFu.report.show_in_browser(MetricFu.output_directory)
34
+ end
35
+ end
36
+ end