コミット前に自動でRubocopを実行する(仮想開発環境編)
GithubのPR作成タイミングで、Rubocop を使ったコーディングスタイルのチェックをしている方々は多いのではないでしょうか。
私もその一人です。
原則、オールグリーンにならないとマージできないので、極力コーディングチェックで怒られたくありません。
pushする前に、Rubucopでチェックをしているのですが、仮想環境を使っているため
- 別画面に切り替えたり
- コードの同期を待ったり
- コマンドを実行したり
・・・地味なストレスが溜まります。
Gitのpre-commit
を使い、commitタイミングでRubocopを自動実行させる方法を教えていただいたので、仮想開発環境バージョンを残します。
Pre-commitとは
Git hookの仕組みの一つで、 コミットメッセージが入力される前に、任意のスクリプトを実行するできる機能です。
大雑把なイメージとしては、「git commit
コマンドを実行前に、スクリプトを走らせる機能」です。
その前に、Git hookとは、git
の特定のアクションを
実行する直前 または、 実行後
に、特定のスクリプトを実行するための仕組みです。
詳しくは、Gitの公式サイトへ
今回は、Rubocop で利用しますが、様々なタイミングでスクリプトを実行させることができるので、いろいろな活用方法が考えられます
仮想開発環境でRubocopを自動実行
Macで開発環境を構築している場合は、こちらの記事を参考に! 仮想開発環境版もこちらの記事を参考に作りました
$ cd <Railsプロジェクトのディレクトリ>
$ vim .git/hooks/pre-commit
===========================
#!/bin/bash
vagrant_path="<vagrantのディレクトリ>"
workspace_path="<Vagrant上のRailsプロジェクトディレクトリ>"
files=`git diff --cached --name-only --diff-filter=AM | grep '.rb$' | tr '\n' ' '` --- (1)
# 実行するファイルがなければ、何もしない
if [ ! -n "${files}" ]; then
exit
fi
echo 変更があったファイルにrubocopを実行します。
cd ${vagrant_path} && vagrant ssh -c "cd ${workspace_path} && bundle exec rubocop -RDa ${files}" --- (2)
echo rubocopの実行が完了しました。
exit $?
===========================
コマンドの解説
(1)では、変更差分があったファイル(git diff
の実行結果)の中から、 Rubyファイル(grep
)を抽出します。
その後、tr
コマンドで、文字列に含まれる改行を空白に変換します。
app/model/query.rb
(2)では、vagrant
ディレクトリに移動し、vagrantにSSH(vagrant ssh
)します。
vagrant ssh
コマンドは、-c
オプションをつけると、引数で渡したコマンドを実行してくれます。
cd ${workspace_path} && bundle exec rubocop -RDa ${files}
まず、vagrant内のRailsプロジェクトのディレクトリに移動(cd
)します。
Mac側のディレクトリではなく、vagrantに同期しているディレクトリなので気をつけましょう。
(1)で抽出したRubyファイルに対し、rubocopを実行します。
bundle exec rubocop -RDa app/model/query.rb
実行結果
pre-commit
ファイルを作った状態で、git commit
を試してみます。
yn-misaki$ git commit -m ":cop: テスト用"
変更があったファイルにrubocopを実行します。
Inspecting 1 file
.
1 file inspected, no offenses detected
rubocopの実行が完了しました。
[rubocop_test 5502ea0] :cop: テスト用
2 files changed, 9 insertions(+), 1 deletion(-)
vagrant内で、rubocopを実行し、その実行結果が返ってきます。
実行結果が2 files changed
となっているのは、 変更対象に.yml
ファイルがあるからです。
つまり、rubocopの実行対象外です。
ローカルと仮想開発環境の両方で使いたい場合・・・!
ローカル派と仮想派で、開発環境が分かれている場合、if文を入れて対応します。
$ vim .git/hooks/pre-commit
===========================
if [ -e ${vagrant_path} ]; then
cd ${vagrant_path} && vagrant ssh -c "cd ${workspace_path} && bundle exec rubocop -RDa ${files}"
else
bundle exec rubocop -RDa ${files}
fi
===========================
vagrantディレクトリが存在しないとき、ローカルでrubocopを実行します。
これで、ローカル派と仮想派が共存できる pre-commit
の完成です。
まとめ
pre-commit
を使うことで、自動でコーディングチェックができるようになりました。
pre-commit
を使いはじめてから、PR上でrubocopで怒られなくなり、どういうコードがダメなのか、気付く -> 直すができて良いです
あとは、rspec
もコミット前に実行させようかなーと思っています(もう一台仮想環境を作るか、同一のVagrant内で実行するか迷い中...)
参考
Author And Source
この問題について(コミット前に自動でRubocopを実行する(仮想開発環境編)), 我々は、より多くの情報をここで見つけました https://qiita.com/yn-misaki/items/adbc9a02be226bc10354著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .