直径1.5メートル

ひよっこエンジニアのちょっとしたメモ。主に備忘録。たまに雑記。

【Rails】rubocopを変更を加えたファイルに限定して実行する

コーディングルールをチェックしてくれるrubocopですが、途中から導入すると、ほとんどの場合ほぼ全ファイル修正する必要があるため、修正をやり遂げる前に力尽きます。
気合いで完遂したとしても、その量のレビューはちょっと辛く思ってしまったり。なんだり。
とりあえずは、自身が修正を加えたファイルに対してrubocop修正もできれば、修正祭は避けられます。

ということで、変更ファイルに限定して実行するようにしました。

git diffの結果に対してrubocop

修正を加えたところはgit diffで取得できます。

git diffだけでは差分の範囲なども表示してくれますが、rubocopで指定したいのはファイルなので、差分はファイル名で欲しいです。
なので、git diff--name-onlyオプションを追加して、ファイルのみ取得します。
rubocop実行のところはxargsで。

$ git diff --name-only | xargs bundle exec rubocop

削除ファイルは対象にしない

また、git管理されていたファイルを削除した場合、差分としては取得できるものの、そのままrubocopを実行するとno such fileと言われてしまいます。
「削除したファイルは差分として取得しなくても良い」として、差分取得時に--diff-filterオプションで、変更したファイルに限定します。

$ git diff --diff-filter=ACMR --name-only | xargs bundle exec rubocop

diff-filterに指定しているACMRは、それぞれ
- A…Added
- C…Copied
- M…Modified
- R…Renamed
です。

差分がなければ実行しない

git diff --diff-filter=ACMR --name-onlyの結果、差分がないとbundle exec rubocopが実行され、全ファイルがrubocopチェック対象になります。
これでは今までゴニョゴニョしてきたオプションが水の泡。rubocopに怒られまくります。

差分がなければrubocopを実行しなければ良いので、xargsの-r, --no-run-if-emptyオプションを使います。

$ git diff --diff-filter=ACMR --name-only | xargs --no-run-if-empty bundle exec rubocop

(xargs -r bundle exec rubocopでも)
Mac上で実行するときは、--no-run-if-emptyをつけると「そんなオプションありません!」と怒られます。
オプションをつけずにxargs bundle exec rubocopのままでも、差分がなければ実行しないようになっているようです。