Docker環境でもGitのcommitやpushの前にRubocopのチェックをする
Rubocop + Docker = ツライ
Ruby のプロジェクトだと Rubocop を使うのは当たり前という感じもしますよね。
VSCode では ruby-rubocop を使ったり、Vim でも dense-analysis/ale を使ったりして、コードを書きながら Rubocop のチェックを通している人も多いのではないでしょうか?
しかし最近では Docker を使って環境を構築するケースも増えていて、そうするとローカルで Rubocop を動かすことができません。
Docker のコンテナ上で実行をしてエディターに結果を表示することもできますが、やはり実行速度がローカルよりも遅いのは気になります。
とはいえわざわざエディターでのチェックのために bundle install
を手元でするのは、せっかく開発環境を Docker で作っている意味が薄まってしまいます...。
ということで、エディター上でのリアルタイムでのチェックは諦めるけど、リモートに push する前に Rubocop のチェックを通すような方法を考えてみます。
Git のフック
Git には様々なイベントの前後に処理を挟むことができる Git フックという仕組みがあります。
(ドキュメント: Git - Git フック)
フックできるタイミングは様々ありますが、今回はその中でも pre-commit と pre-push のフックを使って Rubocop のチェックをしてみます。
それぞれ git commit
する前と git push
をする前に行われる処理を追加することができます。
git commit
する前に Rubocop のチェックをする
Git フックを使いたいときは次の手順で準備をします。
-
.git/hooks
にpre-commit
というファイルを追加 -
chmod a+x .git/hooks/pre-commit
で実行権限を与える
Docker で立ち上げたコンテナ上で Rubocop を実行するために、次の内容で pre-commit
を準備しましょう。
#!/bin/sh
if git diff --cached --name-only --diff-filter=AM | grep '\.rb$'; then
echo '---Rubocopで警告がないかチェック---'
git diff --cached --name-only --diff-filter=AM | grep '\.rb$' | xargs docker-compose exec -T web bundle exec rubocop --fail-level R --display-only-fail-level-offenses
fi
こうすることで git commit
する前に git diff
に含まれる .rb
のファイルをチェックすることができます。
またチェックに引っかかったファイルがある場合はコミットを中止してくれるので、誤ってコミットすることを防げます。
git push
する前に Rubocop のチェックをする
pre-commit と同様に pre-push のタイミングのフックも準備します。
-
.git/hooks
にpre-push
というファイルを追加 -
chmod a+x .git/hooks/pre-push
で実行権限を与える
pre-push の内容は次の内容にします。
#!/bin/sh
echo '---Rubocopで警告がないかチェック---'
docker-compose exec -T web bundle exec rubocop ./**/*.rb --fail-level R --display-only-fail-level-offenses
こうすることで git push
する前にプロジェクトの全ての .rb
のファイルをチェックすることができます。
またチェックに引っかかったファイルがある場合はプッシュを中止してくれるので、誤ってプッシュすることを防げます。
Rubocop + Docker + Git フック = 幸せ
Git フックを駆使することで Docker 環境でも Rubocop の手元でのチェックを自動化することができました。
GitHub Actions や CircleCI を使ってチェックしているとは思いますが、CI を待たず手元で気付くことができるとより素早く修正をすることができます。
自動でチェックをして素早く改善をして、余った時間は美味しいお菓子でも食べてのんびり過ごしましょう🍰
Discussion