metric_fu 4.1.0 → 4.1.1

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 (62) hide show
  1. data/Gemfile +1 -1
  2. data/HISTORY.md +12 -1
  3. data/README.md +3 -0
  4. data/TODO.md +0 -41
  5. data/lib/metric_fu.rb +9 -1
  6. data/lib/metric_fu/configuration.rb +9 -1
  7. data/lib/metric_fu/initial_requires.rb +11 -11
  8. data/lib/metric_fu/load_files.rb +1 -0
  9. data/lib/metric_fu/metrics/cane/cane.rb +5 -4
  10. data/lib/metric_fu/metrics/cane/cane_bluff_grapher.rb +15 -0
  11. data/lib/metric_fu/metrics/cane/cane_grapher.rb +1 -0
  12. data/lib/metric_fu/metrics/cane/init.rb +1 -0
  13. data/lib/metric_fu/metrics/churn/churn_hotspot.rb +9 -1
  14. data/lib/metric_fu/metrics/flay/flay.rb +0 -2
  15. data/lib/metric_fu/metrics/flay/flay_bluff_grapher.rb +15 -0
  16. data/lib/metric_fu/metrics/flay/flay_gchart_grapher.rb +17 -0
  17. data/lib/metric_fu/metrics/flay/flay_grapher.rb +1 -0
  18. data/lib/metric_fu/metrics/flay/flay_hotspot.rb +18 -1
  19. data/lib/metric_fu/metrics/flay/init.rb +1 -0
  20. data/lib/metric_fu/metrics/flog/flog.rb +6 -4
  21. data/lib/metric_fu/metrics/flog/flog_bluff_grapher.rb +16 -0
  22. data/lib/metric_fu/metrics/flog/flog_gchart_grapher.rb +21 -0
  23. data/lib/metric_fu/metrics/flog/flog_grapher.rb +1 -0
  24. data/lib/metric_fu/metrics/flog/flog_hotspot.rb +13 -1
  25. data/lib/metric_fu/metrics/flog/init.rb +1 -0
  26. data/lib/metric_fu/metrics/hotspots/analysis/analyzed_problems.rb +73 -0
  27. data/lib/metric_fu/metrics/hotspots/analysis/analyzer_tables.rb +116 -0
  28. data/lib/metric_fu/metrics/hotspots/analysis/groupings.rb +21 -0
  29. data/lib/metric_fu/metrics/hotspots/analysis/problems.rb +21 -0
  30. data/lib/metric_fu/metrics/hotspots/analysis/rankings.rb +81 -0
  31. data/lib/metric_fu/metrics/hotspots/hotspot.rb +29 -0
  32. data/lib/metric_fu/metrics/hotspots/hotspot_analyzer.rb +62 -308
  33. data/lib/metric_fu/metrics/hotspots/hotspots.rb +1 -27
  34. data/lib/metric_fu/metrics/rails_best_practices/rails_best_practices_bluff_grapher.rb +15 -0
  35. data/lib/metric_fu/metrics/rails_best_practices/rails_best_practices_gchart_grapher.rb +21 -0
  36. data/lib/metric_fu/metrics/rails_best_practices/rails_best_practices_grapher.rb +1 -0
  37. data/lib/metric_fu/metrics/rcov/rcov_bluff_grapher.rb +15 -0
  38. data/lib/metric_fu/metrics/rcov/rcov_gchart_grapher.rb +17 -0
  39. data/lib/metric_fu/metrics/rcov/rcov_grapher.rb +1 -0
  40. data/lib/metric_fu/metrics/rcov/rcov_hotspot.rb +28 -16
  41. data/lib/metric_fu/metrics/reek/reek_bluff_grapher.rb +20 -0
  42. data/lib/metric_fu/metrics/reek/reek_gchart_grapher.rb +25 -0
  43. data/lib/metric_fu/metrics/reek/reek_grapher.rb +1 -0
  44. data/lib/metric_fu/metrics/reek/reek_hotspot.rb +16 -1
  45. data/lib/metric_fu/metrics/roodi/roodi_bluff_grapher.rb +15 -0
  46. data/lib/metric_fu/metrics/roodi/roodi_gchart_grapher.rb +17 -0
  47. data/lib/metric_fu/metrics/roodi/roodi_grapher.rb +1 -0
  48. data/lib/metric_fu/metrics/roodi/roodi_hotspot.rb +16 -1
  49. data/lib/metric_fu/metrics/saikuro/saikuro_hotspot.rb +13 -1
  50. data/lib/metric_fu/metrics/stats/stats_bluff_grapher.rb +16 -0
  51. data/lib/metric_fu/metrics/stats/stats_gchart_grapher.rb +20 -0
  52. data/lib/metric_fu/metrics/stats/stats_grapher.rb +1 -0
  53. data/lib/metric_fu/metrics/stats/stats_hotspot.rb +1 -1
  54. data/lib/metric_fu/reporting/graphs/engines/bluff.rb +0 -114
  55. data/lib/metric_fu/reporting/graphs/engines/gchart.rb +0 -123
  56. data/lib/metric_fu/run.rb +1 -0
  57. data/lib/metric_fu/version.rb +1 -1
  58. data/metric_fu.gemspec +1 -0
  59. data/spec/metric_fu/metrics/cane/cane_spec.rb +17 -0
  60. data/spec/metric_fu/metrics/hotspots/hotspot_spec.rb +11 -0
  61. data/spec/metric_fu/metrics/hotspots/hotspots_spec.rb +7 -0
  62. metadata +180 -134
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gem 'rake'
4
4
  group :development, :test do
data/HISTORY.md CHANGED
@@ -1,5 +1,16 @@
1
1
  ### Master
2
2
 
3
+ ### MetricFu 4.1.1 / 2013-04-16
4
+
5
+ * Fixes
6
+ * Fix Syck warning in Ruby > 1.9 (Todd A. Jacobs #58, Benjamin Fleischer)
7
+ * Cane parser doesn't blow up when no output returned (Guilherme Souza #55)
8
+ * Fix typo in readme (Paul Elliott #52)
9
+ * Disable Flog and Cane in non-MRI rubies, as they require ripper (Benjamin Fleischer)
10
+ * Refactor hotspots and graph code to live in its own metric (Benjamin Fleischer #54, #60)
11
+ * Use RedCard gem to determine ruby version and ruby engine
12
+ * Fix Gemfile ssl source warning
13
+
3
14
  ### MetricFu 4.1.0 / 2013-03-06
4
15
 
5
16
  * Fix crash in cane when missing readme (Sathish, pull request #51)
@@ -9,7 +20,7 @@
9
20
 
10
21
  * Adding cane metrics (Sathish, pull request #49)
11
22
  * Not yet included in hotspots
12
- * *Removed ruby 1.9 support*
23
+ * *Removed ruby 1.8 support*
13
24
 
14
25
  ### MetricFu 3.0.1 / 2013-03-01
15
26
 
data/README.md CHANGED
@@ -21,8 +21,11 @@ See `metric_fu --help` for more options
21
21
  * For 1.8.7 support, see version 3.0.0 for partial support, or 2.1.3.7.18.1 (where [Semantic Versioning](http://semver.org/) goes to die)
22
22
 
23
23
  * The `japgolly-Saikuro` fork and `metric_fu-roodi` fork are a part of an attempt to get metric_fu working in a modern Ruby environment, specifically compatibility with Ruby 1.9 and Bundler.
24
+
24
25
  * metric_fu no longer runs rcov itself. You may still use rcov metrics as documented below
25
26
 
27
+ * The Cane and Flog metrics are disabled in non-MRI rubies as they depend on ripper
28
+
26
29
  ## Documentation
27
30
 
28
31
  * Cane code quality threshold checking is not included in the hotspots report
data/TODO.md CHANGED
@@ -6,9 +6,6 @@
6
6
 
7
7
  * Move code that references rcov out of
8
8
 
9
- lib/metrics/hotspots/hotspot_analyzer.rb
10
- lib/reporting/graphs/engines/bluff.rb
11
- lib/reporting/graphs/engines/gchart.rb
12
9
  lib/reporting/templates/awesome/css/default.css
13
10
  lib/reporting/templates/awesome/index.html.erb
14
11
  lib/reporting/templates/standard/default.css
@@ -18,10 +15,6 @@
18
15
 
19
16
  lib/configuration.rb
20
17
  lib/metrics/hotspots/analysis/code_issue.rb
21
- lib/metrics/hotspots/analysis/scoring_strategies.rb
22
- lib/metrics/hotspots/hotspot_analyzer.rb
23
- lib/reporting/graphs/engines/bluff.rb
24
- lib/reporting/graphs/engines/gchart.rb
25
18
  lib/reporting/templates/awesome/index.html.erb
26
19
  lib/reporting/templates/standard/index.html.erb
27
20
 
@@ -29,16 +22,12 @@
29
22
 
30
23
  lib/metrics/generator.rb
31
24
  lib/metrics/hotspots/analysis/code_issue.rb
32
- lib/metrics/hotspots/hotspot_analyzer.rb
33
- lib/reporting/graphs/engines/bluff.rb
34
- lib/reporting/graphs/engines/gchart.rb
35
25
  lib/reporting/templates/awesome/index.html.erb
36
26
  lib/reporting/templates/standard/index.html.erb
37
27
 
38
28
  * Move code that references churn out of
39
29
 
40
30
  lib/metrics/hotspots/analysis/code_issue.rb
41
- lib/metrics/hotspots/hotspot_analyzer.rb
42
31
  lib/metrics/hotspots/init.rb
43
32
  lib/reporting/templates/awesome/index.html.erb
44
33
  lib/reporting/templates/standard/index.html.erb
@@ -46,21 +35,13 @@
46
35
  * Move code that references rails_best_practices out of
47
36
 
48
37
  lib/metrics/hotspots/analysis/code_issue.rb
49
- lib/metrics/hotspots/hotspot_analyzer.rb
50
- lib/reporting/graphs/engines/bluff.rb
51
- lib/reporting/graphs/engines/gchart.rb
52
38
  lib/reporting/templates/awesome/index.html.erb
53
39
  lib/reporting/templates/standard/index.html.erb
54
40
 
55
41
 
56
42
  * Move code that references reek out of
57
43
 
58
- lib/data_structures/location.rb
59
44
  lib/metrics/hotspots/analysis/code_issue.rb
60
- lib/metrics/hotspots/analysis/scoring_strategies.rb
61
- lib/metrics/hotspots/hotspot_analyzer.rb
62
- lib/reporting/graphs/engines/bluff.rb
63
- lib/reporting/graphs/engines/gchart.rb
64
45
  lib/reporting/templates/awesome/index.html.erb
65
46
  lib/reporting/templates/standard/index.html.erb
66
47
 
@@ -68,23 +49,17 @@
68
49
  * Move code that references roodi out of
69
50
 
70
51
  lib/metrics/hotspots/analysis/code_issue.rb
71
- lib/metrics/hotspots/hotspot_analyzer.rb
72
- lib/reporting/graphs/engines/bluff.rb
73
- lib/reporting/graphs/engines/gchart.rb
74
52
  lib/reporting/templates/awesome/index.html.erb
75
53
  lib/reporting/templates/standard/index.html.erb
76
54
 
77
55
  * Move code that references saikuro out of
78
56
 
79
57
  lib/metrics/hotspots/analysis/code_issue.rb
80
- lib/metrics/hotspots/hotspot_analyzer.rb
81
58
  lib/reporting/templates/awesome/index.html.erb
82
59
  lib/reporting/templates/standard/index.html.erb
83
60
 
84
61
  * Move code that references stats out of
85
62
 
86
- lib/reporting/graphs/engines/bluff.rb
87
- lib/reporting/graphs/engines/gchart.rb
88
63
  lib/reporting/templates/awesome/index.html.erb
89
64
  lib/reporting/templates/standard/index.html.erb
90
65
 
@@ -98,16 +73,11 @@ lib/reporting/templates/standard/index.html.erb
98
73
 
99
74
  ## Features
100
75
 
101
- * Remove rcov by default
102
- * Either allow user to define a command to run a coverage task or supply a directory with coverage results. We can't predict every test setup to run coverage correctly, but we can analyze results.
103
- * Look into getting everything to run on RubyParser ~> 3
104
76
  * Look into adding
105
77
  * https://github.com/metricfu/code_statistics
106
78
  * brakeman https://github.com/metricfu/brakeman
107
- * cane https://github.com/square/cane
108
79
  * laser https://github.com/metricfu/laser
109
80
  * Add configurable logger to all output streams
110
- * Allow command-line metric_fu to accept parameters, and especially output its version
111
81
  * Color code flog results with scale from: http://jakescruggs.blogspot.com/2008/08/whats-good-flog-score.html
112
82
  * Make running metric_fu on metric_fu less embarrassing
113
83
  * Load all gems at config time so you fail fast if one is missing
@@ -118,21 +88,10 @@ lib/reporting/templates/standard/index.html.erb
118
88
 
119
89
  * Determine how to test metric_fu against codebases that are not metric_fu, to ensure it works on most applications
120
90
  * This is especially true for rails applications
121
- * <strike>Re-organize test files structure to align with changed structure of library files</strike>
122
91
  * Remove / Modify Devver code from the generators/hotspots_spec and base/hotspot_analzyer_spec
123
- * <strike>Don't leave around test artifacts such as the folders './foo' and './is set'</strike>
124
92
 
125
93
  ## Bugs / Fixes
126
94
 
127
- * Fix occasional gem install metric_fu failures such as with ripper in Ruby 1.9
128
- * <strike>Fork roodi and correct the yaml</strike>
129
- * See https://github.com/metricfu/metric_fu/issues/2 about updating gems
130
-
131
- ## Ruby 1.9 compatibility
132
-
133
- * Consider `RUBYOPT='-rpsych'` e.g. from https://github.com/jscruggs/metric_fu/pull/77
134
- * Look into using the sexp_processor for ruby parsing in brakeman https://github.com/presidentbeef/brakeman/blob/cdc85962d589fb37e37ed53333bb0b7bd913e028/lib/ruby_parser/bm_sexp_processor.rb
135
-
136
95
  ## Misc
137
96
 
138
97
  * Determine if CodeIssue is used, else remove it
data/lib/metric_fu.rb CHANGED
@@ -43,9 +43,17 @@ module MetricFu
43
43
  def self.configure
44
44
  MetricFu.lib_require { 'configuration' }
45
45
  init_files = Dir.glob(File.join(MetricFu.metrics_dir, '**/init.rb')).reject do |file|
46
- if file =~ /rcov/
46
+ if file =~ /rcov/o
47
47
  MetricFu.configuration.mf_debug("rcov is not available. See README")
48
48
  true
49
+ elsif MetricFu.configuration.mri?
50
+ false
51
+ elsif file =~ /cane/o
52
+ MetricFu.configuration.mf_debug("Cane is only available in MRI. It requires ripper")
53
+ true
54
+ elsif file =~ /flog/o
55
+ MetricFu.configuration.mf_debug("Flog is only available in MRI. It requires ripper")
56
+ true
49
57
  else
50
58
  false
51
59
  end
@@ -118,6 +118,14 @@ module MetricFu
118
118
  !!ENV['CC_BUILD_ARTIFACTS']
119
119
  end
120
120
 
121
+ def jruby?
122
+ @jruby ||= RedCard.check(:jruby)
123
+ end
124
+
125
+ def mri?
126
+ @mri ||= RedCard.check(:ruby)
127
+ end
128
+
121
129
  def platform #:nodoc:
122
130
  # TODO, change
123
131
  # RbConfig::CONFIG['ruby_install_name'].dup
@@ -125,7 +133,7 @@ module MetricFu
125
133
  end
126
134
 
127
135
  def self.ruby_strangely_makes_accessors_private?
128
- !!(RUBY_VERSION =~ /1.9.2/) || defined?(JRUBY_VERSION)
136
+ RedCard.check('1.9.2') || jruby?
129
137
  end
130
138
  protected unless ruby_strangely_makes_accessors_private?
131
139
 
@@ -1,17 +1,17 @@
1
1
  require 'rake'
2
+
2
3
  require 'yaml'
3
- begin
4
- require 'psych'
5
- YAML::ENGINE.yamler = 'syck'
6
- rescue LoadError
7
- #nothing to report
4
+ require 'redcard'
5
+
6
+ # Psych is not defined in Ruby < 1.9
7
+ if defined?(Psych)
8
+ # Syck is not available in Ruby > 1.9 or JRuby 1.9
9
+ if defined?(Syck) && !RedCard.check(:jruby)
10
+ YAML::ENGINE.yamler = 'syck'
11
+ end
8
12
  end
9
- # def with_syck(&block)
10
- # current_engine = YAML::ENGINE.yamler
11
- # YAML::ENGINE.yamler = 'syck'
12
- # block.call
13
- # YAML::ENGINE.yamler = current_engine
14
- # end
13
+
14
+
15
15
  begin
16
16
  require 'active_support'
17
17
  require 'active_support/core_ext/object/to_json'
@@ -1,5 +1,6 @@
1
1
  # require these first because others depend on them
2
2
  MetricFu.reporting_require { 'report' }
3
+ MetricFu.metrics_require { 'hotspots/hotspot' }
3
4
  MetricFu.metrics_require { 'generator' }
4
5
  MetricFu.metrics_require { 'graph' }
5
6
  MetricFu.reporting_require { 'graphs/grapher' }
@@ -1,5 +1,3 @@
1
- require 'cane'
2
-
3
1
  module MetricFu
4
2
  class Cane < Generator
5
3
  attr_reader :violations, :total_violations
@@ -76,8 +74,11 @@ module MetricFu
76
74
  end
77
75
 
78
76
  def extract_total_violations
79
- total = @output.match(/Total Violations: (\d+)/)[1]
80
- @total_violations = total.to_i if total
77
+ if @output =~ /Total Violations: (\d+)/
78
+ @total_violations = $1.to_i
79
+ else
80
+ @total_violations = 0
81
+ end
81
82
  end
82
83
  end
83
84
  end
@@ -0,0 +1,15 @@
1
+ MetricFu.metrics_require { 'cane/cane_grapher' }
2
+ module MetricFu
3
+ class CaneBluffGrapher < CaneGrapher
4
+ def graph!
5
+ content = <<-EOS
6
+ #{BLUFF_DEFAULT_OPTIONS}
7
+ g.title = 'Cane: code quality threshold violations';
8
+ g.data('cane', [#{@cane_violations.join(',')}]);
9
+ g.labels = #{@labels.to_json};
10
+ g.draw();
11
+ EOS
12
+ File.open(File.join(MetricFu.output_directory, 'cane.js'), 'w') {|f| f << content }
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,4 @@
1
+ MetricFu.reporting_require { 'graphs/grapher' }
1
2
  module MetricFu
2
3
  class CaneGrapher < Grapher
3
4
  attr_accessor :cane_violations, :labels
@@ -1,4 +1,5 @@
1
1
  MetricFu::Configuration.run do |config|
2
+ require 'cane'
2
3
  config.add_metric(:cane)
3
4
  config.add_graph(:cane)
4
5
  config.configure_metric(:cane, {
@@ -1,4 +1,4 @@
1
- class ChurnHotspot
1
+ class ChurnHotspot < MetricFu::Hotspot
2
2
  include MetricFu::HotspotScoringStrategies
3
3
 
4
4
  COLUMNS = %w{times_changed}
@@ -35,4 +35,12 @@ class ChurnHotspot
35
35
  end
36
36
  end
37
37
 
38
+ def present_group(group)
39
+ "detected high level of churn (changed #{group[0].times_changed} times)"
40
+ end
41
+
42
+ def present_group_details(group)
43
+ "detected high level of churn (changed #{group[0].times_changed} times)"
44
+ end
45
+
38
46
  end
@@ -1,5 +1,3 @@
1
- require 'flay'
2
-
3
1
  module MetricFu
4
2
 
5
3
  class Flay < Generator
@@ -0,0 +1,15 @@
1
+ MetricFu.metrics_require { 'flay/flay_grapher' }
2
+ module MetricFu
3
+ class FlayBluffGrapher < FlayGrapher
4
+ def graph!
5
+ content = <<-EOS
6
+ #{BLUFF_DEFAULT_OPTIONS}
7
+ g.title = 'Flay: duplication';
8
+ g.data('flay', [#{@flay_score.join(',')}]);
9
+ g.labels = #{@labels.to_json};
10
+ g.draw();
11
+ EOS
12
+ File.open(File.join(MetricFu.output_directory, 'flay.js'), 'w') {|f| f << content }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ MetricFu.metrics_require { 'flay/flay_grapher' }
2
+ module MetricFu
3
+ class FlayGchartGrapher < FlayGrapher
4
+ def graph!
5
+ determine_y_axis_scale(@flay_score)
6
+ url = Gchart.line(
7
+ :size => GCHART_GRAPH_SIZE,
8
+ :title => URI.escape("Flay: duplication"),
9
+ :data => @flay_score,
10
+ :max_value => @max_value,
11
+ :axis_with_labels => 'x,y',
12
+ :axis_labels => [@labels.values, @yaxis],
13
+ :format => 'file',
14
+ :filename => File.join(MetricFu.output_directory, 'flay.png'))
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,4 @@
1
+ MetricFu.reporting_require { 'graphs/grapher' }
1
2
  module MetricFu
2
3
  class FlayGrapher < Grapher
3
4
  attr_accessor :flay_score, :labels
@@ -1,4 +1,4 @@
1
- class FlayHotspot
1
+ class FlayHotspot < MetricFu::Hotspot
2
2
  include MetricFu::HotspotScoringStrategies
3
3
 
4
4
  COLUMNS = %w{flay_reason flay_matching_reason}
@@ -47,4 +47,21 @@ class FlayHotspot
47
47
  end
48
48
  end
49
49
 
50
+ def present_group(group)
51
+ occurences = group.size
52
+ "found #{occurences} code duplications"
53
+ end
54
+
55
+ def present_group_details(group)
56
+ occurences = group.size
57
+ message = "found #{occurences} code duplications<br/>"
58
+ group.each do |item|
59
+ problem = item.data["flay_reason"]
60
+ problem = problem.gsub(/^[0-9]*\)/,'')
61
+ problem = problem.gsub(/files\:/,' <br>&nbsp;&nbsp;&nbsp;files:')
62
+ message << "* #{problem}<br/>"
63
+ end
64
+ message
65
+ end
66
+
50
67
  end
@@ -1,4 +1,5 @@
1
1
  MetricFu::Configuration.run do |config|
2
+ require 'flay'
2
3
  config.add_metric(:flay)
3
4
  config.add_graph(:flay)
4
5
  config.configure_metric(:flay,
@@ -1,7 +1,6 @@
1
1
  require 'pathname'
2
2
  require 'optparse'
3
3
  require 'rbconfig'
4
- require 'flog'
5
4
  class RubyParser
6
5
  alias_method :original_process, :process
7
6
  def process(s,f,t)
@@ -33,9 +32,12 @@ module MetricFu
33
32
  @flogger = ::Flog.new options
34
33
  @flogger.flog files
35
34
 
36
- rescue LoadError
37
- if defined?(JRUBY_VERSION)
38
- puts 'running in jruby - flog tasks not available'
35
+ rescue LoadError => e
36
+ message = "#{e.class}\t#{e.message}\n\t#{e.backtrace.join('\n\t')}"
37
+ if MetricFu.configuration.mri?
38
+ puts "Flog Error: #{message}"
39
+ else
40
+ puts "Flog tasks only available in MRI: #{message}"
39
41
  end
40
42
  end
41
43
 
@@ -0,0 +1,16 @@
1
+ MetricFu.metrics_require { 'flog/flog_grapher' }
2
+ module MetricFu
3
+ class FlogBluffGrapher < FlogGrapher
4
+ def graph!
5
+ content = <<-EOS
6
+ #{BLUFF_DEFAULT_OPTIONS}
7
+ g.title = 'Flog: code complexity';
8
+ g.data('average', [#{@flog_average.join(',')}]);
9
+ g.data('top 5% average', [#{@top_five_percent_average.join(',')}])
10
+ g.labels = #{@labels.to_json};
11
+ g.draw();
12
+ EOS
13
+ File.open(File.join(MetricFu.output_directory, 'flog.js'), 'w') {|f| f << content }
14
+ end
15
+ end
16
+ end