metric_fu 4.3.1 → 4.4.0

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 (88) hide show
  1. checksums.yaml +7 -0
  2. data/.metrics +55 -26
  3. data/.travis.yml +4 -1
  4. data/AUTHORS +12 -0
  5. data/Gemfile +1 -0
  6. data/HISTORY.md +24 -0
  7. data/README.md +27 -22
  8. data/checksum/metric_fu-4.3.1.gem.sha512 +1 -0
  9. data/checksum/metric_fu-4.4.0.gem.sha512 +1 -0
  10. data/lib/metric_fu.rb +28 -79
  11. data/lib/metric_fu/cli/helper.rb +1 -1
  12. data/lib/metric_fu/cli/parser.rb +1 -1
  13. data/lib/metric_fu/configuration.rb +104 -150
  14. data/lib/metric_fu/environment.rb +88 -0
  15. data/lib/metric_fu/formatter.rb +23 -0
  16. data/lib/metric_fu/formatter/html.rb +12 -9
  17. data/lib/metric_fu/initial_requires.rb +1 -0
  18. data/lib/metric_fu/io.rb +60 -1
  19. data/lib/metric_fu/load_files.rb +4 -2
  20. data/lib/metric_fu/loader.rb +62 -0
  21. data/lib/metric_fu/metric.rb +102 -0
  22. data/lib/metric_fu/metrics/base_template.rb +15 -9
  23. data/lib/metric_fu/metrics/cane/cane.rb +9 -5
  24. data/lib/metric_fu/metrics/cane/init.rb +35 -13
  25. data/lib/metric_fu/metrics/churn/churn.rb +5 -1
  26. data/lib/metric_fu/metrics/churn/init.rb +24 -4
  27. data/lib/metric_fu/metrics/flay/flay.rb +7 -3
  28. data/lib/metric_fu/metrics/flay/init.rb +29 -13
  29. data/lib/metric_fu/metrics/flay/template_awesome/flay.html.erb +1 -1
  30. data/lib/metric_fu/metrics/flog/flog.rb +14 -38
  31. data/lib/metric_fu/metrics/flog/init.rb +30 -7
  32. data/lib/metric_fu/metrics/generator.rb +21 -6
  33. data/lib/metric_fu/metrics/graph.rb +2 -2
  34. data/lib/metric_fu/metrics/hotspots/hotspots.rb +5 -1
  35. data/lib/metric_fu/metrics/hotspots/init.rb +21 -5
  36. data/lib/metric_fu/metrics/rails_best_practices/init.rb +29 -5
  37. data/lib/metric_fu/metrics/rails_best_practices/rails_best_practices.rb +20 -27
  38. data/lib/metric_fu/metrics/rails_best_practices/template_awesome/rails_best_practices.html.erb +1 -1
  39. data/lib/metric_fu/metrics/rcov/init.rb +40 -15
  40. data/lib/metric_fu/metrics/rcov/rcov.rb +15 -10
  41. data/lib/metric_fu/metrics/reek/init.rb +25 -6
  42. data/lib/metric_fu/metrics/reek/reek.rb +52 -31
  43. data/lib/metric_fu/metrics/reek/template_awesome/reek.html.erb +1 -1
  44. data/lib/metric_fu/metrics/roodi/init.rb +25 -6
  45. data/lib/metric_fu/metrics/roodi/roodi.rb +7 -3
  46. data/lib/metric_fu/metrics/saikuro/init.rb +22 -6
  47. data/lib/metric_fu/metrics/saikuro/saikuro.rb +8 -3
  48. data/lib/metric_fu/metrics/stats/init.rb +28 -5
  49. data/lib/metric_fu/metrics/stats/stats.rb +24 -6
  50. data/lib/metric_fu/metrics/stats/template_awesome/stats.html.erb +2 -2
  51. data/lib/metric_fu/parser_ext.rb +15 -0
  52. data/lib/metric_fu/reporting/graphs/engines/gchart.rb +1 -1
  53. data/lib/metric_fu/reporting/graphs/engines/init.rb +18 -4
  54. data/lib/metric_fu/reporting/graphs/grapher.rb +1 -1
  55. data/lib/metric_fu/reporting/result.rb +13 -6
  56. data/lib/metric_fu/reporting/templates/awesome/awesome_template.rb +1 -1
  57. data/lib/metric_fu/run.rb +7 -10
  58. data/lib/metric_fu/sexp_ext.rb +11 -0
  59. data/lib/metric_fu/version.rb +1 -1
  60. data/metric_fu.gemspec +23 -20
  61. data/spec/cli/helper_spec.rb +5 -16
  62. data/spec/metric_fu/configuration_spec.rb +62 -88
  63. data/spec/metric_fu/formatter/html_spec.rb +26 -16
  64. data/spec/metric_fu/formatter/yaml_spec.rb +2 -2
  65. data/spec/metric_fu/metric_spec.rb +50 -0
  66. data/spec/metric_fu/metrics/base_template_spec.rb +9 -7
  67. data/spec/metric_fu/metrics/cane/cane_spec.rb +19 -24
  68. data/spec/metric_fu/metrics/churn/churn_spec.rb +8 -8
  69. data/spec/metric_fu/metrics/flay/flay_spec.rb +7 -13
  70. data/spec/metric_fu/metrics/flog/flog_spec.rb +63 -58
  71. data/spec/metric_fu/metrics/generator_spec.rb +4 -0
  72. data/spec/metric_fu/metrics/hotspots/hotspots_spec.rb +7 -7
  73. data/spec/metric_fu/metrics/rails_best_practices/rails_best_practices_spec.rb +14 -33
  74. data/spec/metric_fu/metrics/rcov/rcov_spec.rb +17 -18
  75. data/spec/metric_fu/metrics/reek/reek_spec.rb +9 -10
  76. data/spec/metric_fu/metrics/roodi/roodi_spec.rb +5 -11
  77. data/spec/metric_fu/metrics/saikuro/saikuro_spec.rb +15 -14
  78. data/spec/metric_fu/metrics/stats/stats_spec.rb +5 -6
  79. data/spec/metric_fu/reporting/graphs/engines/bluff_spec.rb +2 -3
  80. data/spec/metric_fu/reporting/graphs/engines/gchart_spec.rb +12 -9
  81. data/spec/metric_fu/reporting/result_spec.rb +3 -3
  82. data/spec/run_spec.rb +45 -29
  83. data/spec/spec_helper.rb +7 -0
  84. data/spec/support/helper_methods.rb +9 -0
  85. data/spec/support/suite.rb +17 -11
  86. metadata +59 -56
  87. data/bin/mf-rails_best_practices +0 -9
  88. data/bin/mf-stats +0 -7
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 741f0378823b8b42fce3ad9e4bc36b0312988660
4
+ data.tar.gz: 66dce50c5876c8dc84d672e5ed5571e6e9854dd5
5
+ SHA512:
6
+ metadata.gz: fc38e9dfd106e6f8c92d9f044a3ee1d9d192d6ae3de367b871efa70bc40bd7c67f877f6bc9628440c05094284eb333a635d96c9626e05f2e79f6be4aacd79b14
7
+ data.tar.gz: 1487b7c82f5f8bf932bbd81b1b538fdd0bf03216fd32af2b3c3f294c7d83edd808cae889f827b1c4e0b788667593f2d0f9e159ce149beb7396b1cd29bd270267
data/.metrics CHANGED
@@ -3,34 +3,63 @@
3
3
  # For testing that this file gets loaded
4
4
  $metric_file_loaded = true
5
5
 
6
- # example configuration
7
- # MetricFu::Configuration.run do |config|
8
- # coverage_file = File.expand_path("coverage/rcov/rcov.txt", Dir.pwd)
9
- # config.add_metric(:rcov)
10
- # config.add_graph(:rcov)
11
- # config.configure_metric(:rcov, {:external => coverage_file})
12
- # config.cane = {:abc_max => 15, :line_length => 80, :no_doc => 'y', :no_readme => 'y'}
13
- # end
14
- # or
6
+ # Example Configuration
7
+ #
15
8
  # MetricFu::Configuration.run do |config|
16
- # config.metrics -= [ :rcov ]
17
- # end
18
- # you may enable running rcov manually with
19
- # MetricFu.run_rcov
20
9
  #
21
- # By default, metric_fu will use the built-in html formatter
22
- # to generate HTML reports for each metric with pretty graphs.
10
+ # Configure Metrics
11
+ #
12
+ # To configure individual metrics...
13
+ #
14
+ # config.configure_metric(:rcov) do |rcov|
15
+ # rcov.enabled = true
16
+ # coverage_file = File.expand_path("coverage/rcov/rcov.txt", Dir.pwd)
17
+ # rcov.external = coverage_file
18
+ # end
19
+ #
20
+ # config.configure_metric(:cane) do |cane|
21
+ # cane.enabled = true
22
+ # cane.abc_max = 15
23
+ # cane.line_length = 80
24
+ # cane.no_doc = 'y'
25
+ # cane.no_readme = 'y'
26
+ # end
27
+ #
28
+ # Or, to configure a group of metrics...
29
+ # config.configure_metrics.each do |metric|
30
+ # if [:churn, :flay, :flog].include?(metric.name)
31
+ # metric.enabled = true
32
+ # else
33
+ # metric.enabled = false
34
+ # end
35
+ # end
36
+ #
37
+ #
38
+ # Configure Formatters
39
+ #
40
+ # By default, metric_fu will use the built-in html formatter
41
+ # to generate HTML reports for each metric with pretty graphs.
23
42
 
24
- # To configure different formatter(s) or output ...
25
- # MetricFu::Configuration.run do |config|
26
- # config.add_formatter(:html)
27
- # config.add_formatter(:yaml, "customreport.yml")
28
- # config.add_formatter(MyCustomFormatter)
29
- # end
43
+ # To configure different formatter(s) or output ...
44
+ #
45
+ # config.configure_formatter(:html)
46
+ # config.configure_formatter(:yaml, "customreport.yml")
47
+ # config.configure_formatter(MyCustomFormatter)
48
+ #
49
+ # MetricFu will attempt to require a custom formatter by
50
+ # fully qualified name based on ruby search path,
51
+ # but you may find that you need to add a require above.
30
52
  #
31
- # metric_fu will attempt to require a custom formatter by
32
- # fully qualified name based on ruby search path,
33
- # but you may find that you need to add a require above.
53
+ # For instance, to require a formatter in your app's lib directory, add the
54
+ # following line to the top of this file.
55
+ # require './lib/my_custom_formatter.rb'
34
56
  #
35
- # For instance, to require a formatter in your app's lib directory:
36
- # require './lib/my_custom_formatter.rb'
57
+ #
58
+ # Configure Graph Engine
59
+ #
60
+ # By default, metric_fu uses the bluff graph engine.
61
+ # To configure a different graph engine...
62
+ #
63
+ # config.configure_graph_engine(:gchart)
64
+ #
65
+ # end
data/.travis.yml CHANGED
@@ -9,6 +9,9 @@ gemfile:
9
9
  rvm:
10
10
  - 2.0.0
11
11
  - 1.9.3
12
- - 1.9.2
12
+ # - 1.9.2 # code_metric 0.1.0 requires ruby 1.9.3 or greater
13
13
  - jruby-19mode # JRuby in 1.9 mode
14
14
  - rbx-19mode
15
+ # matrix:
16
+ # allow_failures:
17
+ # - rvm: rbx-19mode
data/AUTHORS ADDED
@@ -0,0 +1,12 @@
1
+ Jake Scruggs
2
+ Sean Soper
3
+ Andre Arko
4
+ Petrik de Heus
5
+ Grant McInnes
6
+ Nick Quaranto
7
+ Édouard Brière
8
+ Carl Youngblood
9
+ Richard Huang
10
+ Dan Mayer
11
+ Benjamin Fleischer
12
+ Robin Curry
data/Gemfile CHANGED
@@ -15,5 +15,6 @@ group :test do
15
15
  gem 'simplecov-rcov-text'
16
16
  end
17
17
  gem "fakefs", :require => "fakefs/safe"
18
+ gem 'json'
18
19
  end
19
20
  gemspec :path => File.expand_path('..', __FILE__)
data/HISTORY.md CHANGED
@@ -10,6 +10,30 @@ As such, a _Feature_ would map to either major or minor. A _bug fix_ to a patch.
10
10
  * Fixes
11
11
  * Misc
12
12
 
13
+ ### MetricFu 4.4.0 / 2013-08-15
14
+
15
+ * Features
16
+ * Metrics now configure themselves in a subclass of MetricFu::Metric ( Benjamin Fleischer / Robin Curry #91, #111)
17
+ * Metrics can be configured individually via Metric.configuration.configure_metric(:some_metric) or Metric.configuration.configure_metrics {|metric| }. See .metrics file for examples ( Benjamin Fleischer / Robin Curry #91, #111)
18
+ * Distinguish between an activated metric library and an enabled metric.
19
+ * An enabled metric will be run.
20
+ * An activated metric has had its library successfully required. (Benjamin Fleischer #125)
21
+ * Code Statistics metrics always runs now, relies on the code_metrics gem extracted from Rails. Does not shell out. ( Benjamin Fleischer, #108 )
22
+ * Rails Best Practices report now provides a link to the description and solution of the problem (Calveto #117)
23
+ * Rails Best Practices now runs as a library. It is no longer shelled out. (Calveto #117)
24
+ * Update flog to ~> 4.1.1, this is needed to use keyword parameters in ruby 2. (George Erickson, #122)
25
+ * Fixes
26
+ * Skip reek when no files are found to run against. Otherwise, reek hangs trying to read from STDIN (Benjamin Fleischer, #119, #121)
27
+ * Reek will now find files on Windows. Remove *nix-specific '/' directory separators from Reek file glob. (Benjamin Fleischer, #119, #121)
28
+ * Link to correct reek url on report. (Calveto #116)
29
+ * Hack to accomodate Rails Best Practices dependency Code Analyzer monkey patch of Sexp (Benjamin Fleischer #123, #124)
30
+ * Misc
31
+ * Moved environmental concerns into an Environment module ( Benjamin Fleischer / Robin Curry #91, #111)
32
+ * Exposed RubyParser patch ( Benjamin Fleischer / Robin Curry #91, #111)
33
+ * Separated out io / filesystem /templating concerns into their own classes or modules. Thus, we removed all the metaprogrammatically defined methods and instance variables.( Benjamin Fleischer / Robin Curry #91, #111, #112, #115)
34
+ * Generator subclasses can now be found by metric name. MetricFu::Generator.get_generator(:flog) (Benjamin Fleischer, #126)
35
+ * Breaking change related to the above: removed configuration methods / MetricFu module methods: add_graph, add_metric, configure_graph, configure_metric, configure_graph_engine, graph_engine, metrics, formatters, graphs, graph_engines, rails?, code_dirs, base_directory, scratch_directory, output_directory, data_directory, file_globs_to_ignore, metric_fu_root_directory, template_directory, template_class, link_prefix, darwin_txmt_protocol_no_thanks, syntax_highlighting
36
+
13
37
  ### MetricFu 4.3.1 / 2013-08-02
14
38
 
15
39
  * Features
data/README.md CHANGED
@@ -1,7 +1,9 @@
1
- # MetricFu [![Gem Version](https://badge.fury.io/rb/metric_fu.png)](http://badge.fury.io/rb/metric_fu) [![Build Status](https://travis-ci.org/metricfu/metric_fu.png?branch=master)](http://travis-ci.org/metricfu/metric_fu) [Rdoc](http://rdoc.info/github/metricfu/metric_fu/)
1
+ # MetricFu [![Gem Version](https://badge.fury.io/rb/metric_fu.png)](http://badge.fury.io/rb/metric_fu) [![Build Status](https://travis-ci.org/metricfu/metric_fu.png?branch=master)](http://travis-ci.org/metricfu/metric_fu)
2
2
 
3
3
  [![Code Climate](https://codeclimate.com/github/metricfu/metric_fu.png)](https://codeclimate.com/github/metricfu/metric_fu) [![Dependency Status](https://gemnasium.com/metricfu/metric_fu.png)](https://gemnasium.com/metricfu/metric_fu)
4
4
 
5
+ [Rdoc](http://rdoc.info/github/metricfu/metric_fu/)
6
+
5
7
  ## Metrics
6
8
 
7
9
  * [Cane](https://rubygems.org/gems/cane), [Source](http://github.com/square/cane)
@@ -10,13 +12,13 @@
10
12
  * [Flay](https://rubygems.org/gems/flay), [Source](https://github.com/seattlerb/flay)
11
13
  * [Reek](https://rubygems.org/gems/reek) [Source](https://github.com/troessner/reek)
12
14
  * [Roodi](https://rubygems.org/gems/metric_fu-roodi), [Source](https://github.com/metricfu/roodi)
13
- * [Saikuro](https://rubygems.org/gems/japgolly-Saikuro), [Source](https://github.com/japgolly/Saikuro)
15
+ * [Saikuro](https://rubygems.org/gems/metric_fu-Saikuro), [Source](https://github.com/metricfu/Saikuro)
16
+ [Code Statistics](https://rubygems.org/gems/code_metrics), [Source](https://github.com/bf4/code_metrics) )
14
17
  * Rails-only
15
18
  * [Rails Best Practices](https://rubygems.org/gems/rails_best_practices), [Source](https://github.com/railsbp/rails_best_practices)
16
- * Rails `rake stats` task (see [gem](https://rubygems.org/gems/code_statistics), [Source](https://github.com/danmayer/code_statistics) )
17
19
  * Test Coverage
18
20
  * 1.9: [SimpleCov](http://rubygems.org/gems/simplecov) and [SimpleCov-Rcov-Text](http://rubygems.org/gems/simplecov-rcov-text)
19
- * 1.8 [Rcov](http://rubygems.org/gems/rcov)
21
+ * 1.8: [Rcov](http://rubygems.org/gems/rcov)
20
22
  * Hotspots (a meta-metric of the above)
21
23
 
22
24
  ## Installation
@@ -29,25 +31,25 @@ See documentation on the rubyforge page for how to customize your metrics. Other
29
31
 
30
32
  ## Usage
31
33
 
32
- By default, you can run all metrics from the root of an app with the command `metric_fu -r`
34
+ By default, you can run all metrics from the root of an app with the command `metric_fu`
33
35
 
34
36
  See `metric_fu --help` for more options
35
37
 
36
38
  ## Compatibility
37
39
 
38
- * It is currently testing on MRI 1.9.2, 1.9.3 and 2.0.0. Ruby 1.8 is no longer supported due to the cane library.
40
+ * It is currently testing on MRI (1.9.3 and 2.0.0), JRuby (19 mode), and Rubinius (19 mode). Ruby 1.8 is no longer supported due to the cane library.
39
41
 
40
42
  * 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)
41
43
 
42
- * 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.
44
+ * The `metric_fu-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.
43
45
 
44
46
  * metric_fu no longer runs rcov itself. You may still use rcov metrics as documented below
45
47
 
46
- * The Cane, Flog, and Rails Best Practices metrics are disabled in non-MRI rubies as they depend on ripper
48
+ * The Cane, Flog, and Rails Best Practices metrics are disabled when Ripper is not available
47
49
 
48
50
  ## Documentation
49
51
 
50
- * Cane code quality threshold checking is not included in the hotspots report
52
+ *[See wiki](https://github.com/metricfu/metric_fu/wiki#usage)
51
53
 
52
54
  ## Formatters
53
55
 
@@ -115,15 +117,14 @@ see the .metrics file
115
117
  in your .metrics file add the below to run pre-generated metrics
116
118
 
117
119
  MetricFu::Configuration.run do |config|
118
- coverage_file = File.expand_path("coverage/rcov/rcov.txt", Dir.pwd)
119
- config.add_metric(:rcov)
120
- config.add_graph(:rcov)
121
- config.configure_metric(:rcov, {:external => coverage_file})
120
+ config.configure_metric(:rcov) do |rcov|
121
+ rcov.enabled = true
122
+ coverage_file = File.expand_path("coverage/rcov/rcov.txt", Dir.pwd)
123
+ rcov.external = coverage_file
124
+ end
122
125
  end
123
126
 
124
- if you want metric_fu to actually run rcov itself (1.8 only), just add
125
-
126
- MetricFu.run_rcov
127
+ If you want metric_fu to actually run rcov itself (1.8 only), don't specify an external file to read from
127
128
 
128
129
  #### Rcov metrics with Ruby 1.8
129
130
 
@@ -156,19 +157,23 @@ There is some useful-but-out-of-date documentation about configuring metric_fu a
156
157
 
157
158
  See the TODO for some ideas
158
159
 
159
- See CONTRIBUTING for how to contribute
160
+ See [CONTRIBUTING](https://github.com/metricfu/metric_fu/blob/master/CONTRIBUTING.md) for how to contribute
160
161
 
161
162
  ## Resources:
162
163
 
163
- This is the official repository for metric_fu. The original repository by Jake Scruggs at [https://github.com/jscruggs/metric_fu](https://github.com/jscruggs/metric_fu) [has been deprecated.](http://jakescruggs.blogspot.com/2012/08/why-i-abandoned-metricfu.html).
164
+ This is the official repository for metric_fu. The original repository by Jake Scruggs at [https://github.com/jscruggs/metric_fu](https://github.com/jscruggs/metric_fu) has been deprecated.
164
165
 
165
- * Github: http://github.com/metricfu/metric_fu
166
- * Issue Tracker: http://github.com/metricfu/metric_fu/issues
167
- * Google Group: http://groups.google.com/group/metric_fu
168
- * Historical Homepage: http://metric-fu.rubyforge.org/
166
+ * [Official Repository](http://github.com/metricfu/metric_fu)
167
+ * [Issue Tracker](http://metricfu.github.io/metric_fu/)
168
+ * [Google Group](http://metricfu.github.io/metric_fu/)
169
+ * [Outdated Homepage](http://metricfu.github.io/metric_fu/)
170
+ * [List of code tools](https://github.com/metricfu/metric_fu/wiki/Code-Tools)
171
+ * [Roadmap](https://github.com/metricfu/metric_fu/wiki/Roadmap)
169
172
 
170
173
  ### Original Resources:
171
174
 
172
175
  * Github: http://github.com/jscruggs/metric_fu
173
176
  * Issue Tracker: http://github.com/jscruggs/metric_fu/issues
177
+ * Historical Homepage: http://metric-fu.rubyforge.org/
174
178
  * Jake's Blog: http://jakescruggs.blogspot.com/
179
+ * Jake's Post about stepping down: http://jakescruggs.blogspot.com/2012/08/why-i-abandoned-metricfu.html
@@ -0,0 +1 @@
1
+ 8ceae4f1bb2719d8ecbe2c7b3e929fe477cbe4ea6582297092a1bc09a6bef9e423f3a33c619b62372b208f956c4d8f9839257cd491475b58c06a2c8341eafc77
@@ -0,0 +1 @@
1
+ 1f9be27229b5a441bc4e4367d099f6f92641d994246b88f9a396fc8c99d832a00412fe7c9a5dc5078c9beecc8d77d575d9b9ab55b50ab7b0b7583130763369bf
data/lib/metric_fu.rb CHANGED
@@ -1,98 +1,47 @@
1
+ require 'metric_fu/version'
1
2
  module MetricFu
2
3
  APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__),'..'))
3
4
  LIB_ROOT = File.join(APP_ROOT,'lib/metric_fu')
4
- @loaded_files = []
5
- class << self
6
- attr_reader :loaded_files
7
- end
8
- def self.lib_require(base='',&block)
9
- paths = []
10
- base_path = File.join(LIB_ROOT, base)
11
- Array((yield paths, base_path)).each do |path|
12
- file = File.join(base_path, *Array(path))
13
- require file
14
- if @loaded_files.include?(file)
15
- puts "!!!\tAlready loaded #{file}" if !!(ENV['MF_DEBUG'] =~ /true/i)
16
- else
17
- @loaded_files << file
18
- end
19
- end
20
- end
21
5
  def self.root_dir
22
6
  APP_ROOT
23
7
  end
24
8
  def self.lib_dir
25
9
  LIB_ROOT
26
10
  end
27
- class << self
28
- %w(metrics formatter reporting logging errors data_structures tasks).each do |dir|
29
- define_method("#{dir}_dir") do
30
- File.join(lib_dir,dir)
31
- end
32
- module_eval(%Q(def #{dir}_require(&block); lib_require('#{dir}', &block); end))
33
- end
11
+
12
+ require 'metric_fu/loader'
13
+ LOADER = MetricFu::Loader.new(LIB_ROOT)
14
+ def self.lib_require(base='',&block)
15
+ LOADER.lib_require(base,&block)
34
16
  end
35
- def self.tasks_load(tasks_relative_path)
36
- load File.join(LIB_ROOT, 'tasks', *Array(tasks_relative_path))
17
+
18
+ LOADER.create_dirs(self) do
19
+ %w(metrics formatter reporting logging errors data_structures tasks)
37
20
  end
38
- # path is relative to where the task is being run,
21
+
22
+ # @note artifact_dir is relative to where the task is being run,
39
23
  # not to the metric_fu library
24
+ require 'metric_fu/io'
40
25
  def self.artifact_dir
41
- (ENV['CC_BUILD_ARTIFACTS'] || 'tmp/metric_fu')
42
- end
43
- def self.configure
44
- MetricFu.lib_require { 'configuration' }
45
- init_files = Dir.glob(File.join(MetricFu.metrics_dir, '**/init.rb')).reject do |file|
46
- if file =~ /rcov/o
47
- MetricFu.configuration.mf_debug("rcov is not available. See README")
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
57
- elsif file =~ /rails_best_practices/o
58
- MetricFu.configuration.mf_debug("Rails Best Practices only available in MRI. It requires ripper")
59
- true
60
- else
61
- false
62
- end
63
- end
64
- init_files.each do |file|
65
- load file
66
- end
67
- MetricFu.configuration
26
+ MetricFu::Io::FileSystem.artifact_dir
68
27
  end
69
- def self.mri_only_metrics
70
- if MetricFu.configuration.mri?
71
- []
72
- else
73
- [:cane, :flog, :rails_best_practices]
74
- end
75
- end
76
- def self.run_rcov
77
- load File.join(MetricFu.metrics_dir, 'rcov/init.rb')
28
+
29
+ LOADER.create_artifact_subdirs(self) do
30
+ %w(scratch output _data)
78
31
  end
79
- def self.skip_rcov
80
- MetricFu.metrics -= [:rcov]
81
- MetricFu.graphs -= [:rcov]
32
+
33
+ def self.tasks_load(tasks_relative_path)
34
+ LOADER.load_tasks(tasks_relative_path)
82
35
  end
83
- class << self
84
- %w(scratch output _data).each do |dir|
85
- define_method("#{dir.gsub(/[^A-Za-z0-9]/,'')}_dir") do
86
- File.join(artifact_dir,dir)
87
- end
88
- end
89
36
 
37
+ LOADER.setup
38
+
39
+ def self.reset
40
+ # TODO Don't like how this method needs to know
41
+ # all of these class variables that are defined
42
+ # in separate classes.
43
+ @configuration = nil
44
+ @graph = nil
45
+ @result = nil
90
46
  end
91
- # def const_missing(name)
92
- #
93
- # end
94
47
  end
95
- MetricFu.lib_require { 'version' }
96
- MetricFu.lib_require { 'initial_requires' }
97
- # Load a few things to make our lives easier elsewhere.
98
- MetricFu.lib_require { 'load_files' }
@@ -32,7 +32,7 @@ module MetricFu
32
32
  end
33
33
 
34
34
  def metrics
35
- MetricFu.configuration.metrics.sort_by(&:to_s)
35
+ MetricFu::Metric.metrics.map(&:name).sort_by(&:to_s)
36
36
  end
37
37
 
38
38
  def process_options(argv=[])
@@ -54,7 +54,7 @@ module MetricFu
54
54
  "This option applies to the previously",
55
55
  "specified --format, or the default format",
56
56
  "if no format is specified. Paths are relative to",
57
- "#{Pathname.pwd.join(MetricFu.base_directory)}",
57
+ "#{Pathname.pwd.join(MetricFu::Io::FileSystem.directory('base_directory'))}",
58
58
  "Check the specific formatter\'s docs to see",
59
59
  "whether to pass a file or a dir.") do |o|
60
60
  @result[:format] ||= MetricFu::Formatter::DEFAULT
@@ -1,9 +1,8 @@
1
- require 'fileutils'
2
- require 'rbconfig'
3
- MetricFu.reporting_require { 'templates/awesome/awesome_template' }
4
1
  MetricFu.logging_require { 'mf_debugger' }
5
2
  module MetricFu
6
3
 
4
+ # Even though the below class methods are defined on the MetricFu module
5
+ # They are included here as they deal with configuration
7
6
 
8
7
  # The @configuration class variable holds a global type configuration
9
8
  # object for any parts of the system to use.
@@ -12,21 +11,29 @@ module MetricFu
12
11
  @configuration ||= Configuration.new
13
12
  end
14
13
 
14
+ def self.configure
15
+ Dir.glob(File.join(MetricFu.metrics_dir, '**/init.rb')).each{|init_file|require(init_file)}
16
+ Dir.glob(File.join(MetricFu.reporting_dir, '**/init.rb')).each{|init_file|require(init_file)}
17
+ configuration.tap do |config|
18
+ config.configure_metrics
19
+ end
20
+ end
21
+
22
+ # TODO: Remove this method. It is really a test concern for identifying
23
+ # metrics turned off for environmental reasons
24
+ def self.mri_only_metrics
25
+ if MetricFu.configuration.mri?
26
+ []
27
+ else
28
+ [:cane, :flog, :rails_best_practices]
29
+ end
30
+ end
31
+
15
32
  # = Configuration
16
33
  #
17
34
  # The Configuration class, as it sounds, provides methods for
18
35
  # configuring the behaviour of MetricFu.
19
36
  #
20
- # == Customization for Rails
21
- #
22
- # The Configuration class checks for the presence of a
23
- # 'config/environment.rb' file. If the file is present, it assumes
24
- # it is running in a Rails project. If it is, it will:
25
- #
26
- # * Add 'app' to the @code_dirs directory to include the
27
- # code in the app directory in the processing
28
- # * Add :stats and :rails_best_practices to the list of metrics to run
29
- #
30
37
  # == Customization for CruiseControl.rb
31
38
  #
32
39
  # The Configuration class checks for the presence of a
@@ -36,186 +43,133 @@ module MetricFu
36
43
  #
37
44
  # == Metric Configuration
38
45
  #
39
- # Each metric can be configured by e.g. config.churn, config.flog, config.saikuro
46
+ # Each metric can be configured by e.g.
47
+ # config.configure_metric(:flog) do |flog|
48
+ # flog.enable
49
+ # flog.dirs_to_flog = %w(app lib spec)
50
+ # ...
51
+ # end
52
+ #
53
+ # or iterate over all metrics to configure by e.g.
54
+ # config.configure_metrics.each do |metric|
55
+ # ...
56
+ # end
57
+ #
58
+ # == Formatter Configuration
59
+ #
60
+ # Formatters can be configured by e.g.
61
+ # config.configure_formatter(:html)
62
+ # config.configure_formatter(:yaml, "customreport.yml")
63
+ # config.configure_formatter(MyCustomFormatter)
64
+ #
65
+ # == Graph Configuration
66
+ #
67
+ # Graphing engine can be configured by e.g.
68
+ # config.configure_graph_engine(:bluff)
69
+ #
70
+ #
40
71
  class Configuration
72
+ require_relative 'environment'
73
+ require_relative 'io'
74
+ require_relative 'formatter'
75
+ # TODO: Remove need to include the module
76
+ include MetricFu::Environment
41
77
 
42
78
  def initialize #:nodoc:#
43
79
  reset
44
80
  end
45
81
 
46
- def verbose
47
- MfDebugger::Logger.debug_on
48
- end
49
-
50
- def verbose=(toggle)
51
- MfDebugger::Logger.debug_on = toggle
52
- end
53
-
54
82
  def mf_debug(msg)
55
83
  MfDebugger.mf_debug msg
56
84
  end
57
85
 
58
86
  # TODO review if these code is functionally duplicated in the
59
87
  # base generator initialize
88
+ attr_reader :formatters
60
89
  def reset
61
- set_directories
62
- configure_template
63
- add_promiscuous_instance_variable(:metrics, [])
64
- add_promiscuous_instance_variable(:formatters, [])
65
- add_promiscuous_instance_variable(:graphs, [])
66
- add_promiscuous_instance_variable(:graph_engines, [])
67
- add_promiscuous_method(:graph_engine)
90
+ # TODO: Remove calls to self and/or allow querying the
91
+ # template/filesystem/metric/graph/environment, etc settings
92
+ # from the configuration instance
93
+ MetricFu::Io::FileSystem.set_directories(self)
94
+ MetricFu::Formatter::Templates.configure_template(self)
95
+ @formatters = []
96
+ @graph_engine_config = MetricFu::GraphEngine.new
68
97
  end
69
98
 
70
99
  # This allows us to have a nice syntax like:
71
100
  #
72
101
  # MetricFu.run do |config|
73
- # config.base_directory = 'tmp/metric_fu'
102
+ # congif.configure_metric(:churn) do
103
+ # ...
104
+ # end
105
+ #
106
+ # config.configure_graph_engine(:bluff)
74
107
  # end
75
108
  #
76
109
  # See the README for more information on configuration options.
110
+ # TODO: Consider breaking compatibility by removing this, now unused method
77
111
  def self.run
78
112
  yield MetricFu.configuration
79
113
  end
80
114
 
81
- attr_accessor :metrics
82
- # e.g. :churn
83
- def add_metric(metric)
84
- add_promiscuous_method(metric)
85
- self.metrics = (metrics << metric).uniq
115
+ def configure_metric(name)
116
+ yield MetricFu::Metric.get_metric(name)
86
117
  end
87
118
 
88
- # e.g. :reek
89
- def add_graph(metric)
90
- add_promiscuous_method(metric)
91
- self.graphs = (graphs << metric).uniq
92
- end
93
-
94
- def add_formatter(format, output = nil)
95
- @formatters << MetricFu::Formatter.class_for(format).new(output: output)
96
- end
97
-
98
- # e.g. :reek, {}
99
- def configure_metric(metric, metric_configuration)
100
- add_promiscuous_instance_variable(metric, metric_configuration)
101
- end
102
-
103
- # e.g. :bluff
104
- def add_graph_engine(graph_engine)
105
- add_promiscuous_method(graph_engine)
106
- self.graph_engines = (graph_engines << graph_engine).uniq
107
- end
108
-
109
- # e.g. :bluff
110
- def configure_graph_engine(graph_engine)
111
- add_promiscuous_instance_variable(:graph_engine, graph_engine)
112
- end
113
-
114
- # Perform a simple check to try and guess if we're running
115
- # against a rails app.
116
- #
117
- # TODO This should probably be made a bit more robust.
118
- def rails?
119
- add_promiscuous_instance_variable(:rails, File.exist?("config/environment.rb"))
120
- end
121
-
122
- def is_cruise_control_rb?
123
- !!ENV['CC_BUILD_ARTIFACTS']
124
- end
125
-
126
- def jruby?
127
- @jruby ||= !!RedCard.check(:jruby)
128
- end
129
-
130
- def mri?
131
- @mri ||= !!RedCard.check(:ruby)
132
- end
133
-
134
- def rubinius?
135
- @rubinius ||= !!RedCard.check(:rubinius)
136
- end
137
-
138
- def platform #:nodoc:
139
- # TODO, change
140
- # RbConfig::CONFIG['ruby_install_name'].dup
141
- return RUBY_PLATFORM
142
- end
143
-
144
- def self.ruby_strangely_makes_accessors_private?
145
- ruby192? || jruby?
146
- end
147
-
148
- def self.ruby192?
149
- @ruby192 ||= !!RedCard.check('1.9.2')
119
+ def configure_metrics
120
+ MetricFu::Metric.metrics.each do |metric|
121
+ if block_given?
122
+ yield metric
123
+ elsif !metric_manually_configured?(metric)
124
+ metric.enabled = false
125
+ metric.enable
126
+ end
127
+ metric.activate if metric.enabled unless metric.activated
128
+ end
150
129
  end
151
130
 
152
- protected unless ruby_strangely_makes_accessors_private?
153
-
154
- def add_promiscuous_instance_variable(name,value)
155
- instance_variable_set("@#{name}", value)
156
- add_promiscuous_method(name)
157
- value
131
+ # TODO: Remove this method. If we run configure_metrics
132
+ # and it disabled rcov, we shouldn't have to worry here
133
+ # that rcov is a special case that can only be enabled
134
+ # manually
135
+ def metric_manually_configured?(metric)
136
+ [:rcov].include?(metric.name)
158
137
  end
159
138
 
160
- def add_promiscuous_method(method_name)
161
- add_promiscuous_class_method_to_metric_fu(method_name)
162
- add_accessor_to_config(method_name)
139
+ # TODO: Reconsider method name/behavior, as it really adds a formatter
140
+ def configure_formatter(format, output = nil)
141
+ @formatters << MetricFu::Formatter.class_for(format).new(output: output)
163
142
  end
164
143
 
165
- def add_promiscuous_class_method_to_metric_fu(method_name)
166
- metric_fu_method = <<-EOF
167
- def self.#{method_name}
168
- configuration.send(:#{method_name})
169
- end
170
- EOF
171
- MetricFu.module_eval(metric_fu_method)
144
+ # @return [Array<Symbol>] names of enabled metrics with graphs
145
+ def graphs
146
+ # TODO: This is a common enough need to be pushed into MetricFu::Metric as :enabled_metrics_with_graphs
147
+ MetricFu::Metric.enabled_metrics.select{|metric|metric.has_graph?}.map(&:name)
172
148
  end
173
149
 
150
+ # TODO: Consider if we need to delegate so much to graph_engine_config
151
+ # if we should use forwardable or change the api
174
152
 
175
- def add_accessor_to_config(method_name)
176
- self.class.send(:attr_accessor, method_name)
153
+ # @return [Array<Symbol>] names of available graph engines
154
+ # @example [:bluff, :gchart]
155
+ def graph_engines
156
+ @graph_engine_config.graph_engines
177
157
  end
178
158
 
179
- private
180
-
181
- def configure_template
182
- add_promiscuous_instance_variable(:template_class, AwesomeTemplate)
183
- add_promiscuous_instance_variable(:link_prefix, nil)
184
- add_promiscuous_instance_variable(:darwin_txmt_protocol_no_thanks, true)
185
- # turning off syntax_highlighting may avoid some UTF-8 issues
186
- add_promiscuous_instance_variable(:syntax_highlighting, true)
159
+ # @return [Symbol] the selected graph engine
160
+ def graph_engine
161
+ @graph_engine_config.graph_engine
187
162
  end
188
163
 
189
- def set_directories
190
- add_promiscuous_instance_variable(:base_directory,MetricFu.artifact_dir)
191
- add_promiscuous_instance_variable(:scratch_directory,MetricFu.scratch_dir)
192
- add_promiscuous_instance_variable(:output_directory,MetricFu.output_dir)
193
- add_promiscuous_instance_variable(:data_directory,MetricFu.data_dir)
194
- # due to behavior differences between ruby 1.8.7 and 1.9.3
195
- # this is good enough for now
196
- create_directories [base_directory, scratch_directory, output_directory]
197
-
198
- add_promiscuous_instance_variable(:metric_fu_root_directory,MetricFu.root_dir)
199
- add_promiscuous_instance_variable(:template_directory,
200
- File.join(metric_fu_root_directory,
201
- 'lib', 'templates'))
202
- add_promiscuous_instance_variable(:file_globs_to_ignore,[])
203
- set_code_dirs
164
+ # @param graph_engine [Symbol] the name of an available graph engine
165
+ def add_graph_engine(graph_engine)
166
+ @graph_engine_config.add_graph_engine(graph_engine)
204
167
  end
205
168
 
206
- def create_directories(*dirs)
207
- Array(*dirs).each do |dir|
208
- FileUtils.mkdir_p dir
209
- end
169
+ # @param graph_engine [Symbol] sets the selected graph engine to use
170
+ def configure_graph_engine(graph_engine)
171
+ @graph_engine_config.configure_graph_engine(graph_engine)
210
172
  end
211
173
 
212
- # Add the 'app' directory if we're running within rails.
213
- def set_code_dirs
214
- if rails?
215
- add_promiscuous_instance_variable(:code_dirs,['app', 'lib'])
216
- else
217
- add_promiscuous_instance_variable(:code_dirs,['lib'])
218
- end
219
- end
220
174
  end
221
175
  end