Ruby on Rails -- metric_fuでメトリクス分析


###概要

metric_fuでメトリクス分析を行います。

### 設定

Gemfileに下記を追加

```rb
gem "metric_fu"
```

そして、``bundle install``または``bundle update``などでgemをインストールします。


###メトリクス分析の実行

```bash
rake metrics:all
```

###結果の確認

``%project_root%/tmp/metric_fu/output/``にHTMLファイルが作成されていますので、こちらをダウンロードするなり、開発用のWebサーバにアップするなりして、確認します。


###各項目について


**RailsBest Practices**
文字通りRailsのベストプラクティスに従っているかどうか 
http://rails-bestpractices.com/

**Cane**
1行あたりの文字数や、スペーシング、クラスコメントの有無などをチェック
https://github.com/square/cane

**Roodi**
メソッド行数や空処理のブロックの検出等
https://github.com/metricfu/roodi

**Flay**
コードの重複部を検出。共通化に役立つ
https://rubygems.org/gems/flay

**Churn**
バージョン管理による変更回数の多いソースは問題が多いのでは、という観点からランク付けして抽出する
https://github.com/danmayer/churn

**Saikur**
分岐、行数等からコードの複雑度を測定
https://github.com/japgolly/Saikuro

**Flog**
コードの複雑度を測定
https://github.com/seattlerb/flog

**Stats**
プロダクトコードのクラス数、行数、メソッド数の統計およびテストコードの行数とプロダクトコード：テストコード比など

**Reek**
コードの臭いの抽出
https://github.com/troessner/reek/wiki

**Hotspots**
各分析結果から、結果の悪いプログラムを順に表示する


###追加されるタスク

gemをインストールすると、下記のようなタスクが追加されます。

```
$ rake -T | grep metrics
rake code_metrics:line_statistics[file_pattern]  # Report LOC for each file, and a total LOC for the list of files
rake code_metrics:stats                          # Report code statistics (KLOCs, etc) from the application
rake metrics:all[options]                        # Generate all metrics reports, or with options, for example:  rake metrics:all['cane: {abc_max: 81}']
rake metrics:cane[options]                       # Generate report for cane, or with options, for example:  rake metrics:cane['cane: {abc_max: 81}']
rake metrics:churn[options]                      # Generate report for churn, or with options, for example:  rake metrics:cane['cane: {abc_max: 81}']
rake metrics:flay[options]                       # Generate report for flay, or with options, for example:  rake metrics:cane['cane: {abc_max: 81}']
rake metrics:flog[options]                       # Generate report for flog, or with options, for example:  rake metrics:cane['cane: {abc_max: 81}']
rake metrics:hotspots[options]                   # Generate report for hotspots, or with options, for example:  rake metrics:cane['cane: {abc_max: 81}']
rake metrics:only[metrics,options]               # Run only specified ;-separated metrics, for example, metrics:only[cane;flog] or with options, for example:  rake metrics:only['cane: {abc_max: 81}']
rake metrics:rails_best_practices[options]       # Generate report for rails_best_practices, or with options, for example:  rake metrics:cane['cane: {abc_max: 81}']
rake metrics:reek[options]                       # Generate report for reek, or with options, for example:  rake metrics:cane['cane: {abc_max: 81}']
rake metrics:roodi[options]                      # Generate report for roodi, or with options, for example:  rake metrics:cane['cane: {abc_max: 81}']
rake metrics:saikuro[options]                    # Generate report for saikuro, or with options, for example:  rake metrics:cane['cane: {abc_max: 81}']
rake metrics:stats[options]                      # Generate report for stats, or with options, for example:  rake metrics:cane['cane: {abc_max: 81}']
```

###実際の実行イメージ

```
$ rake metrics:all
******* STARTING METRIC rails_best_practices
******* ENDING METRIC rails_best_practices
******* STARTING METRIC cane
******* ENDING METRIC cane
******* STARTING METRIC reek
******* ENDING METRIC reek
******* STARTING METRIC flay
******* ENDING METRIC flay
******* STARTING METRIC stats
******* ENDING METRIC stats
******* STARTING METRIC saikuro
******* ENDING METRIC saikuro
******* STARTING METRIC flog
******* ENDING METRIC flog
******* STARTING METRIC roodi
STDERR from roodi:
/usr/local/rvm/gems/ruby-2.3.0/gems/roodi-3.3.1/lib/roodi/core/runner.rb:52:in `output_result': Found 3 errors. (RuntimeError)
        from /usr/local/rvm/gems/ruby-2.3.0/gems/roodi-3.3.1/lib/roodi/core/runner.rb:41:in `start'
        from /usr/local/rvm/gems/ruby-2.3.0/gems/roodi-3.3.1/bin/roodi:13:in `<top (required)>'
        from /usr/local/rvm/gems/ruby-2.3.0/bin/roodi:23:in `load'
        from /usr/local/rvm/gems/ruby-2.3.0/bin/roodi:23:in `<main>'
        from /usr/local/rvm/gems/ruby-2.3.0/bin/ruby_executable_hooks:15:in `eval'
        from /usr/local/rvm/gems/ruby-2.3.0/bin/ruby_executable_hooks:15:in `<main>'
******* ENDING METRIC roodi
******* STARTING METRIC churn
******* ENDING METRIC churn
******* STARTING METRIC hotspots
******* ENDING METRIC hotspots
******* SAVING REPORTS
******* GENERATING GRAPHS
*****Generating graphs
*****Generating graphs for tmp/metric_fu/_data/20160106.yml
```


「tmp/metric_fu/」ディレクトリに

```
$ ls
_data/  output/  report.yml  scratch/
```
のようなファイル構成で出力されています。

「output」ディレクトリの中にHTMLファイルが出力されています。

###HTML出力結果イメージ

**Hotspots**のページのイメージです。
index.htmlを元に、それぞれの項目ごとにページが作成されます。

![metrics-image.png](https://qiita-image-store.s3.amazonaws.com/0/40418/30039aa0-3ba0-d257-e67d-19b1ce558ebf.png)

###補足（だが重要）

``rake code_metrics:stats``コマンドで下記のような統計が得られますので、毎回、開発時に統計を集計すると良いかと思います。
**多分、この機能が一番使えます。**

```
$ rake code_metrics:stats
+----------------------+-------+-------+---------+---------+-----+-------+
| Name                 | Lines |   LOC | Classes | Methods | M/C | LOC/M |
+----------------------+-------+-------+---------+---------+-----+-------+
| Controllers          |   721 |   498 |      16 |      76 |   4 |     4 |
| Helpers              |    29 |    25 |       0 |       2 |   0 |    10 |
| Models               |   270 |    86 |       7 |       6 |   0 |    12 |
| Mailers              |    55 |    19 |       1 |       1 |   1 |    17 |
| Javascripts          |  2085 |  1312 |       0 |     131 |   0 |     8 |
| Libraries            |    20 |    16 |       1 |       1 |   1 |    14 |
| Controller tests     |     0 |     0 |       0 |       0 |   0 |     0 |
| Helper tests         |     0 |     0 |       0 |       0 |   0 |     0 |
| Model tests          |     0 |     0 |       0 |       0 |   0 |     0 |
| Mailer tests         |     0 |     0 |       0 |       0 |   0 |     0 |
| Integration tests    |     0 |     0 |       0 |       0 |   0 |     0 |
+----------------------+-------+-------+---------+---------+-----+-------+
| Total                |  3180 |  1956 |      25 |     217 |   8 |     7 |
+----------------------+-------+-------+---------+---------+-----+-------+
  Code LOC: 1956     Test LOC: 0     Code to Test Ratio: 1:0.0
```