rubocopやjshintなどをgit-hookにまとめて設定できるpre-commit gemが便利そう（メモ）

# rubocop
コードの品質を保つために、コード規約に準拠しているかどうかを調べようとした場合、rubyにはrubocopというgemが用意されています。

[bbatsov/rubocop](https://github.com/bbatsov/rubocop)
[Ruby - Rubocopを使ってコーディングルールへの準拠チェックを自動化 - Qiita](http://qiita.com/yaotti/items/4f69a145a22f9c8f8333)

rubocopについては、すでに多くの有益な記事があるので、詳しくは割愛します。
簡単に言えば、予め定義したルールに則さないコードを自動で見つけてくれるような物です。

```
Offenses:

test.rb:1:5: C: Use snake_case for methods and variables.
def badName
    ^^^^^^^
test.rb:2:3: C: Favor modifier if/unless usage when you have a single-line body. Another good alternative is the usage of control flow &&/||.
  if something
  ^^
test.rb:4:5: W: end at 4, 4 is not aligned with if at 2, 2
    end
    ^^^

1 file inspected, 3 offenses detected
```

この仕組みをgit-hookと組み合わせる事で、規約違反のコードはgit commitできないようにするなど、プロジェクトの品質を保つのに役立ちそうです。

[Gitフックを使っておかしいRubyコードをコミットできないようにする - Qiita](http://qiita.com/yuku_t/items/ad072418290a2b01a35a)

# jshint
一方、javascriptにもコード品質を保つために、jshint / jslintなどがあります。
[JavaScript - JSHint入門 - JSHintを使ってJSコードの信頼性を高める - Qiita](http://qiita.com/yuku_t/items/717d636a174ec37ad967)

こちらも、git-hookと合わせれば、javascriptの品質担保に役立ちそうです。

# pre-commit gem
そんななか、pre-commit gemという物を知ったので、メモとして書いておきます。

[jish/pre-commit](https://github.com/jish/pre-commit)

↑のgithubに書いてある説明はシンプルで、

```
A better pre-commit hook for git.
```

というものです。

#### install
```
$ gem install pre-commit
```

#### list
installできたら、デフォルトの状態を見てみましょう

```
$ pre-commit list
Available providers: default(0) git(10) git_old(11) yaml(20) env(30)
Available checks   : before_all ci closure coffeelint common console_log csslint debugger gemfile_path go jshint jslint json local merge_conflict migration nb_space php pry rails rspec_focus rubocop ruby ruby_symbol_hashrockets scss_lint tabs whitespace yaml
Default   checks   : common rails
Enabled   checks   : common rails
Evaluated checks   : tabs nb_space whitespace merge_conflict debugger pry local jshint console_log migration
Default   warnings : 
Enabled   warnings : 
Evaluated warnings : 
```

Available checks に便利そうなチェック項目が色々あります。

#### 設定
設定は`git`コマンドでも、`pre-commit`コマンドでもできるようです

```
pre-commit <enable|disable> <git|yaml> <checks|warnings> check1 [check2...]
```

試しに、jshintで、warningsが出るようにすると、

```
pre-commit enable  yaml warnings jshint
```
となります。
yamlは設定ファイルをyamlで作成します。
初回このコマンドを実行した場合は、下記のようなファイルができます

```lang:config/pre_commit.yml
---
:warnings_remove: []
:warnings_add:
- :jshint
```
このファイルは直接編集しても問題ありません。

ちなみに、warnings はエラー表示のみ。checksはcommit不可、となります。
rubocopはデフォルトで入っていないので、入れてあげましょう。

```
$ pre-commit enable yaml checks rubocop
```

### 反映
設定を色々やったのち、下記を叩くと

```
# In your git repo
$ pre-commit install
```

.git/hook/pre-commit ファイルが書き変わります。

```lang:.git/hooks/pre-commit
$ cat pre-commit
#!/usr/bin/env sh

# This hook has a focus on portability.
# This hook will attempt to setup your environment before running checks.
#
# If you would like `pre-commit` to get out of your way and you are comfortable
# setting up your own environment, you can install the manual hook using:
#
#     pre-commit install --manual
#

cmd=`git config pre-commit.ruby 2>/dev/null`
if   test -n "${cmd}"
then true
elif which rvm   >/dev/null 2>/dev/null
then cmd="rvm default do ruby"
elif which rbenv >/dev/null 2>/dev/null
then cmd="rbenv exec ruby"
else cmd="ruby"
fi

...
...
省略
```
元々hookが書いてある方は、上書きしないようにご注意を。


試しに、わざとエラーとなるコードを書いてみます
![58868833ad497d3.png](https://qiita-image-store.s3.amazonaws.com/0/25890/1d021b17-855b-c250-4087-9c9e2a3a83b8.png)
jshintのwarningsが出ており、またrubocopのエラーでcommitが失敗しています。

これで、rubyもjsもcoffeeも、まとめてコード規約違反はcommitできなくできそうです :)

## 参考
[Gitフックを使っておかしいRubyコードをコミットできないようにする - Qiita](http://qiita.com/yuku_t/items/ad072418290a2b01a35a)
[rubocopによる静的コード解析でRubyのコード品質を保つ | Act as Professional](http://hiroki.jp/rubocop)
[rubocop + pre-commitで規約違反のコードをコミットできないようにする | Oh My Enter!](http://www.ohmyenter.com/?p=1167)
[git用のpre-commit gemが便利すぎる - TakiTakeの日記](http://takitake.hatenablog.com/entry/2014/07/27/172151)