metric_fu 4.1.2 → 4.1.3
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.
- data/.travis.yml +7 -4
- data/.yardopts +5 -0
- data/CONTRIBUTING.md +28 -13
- data/Gemfile +7 -3
- data/HISTORY.md +12 -0
- data/README.md +17 -0
- data/TODO.md +74 -79
- data/lib/metric_fu.rb +8 -0
- data/lib/metric_fu/configuration.rb +8 -3
- data/lib/metric_fu/core_ext.rb +2 -0
- data/lib/metric_fu/core_ext/inflector/inflections.rb +214 -0
- data/lib/metric_fu/core_ext/inflector/methods.rb +153 -0
- data/lib/metric_fu/core_ext/object.rb +3 -0
- data/lib/metric_fu/core_ext/object/blank.rb +106 -0
- data/lib/metric_fu/core_ext/object/to_json.rb +12 -0
- data/lib/metric_fu/core_ext/string.rb +2 -0
- data/lib/metric_fu/core_ext/string/inflections.rb +195 -0
- data/lib/metric_fu/initial_requires.rb +0 -8
- data/lib/metric_fu/metrics/base_template.rb +28 -1
- data/lib/metric_fu/metrics/churn/churn.rb +2 -2
- data/lib/metric_fu/metrics/churn/template_awesome/churn.html.erb +8 -6
- data/lib/metric_fu/metrics/hotspots/analysis/code_issue.rb +6 -0
- data/lib/metric_fu/metrics/hotspots/init.rb +1 -0
- data/lib/metric_fu/reporting/templates/awesome/awesome_template.rb +37 -20
- data/lib/metric_fu/reporting/templates/awesome/css/bluff.css +15 -0
- data/lib/metric_fu/reporting/templates/awesome/css/default.css +0 -48
- data/lib/metric_fu/reporting/templates/awesome/css/rcov.css +32 -0
- data/lib/metric_fu/reporting/templates/awesome/index.html.erb +4 -32
- data/lib/metric_fu/reporting/templates/awesome/layout.html.erb +2 -0
- data/lib/metric_fu/version.rb +1 -1
- data/metric_fu.gemspec +23 -11
- data/spec/cli/helper_spec.rb +38 -28
- data/spec/metric_fu/configuration_spec.rb +35 -22
- data/spec/metric_fu/metrics/base_template_spec.rb +7 -7
- data/spec/metric_fu/metrics/churn/churn_spec.rb +9 -2
- data/spec/metric_fu/metrics/flog/flog_spec.rb +57 -55
- data/spec/metric_fu/metrics/hotspots/hotspot_analyzer_spec.rb +0 -2
- data/spec/run_spec.rb +0 -8
- data/spec/support/suite.rb +3 -1
- metadata +74 -125
- data/home_page/back_all.jpg +0 -0
- data/home_page/cc.rb.gif +0 -0
- data/home_page/churn.gif +0 -0
- data/home_page/cruise_control_1.gif +0 -0
- data/home_page/cyclomatic.gif +0 -0
- data/home_page/flay.gif +0 -0
- data/home_page/flog.gif +0 -0
- data/home_page/flog2.gif +0 -0
- data/home_page/footer.gif +0 -0
- data/home_page/header.jpg +0 -0
- data/home_page/hotspot.gif +0 -0
- data/home_page/img09.gif +0 -0
- data/home_page/index.html +0 -138
- data/home_page/rcov.gif +0 -0
- data/home_page/reek.gif +0 -0
- data/home_page/robots.txt +0 -5
- data/home_page/roodi.gif +0 -0
- data/home_page/saikuro.gif +0 -0
- data/home_page/stats.gif +0 -0
- data/home_page/styles.css +0 -245
- data/home_page/title.gif +0 -0
- data/home_page/title_back.gif +0 -0
- data/lib/metric_fu/metrics/cane/template_standard/cane.html.erb +0 -95
- data/lib/metric_fu/metrics/churn/template_standard/churn.html.erb +0 -31
- data/lib/metric_fu/metrics/flay/template_standard/flay.html.erb +0 -34
- data/lib/metric_fu/metrics/flog/template_standard/flog.html.erb +0 -57
- data/lib/metric_fu/metrics/hotspots/template_standard/hotspots.html.erb +0 -54
- data/lib/metric_fu/metrics/rails_best_practices/template_standard/rails_best_practices.html.erb +0 -29
- data/lib/metric_fu/metrics/rcov/template_standard/rcov.html.erb +0 -43
- data/lib/metric_fu/metrics/reek/template_standard/reek.html.erb +0 -42
- data/lib/metric_fu/metrics/roodi/template_standard/roodi.html.erb +0 -29
- data/lib/metric_fu/metrics/saikuro/template_standard/saikuro.html.erb +0 -84
- data/lib/metric_fu/metrics/stats/template_standard/stats.html.erb +0 -55
- data/lib/metric_fu/reporting/templates/standard/default.css +0 -64
- data/lib/metric_fu/reporting/templates/standard/index.html.erb +0 -44
- data/lib/metric_fu/reporting/templates/standard/standard_template.rb +0 -26
data/.travis.yml
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
language: ruby
|
2
|
+
bundler_args: --without development
|
3
|
+
script: bundle exec rspec
|
4
|
+
# gemfile:
|
5
|
+
# - gemfiles/Gemfile.ci
|
6
|
+
# before_install: some_command
|
7
|
+
# env:
|
8
|
+
# - "rack=1.3.4"
|
2
9
|
rvm:
|
3
10
|
- 2.0.0
|
4
11
|
- 1.9.3
|
5
12
|
- 1.9.2
|
6
13
|
- jruby-19mode # JRuby in 1.9 mode
|
7
14
|
- rbx-19mode
|
8
|
-
matrix:
|
9
|
-
allow_failures:
|
10
|
-
- rvm: jruby-19mode
|
11
|
-
- rvm: rbx-19mode
|
data/.yardopts
ADDED
data/CONTRIBUTING.md
CHANGED
@@ -1,19 +1,34 @@
|
|
1
1
|
How to contribute:
|
2
2
|
|
3
|
-
|
4
|
-
2. bundle install
|
5
|
-
3. Run the tests ('bundle exec rake')
|
6
|
-
4. Run metric_fu on itself ('bundle exec metric_fu -r')
|
7
|
-
5. Make the changes you want and back them up with tests.
|
8
|
-
6. Make sure two important rake tests still run ('bundle exec rake' and 'bundle exec rake metrics:all')
|
9
|
-
7. Commit and send me a pull request with details as to what has been changed.
|
3
|
+
## Bug reports / Issues
|
10
4
|
|
11
|
-
|
5
|
+
* Is something broken or not working as expected? Check for an existing issue or [create a new one](https://github.com/metricfu/metric_fu/issues/new)
|
6
|
+
* See [Quick guide to writing good bug reports](https://github.com/metricfu/metric_fu/wiki/Issues:-Quick-guide-to-writing-good-bug-reports)
|
12
7
|
|
13
|
-
|
14
|
-
2. Update the documentation here or the rubyforge web page inside the `'home_page'` folder
|
15
|
-
3. Update the History and give yourself credit.
|
8
|
+
## Code
|
16
9
|
|
17
|
-
|
10
|
+
1. Clone the repo: `git clone git://github.com/metricfu/metric_fu.git && cd metric_fu`
|
11
|
+
2. Install the gem dependencies: `bundle install`
|
12
|
+
3. Make the changes you want and back them up with tests.
|
13
|
+
* Run the tests (`bundle exec rake`)
|
14
|
+
* Run metric_fu on itself (`bundle exec rake metrics:all`)
|
15
|
+
4. Update the HISTORY.md file with your changes and give yourself credit
|
16
|
+
5. Commit and create a pull request with details as to what has been changed and why
|
17
|
+
* Use well-described, small (atomic) commits.
|
18
|
+
* Include links to any relevant github issues.
|
19
|
+
* *Don't* change the VERSION file.
|
20
|
+
6. Extra Credit: [Confirm it runs and tests pass on the rubies specified in the travis config](.travis.yml). I will otherwise confirm it runs on these.
|
18
21
|
|
19
|
-
|
22
|
+
How I handle pull requests:
|
23
|
+
|
24
|
+
* If the tests pass and the pull request looks good, I will merge it.
|
25
|
+
* If the pull request needs to be changed,
|
26
|
+
* you can change it by updating the branch you generated the pull request from
|
27
|
+
* either by adding more commits, or
|
28
|
+
* by force pushing to it
|
29
|
+
* I can make any changes myself and manually merge the code in.
|
30
|
+
|
31
|
+
## Documentation
|
32
|
+
|
33
|
+
* If relevant, you may update [the metric_fu website](https://github.com/metricfu/metricfu.github.com) in a separate pull request to that repo
|
34
|
+
* Update the wiki
|
data/Gemfile
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
3
|
gem 'rake'
|
4
|
-
|
4
|
+
# alternative graphing gem
|
5
|
+
gem "googlecharts"
|
6
|
+
group :development do
|
7
|
+
|
8
|
+
end
|
9
|
+
group :test do
|
5
10
|
gem "rspec", '>2'
|
6
|
-
gem
|
7
|
-
gem "googlecharts"
|
11
|
+
gem 'test-construct'
|
8
12
|
if ENV['COVERAGE']
|
9
13
|
gem 'simplecov'
|
10
14
|
# https://github.com/kina/simplecov-rcov-text
|
data/HISTORY.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
### Master
|
2
2
|
|
3
|
+
### MetricFu 4.1.3 / 2013-05-13
|
4
|
+
|
5
|
+
* Features
|
6
|
+
* Tests now pass in JRuby and Rubinius! (Benjamin Fleischer)
|
7
|
+
* Fixes
|
8
|
+
* Line numbers now display and link properly in annotated code (Benjamin Fleischer)
|
9
|
+
* No longer remove historical metrics when testing metric_fu
|
10
|
+
* Churn metric handler won't crash when no source control found (Dan Mayer)
|
11
|
+
* Misc (Benjamin Fleischer)
|
12
|
+
* Removed StandardTemplate, had no additional value and needed to be maintained
|
13
|
+
* Removed most template references to specific metrics
|
14
|
+
|
3
15
|
### MetricFu 4.1.2 / 2013-04-17
|
4
16
|
|
5
17
|
* Fixes
|
data/README.md
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
# MetricFu [](http://badge.fury.io/rb/metric_fu) [](http://travis-ci.org/metricfu/metric_fu) [](https://codeclimate.com/github/metricfu/metric_fu) [](https://gemnasium.com/metricfu/metric_fu)
|
2
2
|
|
3
|
+
## Metrics
|
4
|
+
|
5
|
+
* [Cane](https://rubygems.org/gems/cane), [Source](http://github.com/square/cane)
|
6
|
+
* [Churn](https://rubygems.org/gems/churn), [Source](http://github.com/danmayer/churn)
|
7
|
+
* [Flog](https://rubygems.org/gems/flog), [Source](https://github.com/seattlerb/flog)
|
8
|
+
* [Flay](https://rubygems.org/gems/flay), [Source](https://github.com/seattlerb/flay)
|
9
|
+
* [Reek](https://rubygems.org/gems/reek) [Source](https://github.com/troessner/reek)
|
10
|
+
* [Roodi](https://rubygems.org/gems/metric_fu-roodi), [Source](https://github.com/metricfu/roodi)
|
11
|
+
* [Saikuro](https://rubygems.org/gems/japgolly-Saikuro), [Source](https://github.com/japgolly/Saikuro)
|
12
|
+
* Rails-only
|
13
|
+
* [Rails Best Practices](https://rubygems.org/gems/rails_best_practices), [Source](https://github.com/railsbp/rails_best_practices)
|
14
|
+
* Rails `rake stats` task (see [gem](https://rubygems.org/gems/code_statistics), [Source](https://github.com/danmayer/code_statistics) )
|
15
|
+
* Test Coverage
|
16
|
+
* 1.9: [SimpleCov](http://rubygems.org/gems/simplecov) and [SimpleCov-Rcov-Text](http://rubygems.org/gems/simplecov-rcov-text)
|
17
|
+
* 1.8 [Rcov](http://rubygems.org/gems/rcov)
|
18
|
+
* Hotspots (a meta-metric of the above)
|
19
|
+
|
3
20
|
## Installation
|
4
21
|
|
5
22
|
gem install metric_fu
|
data/TODO.md
CHANGED
@@ -2,107 +2,86 @@
|
|
2
2
|
|
3
3
|
* Keep HISTORY.md in master up to date
|
4
4
|
|
5
|
-
|
5
|
+
Items in each category are in generally order of decreasing priority.
|
6
|
+
The categories themselves are not in any priority order.
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
* Move code that references rcov out of
|
10
|
-
|
11
|
-
lib/reporting/templates/awesome/css/default.css
|
12
|
-
lib/reporting/templates/awesome/index.html.erb
|
13
|
-
lib/reporting/templates/standard/default.css
|
14
|
-
lib/reporting/templates/standard/index.html.erb
|
15
|
-
|
16
|
-
* Move code that references flog out of
|
17
|
-
|
18
|
-
lib/configuration.rb
|
19
|
-
lib/metrics/hotspots/analysis/code_issue.rb
|
20
|
-
lib/reporting/templates/awesome/index.html.erb
|
21
|
-
lib/reporting/templates/standard/index.html.erb
|
22
|
-
|
23
|
-
* Move code that references flay out of
|
24
|
-
|
25
|
-
lib/metrics/generator.rb
|
26
|
-
lib/metrics/hotspots/analysis/code_issue.rb
|
27
|
-
lib/reporting/templates/awesome/index.html.erb
|
28
|
-
lib/reporting/templates/standard/index.html.erb
|
29
|
-
|
30
|
-
* Move code that references churn out of
|
31
|
-
|
32
|
-
lib/metrics/hotspots/analysis/code_issue.rb
|
33
|
-
lib/metrics/hotspots/init.rb
|
34
|
-
lib/reporting/templates/awesome/index.html.erb
|
35
|
-
lib/reporting/templates/standard/index.html.erb
|
36
|
-
|
37
|
-
* Move code that references rails_best_practices out of
|
38
|
-
|
39
|
-
lib/metrics/hotspots/analysis/code_issue.rb
|
40
|
-
lib/reporting/templates/awesome/index.html.erb
|
41
|
-
lib/reporting/templates/standard/index.html.erb
|
42
|
-
|
43
|
-
|
44
|
-
* Move code that references reek out of
|
45
|
-
|
46
|
-
lib/metrics/hotspots/analysis/code_issue.rb
|
47
|
-
lib/reporting/templates/awesome/index.html.erb
|
48
|
-
lib/reporting/templates/standard/index.html.erb
|
49
|
-
|
50
|
-
|
51
|
-
* Move code that references roodi out of
|
52
|
-
|
53
|
-
lib/metrics/hotspots/analysis/code_issue.rb
|
54
|
-
lib/reporting/templates/awesome/index.html.erb
|
55
|
-
lib/reporting/templates/standard/index.html.erb
|
56
|
-
|
57
|
-
* Move code that references saikuro out of
|
58
|
-
|
59
|
-
lib/metrics/hotspots/analysis/code_issue.rb
|
60
|
-
lib/reporting/templates/awesome/index.html.erb
|
61
|
-
lib/reporting/templates/standard/index.html.erb
|
62
|
-
|
63
|
-
* Move code that references stats out of
|
64
|
-
|
65
|
-
lib/reporting/templates/awesome/index.html.erb
|
66
|
-
lib/reporting/templates/standard/index.html.erb
|
67
|
-
|
68
|
-
* Review how metric_fu uses each tools to generate metrics, e.g. by shelling out commands, rake task, modifying the output, etc.
|
69
|
-
|
70
|
-
* Change MetricFu.report.add(metric) to e.g. MetricFu.generate_report(metric) to make clear that this actually runs the tool
|
71
|
-
|
72
|
-
* Allow the coverage task to specify the command it runs plus any flags (see bundler/capistrano options)
|
73
|
-
|
74
|
-
* Test against a rails app
|
8
|
+
Also see [CONTRIBUTING](./CONTRIBUTING.md)
|
75
9
|
|
76
10
|
## Features
|
77
11
|
|
78
|
-
*
|
79
|
-
|
80
|
-
|
81
|
-
|
12
|
+
* Make it easier to whitelist metrics when running from the commanline (cli)
|
13
|
+
* Be able to specify folders to run against rather than just app and lib
|
14
|
+
* Be able to run metric tools from metric_fu without shelling out
|
15
|
+
* Allow the coverage task to specify the command it runs plus any flags (see bundler/capistrano options)
|
82
16
|
* Add configurable logger to all output streams
|
83
|
-
* Color code flog results with scale from: http://jakescruggs.blogspot.com/2008/08/whats-good-flog-score.html
|
84
|
-
* Make running metric_fu on metric_fu less embarrassing
|
85
17
|
* Load all gems at config time so you fail fast if one is missing
|
86
|
-
*
|
87
|
-
|
18
|
+
* Color code flog results with scale from: http://jakescruggs.blogspot.com/2008/08/whats-good-flog-score.html
|
19
|
+
* Make the template pages prettier (hold off until [61](https://github.com/metricfu/metric_fu/pull/61) is merged)
|
20
|
+
* Be able to generate historical metrics for eg gem releases (tagged with appropriate date)
|
88
21
|
|
89
22
|
## Testing
|
90
23
|
|
24
|
+
* Test against a rails app, see [yui-rails](https://github.com/nextmat/yui-rails/tree/master/test/dummy)
|
91
25
|
* Determine how to test metric_fu against codebases that are not metric_fu, to ensure it works on most applications
|
92
26
|
* This is especially true for rails applications
|
93
27
|
* Remove / Modify Devver code from the generators/hotspots_spec and base/hotspot_analzyer_spec
|
28
|
+
* Add tests
|
29
|
+
* Remove useless tests
|
30
|
+
* Remove tests that use StandardTemplate. Will require updating tests yml output, which may not be easy
|
94
31
|
|
95
32
|
## Bugs / Fixes
|
96
33
|
|
34
|
+
* See issues
|
35
|
+
|
97
36
|
## Misc
|
98
37
|
|
38
|
+
### Improvements
|
39
|
+
|
40
|
+
* See TODO items in the code
|
41
|
+
* Change how config works to not metaprogrammatically create so many
|
42
|
+
instance variables and accessors
|
43
|
+
* Clarify the execution path and what a metric's api should be, (repeat for templates and graphs)
|
44
|
+
* Change MetricFu.report.add(metric) to e.g. MetricFu.generate_report(metric) to make clear that this actually runs the tool
|
45
|
+
* Clarify hotspot weighting
|
46
|
+
* Update the wiki with use cases
|
47
|
+
* Review how metric_fu uses each tools to generate metrics, e.g. by shelling out commands, rake task, modifying the output, etc.
|
48
|
+
* Understand and explain s-expressions and how they're used (or should be ) in [line_numbers.rb](https://github.com/metricfu/metric_fu/blob/master/lib/metric_fu/data_structures/line_numbers.rb) (via the ruby_parser)
|
49
|
+
* maybe see [reek tree dresser](https://github.com/troessner/reek/blob/master/lib/reek/source/tree_dresser.rb) and [reek code parser](https://github.com/troessner/reek/blob/master/lib/reek/core/code_parser.rb) or
|
50
|
+
* [ripper-tags](https://github.com/tmm1/ripper-tags)
|
51
|
+
* Remove dead code
|
99
52
|
* Determine if CodeIssue is used, else remove it
|
100
53
|
* Remove references to Ruport from the Devver / Caliper code
|
101
|
-
*
|
54
|
+
* Understand and explain how each metric can be used
|
55
|
+
* Improve metric_fu code metrics
|
56
|
+
* Refactor the hotspots code
|
102
57
|
* Is there any reason not to remove the Manifest.txt?
|
58
|
+
* Consider removing need for the core extensions (ActiveSupport)
|
59
|
+
|
60
|
+
### Documentation
|
61
|
+
|
62
|
+
* Get the rdoc (or yard) published
|
63
|
+
* Add more inline documentation
|
103
64
|
* See other documentation code for examples to improve ours:
|
104
65
|
* https://github.com/charliesome/better_errors/blob/master/CONTRIBUTING.md
|
105
66
|
* https://github.com/charliesome/better_errors/blob/master/README.md
|
67
|
+
|
68
|
+
### Other
|
69
|
+
|
70
|
+
* Look into issues for the tools metric_fu uses
|
71
|
+
* Look into other tools that might work well
|
72
|
+
* Update contributing or issue guidlines
|
73
|
+
* Suggest commit message guidelines
|
74
|
+
* [Update the homepage](https://github.com/metricfu/metricfu.github.com)
|
75
|
+
|
76
|
+
## Future Thoughts
|
77
|
+
|
78
|
+
* Look into how to manage plugins or otherwise load abritrary metrics
|
79
|
+
* [Hoe](https://github.com/seattlerb/hoe/blob/master/lib/hoe.rb#L301)
|
80
|
+
* CLI [Flog](https://github.com/seattlerb/flog/blob/master/lib/flog_cli.rb) Plugins [Flog](https://github.com/seattlerb/flog/blob/master/lib/flog_cli.rb#L34)
|
81
|
+
* Look into adding
|
82
|
+
* https://github.com/metricfu/code_statistics [1](https://github.com/cloudability/code_statistics)
|
83
|
+
* brakeman https://github.com/metricfu/brakeman
|
84
|
+
* laser https://github.com/metricfu/laser
|
106
85
|
* Other intersting libraries to consider:
|
107
86
|
* https://gist.github.com/4562865 for generating Flog on ERB templates by jamesmartin
|
108
87
|
* https://github.com/chad/turbulence churn and complexity (flog)
|
@@ -112,7 +91,23 @@ lib/reporting/templates/standard/index.html.erb
|
|
112
91
|
* https://github.com/metricfu/gauntlet
|
113
92
|
* https://github.com/metricfu/repodepot-ruby https://twitter.com/jakescruggs/status/70521977303076865
|
114
93
|
* https://github.com/eladmeidar/rails_indexes
|
115
|
-
* https://github.com/trptcolin/consistency_fail
|
94
|
+
* https://github.com/trptcolin/consistency_fail
|
116
95
|
* https://github.com/thoughtbot/appraisal
|
117
96
|
* https://github.com/jenkinsci/rubymetrics-plugin
|
118
97
|
* https://github.com/holman/hopper
|
98
|
+
* https://github.com/eric/metriks
|
99
|
+
|
100
|
+
## Useful Links
|
101
|
+
|
102
|
+
### Ruby Guides
|
103
|
+
|
104
|
+
* https://github.com/cwgem/RubyGuide
|
105
|
+
* https://github.com/bbatsov/rubocop
|
106
|
+
* https://github.com/bbatsov/ruby-style-guide
|
107
|
+
* https://github.com/bbatsov/rails-style-guide
|
108
|
+
* [Learning resources](http://www.benjaminfleischer.com/learning/ruby/tutorials.html) [Source](https://github.com/bf4/learning/tree/gh-pages)
|
109
|
+
|
110
|
+
### Perf tools
|
111
|
+
|
112
|
+
* https://github.com/tmm1/perftools.rb
|
113
|
+
* https://twitter.com/mperham/status/311332913641840641
|
data/lib/metric_fu.rb
CHANGED
@@ -41,6 +41,7 @@ module MetricFu
|
|
41
41
|
(ENV['CC_BUILD_ARTIFACTS'] || 'tmp/metric_fu')
|
42
42
|
end
|
43
43
|
def self.configure
|
44
|
+
MetricFu.lib_require { 'core_ext' }
|
44
45
|
MetricFu.lib_require { 'configuration' }
|
45
46
|
init_files = Dir.glob(File.join(MetricFu.metrics_dir, '**/init.rb')).reject do |file|
|
46
47
|
if file =~ /rcov/o
|
@@ -66,6 +67,13 @@ module MetricFu
|
|
66
67
|
end
|
67
68
|
MetricFu.configuration
|
68
69
|
end
|
70
|
+
def self.mri_only_metrics
|
71
|
+
if MetricFu.configuration.mri?
|
72
|
+
[]
|
73
|
+
else
|
74
|
+
[:cane, :flog, :rails_best_practices]
|
75
|
+
end
|
76
|
+
end
|
69
77
|
def self.run_rcov
|
70
78
|
load File.join(MetricFu.metrics_dir, 'rcov/init.rb')
|
71
79
|
end
|
@@ -119,11 +119,11 @@ module MetricFu
|
|
119
119
|
end
|
120
120
|
|
121
121
|
def jruby?
|
122
|
-
@jruby ||= RedCard.check(:jruby)
|
122
|
+
@jruby ||= !!RedCard.check(:jruby)
|
123
123
|
end
|
124
124
|
|
125
125
|
def mri?
|
126
|
-
@mri ||= RedCard.check(:ruby)
|
126
|
+
@mri ||= !!RedCard.check(:ruby)
|
127
127
|
end
|
128
128
|
|
129
129
|
def platform #:nodoc:
|
@@ -133,8 +133,13 @@ module MetricFu
|
|
133
133
|
end
|
134
134
|
|
135
135
|
def self.ruby_strangely_makes_accessors_private?
|
136
|
-
|
136
|
+
ruby192? || jruby?
|
137
137
|
end
|
138
|
+
|
139
|
+
def self.ruby192?
|
140
|
+
@ruby192 ||= !!RedCard.check('1.9.2')
|
141
|
+
end
|
142
|
+
|
138
143
|
protected unless ruby_strangely_makes_accessors_private?
|
139
144
|
|
140
145
|
def add_promiscuous_instance_variable(name,value)
|
@@ -0,0 +1,214 @@
|
|
1
|
+
# https://raw.github.com/rails/rails/20768176292cbcb883ab152b4aa9ed8c664771cd/activesupport/lib/active_support/inflector/inflections.rb
|
2
|
+
# not https://github.com/rails/rails/blob/e8727d37fc49d5bf9976c3cb5c46badb92cf4ced/activesupport/lib/active_support/inflector/inflections.rb
|
3
|
+
MetricFu.lib_require { 'core_ext/inflector/methods' }
|
4
|
+
module ActiveSupport
|
5
|
+
module Inflector
|
6
|
+
# A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
|
7
|
+
# inflection rules. Examples:
|
8
|
+
#
|
9
|
+
# ActiveSupport::Inflector.inflections do |inflect|
|
10
|
+
# inflect.plural /^(ox)$/i, '\1\2en'
|
11
|
+
# inflect.singular /^(ox)en/i, '\1'
|
12
|
+
#
|
13
|
+
# inflect.irregular 'octopus', 'octopi'
|
14
|
+
#
|
15
|
+
# inflect.uncountable "equipment"
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
|
19
|
+
# pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
|
20
|
+
# already have been loaded.
|
21
|
+
class Inflections
|
22
|
+
def self.instance
|
23
|
+
@__instance__ ||= new
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_reader :plurals, :singulars, :uncountables, :humans
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
@plurals, @singulars, @uncountables, @humans = [], [], [], []
|
30
|
+
end
|
31
|
+
|
32
|
+
# Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
|
33
|
+
# The replacement should always be a string that may include references to the matched data from the rule.
|
34
|
+
def plural(rule, replacement)
|
35
|
+
@uncountables.delete(rule) if rule.is_a?(String)
|
36
|
+
@uncountables.delete(replacement)
|
37
|
+
@plurals.insert(0, [rule, replacement])
|
38
|
+
end
|
39
|
+
|
40
|
+
# Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
|
41
|
+
# The replacement should always be a string that may include references to the matched data from the rule.
|
42
|
+
def singular(rule, replacement)
|
43
|
+
@uncountables.delete(rule) if rule.is_a?(String)
|
44
|
+
@uncountables.delete(replacement)
|
45
|
+
@singulars.insert(0, [rule, replacement])
|
46
|
+
end
|
47
|
+
|
48
|
+
# Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
|
49
|
+
# for strings, not regular expressions. You simply pass the irregular in singular and plural form.
|
50
|
+
#
|
51
|
+
# Examples:
|
52
|
+
# irregular 'octopus', 'octopi'
|
53
|
+
# irregular 'person', 'people'
|
54
|
+
def irregular(singular, plural)
|
55
|
+
@uncountables.delete(singular)
|
56
|
+
@uncountables.delete(plural)
|
57
|
+
if singular[0,1].upcase == plural[0,1].upcase
|
58
|
+
plural(Regexp.new("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
|
59
|
+
plural(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + plural[1..-1])
|
60
|
+
singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
|
61
|
+
else
|
62
|
+
plural(Regexp.new("#{singular[0,1].upcase}(?i)#{singular[1..-1]}$"), plural[0,1].upcase + plural[1..-1])
|
63
|
+
plural(Regexp.new("#{singular[0,1].downcase}(?i)#{singular[1..-1]}$"), plural[0,1].downcase + plural[1..-1])
|
64
|
+
plural(Regexp.new("#{plural[0,1].upcase}(?i)#{plural[1..-1]}$"), plural[0,1].upcase + plural[1..-1])
|
65
|
+
plural(Regexp.new("#{plural[0,1].downcase}(?i)#{plural[1..-1]}$"), plural[0,1].downcase + plural[1..-1])
|
66
|
+
singular(Regexp.new("#{plural[0,1].upcase}(?i)#{plural[1..-1]}$"), singular[0,1].upcase + singular[1..-1])
|
67
|
+
singular(Regexp.new("#{plural[0,1].downcase}(?i)#{plural[1..-1]}$"), singular[0,1].downcase + singular[1..-1])
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Add uncountable words that shouldn't be attempted inflected.
|
72
|
+
#
|
73
|
+
# Examples:
|
74
|
+
# uncountable "money"
|
75
|
+
# uncountable "money", "information"
|
76
|
+
# uncountable %w( money information rice )
|
77
|
+
def uncountable(*words)
|
78
|
+
(@uncountables << words).flatten!
|
79
|
+
end
|
80
|
+
|
81
|
+
# Specifies a humanized form of a string by a regular expression rule or by a string mapping.
|
82
|
+
# When using a regular expression based replacement, the normal humanize formatting is called after the replacement.
|
83
|
+
# When a string is used, the human form should be specified as desired (example: 'The name', not 'the_name')
|
84
|
+
#
|
85
|
+
# Examples:
|
86
|
+
# human /_cnt$/i, '\1_count'
|
87
|
+
# human "legacy_col_person_name", "Name"
|
88
|
+
def human(rule, replacement)
|
89
|
+
@humans.insert(0, [rule, replacement])
|
90
|
+
end
|
91
|
+
|
92
|
+
# Clears the loaded inflections within a given scope (default is <tt>:all</tt>).
|
93
|
+
# Give the scope as a symbol of the inflection type, the options are: <tt>:plurals</tt>,
|
94
|
+
# <tt>:singulars</tt>, <tt>:uncountables</tt>, <tt>:humans</tt>.
|
95
|
+
#
|
96
|
+
# Examples:
|
97
|
+
# clear :all
|
98
|
+
# clear :plurals
|
99
|
+
def clear(scope = :all)
|
100
|
+
case scope
|
101
|
+
when :all
|
102
|
+
@plurals, @singulars, @uncountables = [], [], []
|
103
|
+
else
|
104
|
+
instance_variable_set "@#{scope}", []
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Yields a singleton instance of Inflector::Inflections so you can specify additional
|
110
|
+
# inflector rules.
|
111
|
+
#
|
112
|
+
# Example:
|
113
|
+
# ActiveSupport::Inflector.inflections do |inflect|
|
114
|
+
# inflect.uncountable "rails"
|
115
|
+
# end
|
116
|
+
def inflections
|
117
|
+
if block_given?
|
118
|
+
yield Inflections.instance
|
119
|
+
else
|
120
|
+
Inflections.instance
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Returns the plural form of the word in the string.
|
125
|
+
#
|
126
|
+
# Examples:
|
127
|
+
# "post".pluralize # => "posts"
|
128
|
+
# "octopus".pluralize # => "octopi"
|
129
|
+
# "sheep".pluralize # => "sheep"
|
130
|
+
# "words".pluralize # => "words"
|
131
|
+
# "CamelOctopus".pluralize # => "CamelOctopi"
|
132
|
+
def pluralize(word)
|
133
|
+
result = word.to_s.dup
|
134
|
+
|
135
|
+
if word.empty? || inflections.uncountables.include?(result.downcase)
|
136
|
+
result
|
137
|
+
else
|
138
|
+
inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
|
139
|
+
result
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# The reverse of +pluralize+, returns the singular form of a word in a string.
|
144
|
+
#
|
145
|
+
# Examples:
|
146
|
+
# "posts".singularize # => "post"
|
147
|
+
# "octopi".singularize # => "octopus"
|
148
|
+
# "sheep".singularize # => "sheep"
|
149
|
+
# "word".singularize # => "word"
|
150
|
+
# "CamelOctopi".singularize # => "CamelOctopus"
|
151
|
+
def singularize(word)
|
152
|
+
result = word.to_s.dup
|
153
|
+
|
154
|
+
if inflections.uncountables.any? { |inflection| result =~ /\b(#{inflection})\Z/i }
|
155
|
+
result
|
156
|
+
else
|
157
|
+
inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
|
158
|
+
result
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# Capitalizes the first word and turns underscores into spaces and strips a
|
163
|
+
# trailing "_id", if any. Like +titleize+, this is meant for creating pretty output.
|
164
|
+
#
|
165
|
+
# Examples:
|
166
|
+
# "employee_salary" # => "Employee salary"
|
167
|
+
# "author_id" # => "Author"
|
168
|
+
def humanize(lower_case_and_underscored_word)
|
169
|
+
result = lower_case_and_underscored_word.to_s.dup
|
170
|
+
|
171
|
+
inflections.humans.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
|
172
|
+
result.gsub(/_id$/, "").gsub(/_/, " ").capitalize
|
173
|
+
end
|
174
|
+
|
175
|
+
# Capitalizes all the words and replaces some characters in the string to create
|
176
|
+
# a nicer looking title. +titleize+ is meant for creating pretty output. It is not
|
177
|
+
# used in the Rails internals.
|
178
|
+
#
|
179
|
+
# +titleize+ is also aliased as as +titlecase+.
|
180
|
+
#
|
181
|
+
# Examples:
|
182
|
+
# "man from the boondocks".titleize # => "Man From The Boondocks"
|
183
|
+
# "x-men: the last stand".titleize # => "X Men: The Last Stand"
|
184
|
+
def titleize(word)
|
185
|
+
humanize(underscore(word)).gsub(/\b('?[a-z])/) { $1.capitalize }
|
186
|
+
end
|
187
|
+
|
188
|
+
# Create the name of a table like Rails does for models to table names. This method
|
189
|
+
# uses the +pluralize+ method on the last word in the string.
|
190
|
+
#
|
191
|
+
# Examples
|
192
|
+
# "RawScaledScorer".tableize # => "raw_scaled_scorers"
|
193
|
+
# "egg_and_ham".tableize # => "egg_and_hams"
|
194
|
+
# "fancyCategory".tableize # => "fancy_categories"
|
195
|
+
def tableize(class_name)
|
196
|
+
pluralize(underscore(class_name))
|
197
|
+
end
|
198
|
+
|
199
|
+
# Create a class name from a plural table name like Rails does for table names to models.
|
200
|
+
# Note that this returns a string and not a Class. (To convert to an actual class
|
201
|
+
# follow +classify+ with +constantize+.)
|
202
|
+
#
|
203
|
+
# Examples:
|
204
|
+
# "egg_and_hams".classify # => "EggAndHam"
|
205
|
+
# "posts".classify # => "Post"
|
206
|
+
#
|
207
|
+
# Singular names are not handled correctly:
|
208
|
+
# "business".classify # => "Busines"
|
209
|
+
def classify(table_name)
|
210
|
+
# strip out any leading schema name
|
211
|
+
camelize(singularize(table_name.to_s.sub(/.*\./, '')))
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|