こんにちは。株式会社バトンズでエンジニアをしている鈴木です。
先日開発中にハマった出来事についてご紹介します。
要約
- RubyMine 2023.3から、RuboCopのサーバーモードがサポートされるように
- RuboCopのサーバーモードのプロセスが起動していると、lint-stagedで実行したRuboCopが終了しない
- lint-stagedでRuboCopを実行する際に、
--no-server
オプションを付与して解決
問題発生:RuboCopが終わらない・・・
弊社バトンズのとあるサービスの開発では、Ruby関連のファイルのコミット時に、gitのpre-commitフックの仕組みで、RuboCopを実行しています。
このコミットフックでのRuboCopの実行には、husky + lint-stagedを利用しています。
ある日、このコミットフックで実行されるRuboCopが終わらない事象が発生しました。
調査
まずは、ps aux | grep rubocop
を実行し、RuboCopが動いているかどうかを確認しました。
すると、lint-stagedで実行されたと思しきRuboCopのプロセスは見つかったのですが、それとは別に(私としては)見慣れない、--server
オプションが付与されたRuboCopのプロセスも起動した状態になっていました。
このrubocop --server
のプロセスをkillしてからコミットしたところ、無事コミットフックのRuboCopの処理は正常終了し、コミットすることができました。
その後、「RuboCop server lint-staged」というキーワードでGoogle検索して行き着いた以下の記事を読ませていただき、RuboCopに高速化のためのサーバーモードが導入されていたこと、RuboCopのサーバーモードとlint-stagedの相性の悪さを理解・認識しました。
なぜサーバーモードのRuboCopが?
そこでまた一つの疑問が浮かびました。自分では起動した記憶のない、サーバーモードのRuboCopがなぜ起動しているのかと。
まず思い当たったのは、RubyMineのバージョンを最近あげたことでした。
(バトンズでは、希望者にはRubyMineのライセンスを提供しています。ちなみにバトンズエンジニアのRubyMine、Visual Studio Code、Vimの使用比率は6:3:1です。(鈴木調べ))
RubyMineのリリースノートを確認しました。
RubyMine は RuboCop のサーバーモードでの実行を自動的にサポートします。
なるほど、RubyMineがサーバーモードのRuboCopを起動していたのかと納得しました。
解決方法の検討
コミット前に毎回サーバーモードのRuboCopのプロセスをkillするのは面倒なので、別の解決方法を検討しました。
まず思いついたのは、RubyMine の RuboCopのサーバーモードを無効化することですが、無効化する設定は私には見つけられませんでした。
次に思いついたのは、lint-stagedでRuboCopを実行する際に、たとえサーバーモードのRuboCopが起動していたとしても、サーバーモードを使わずRuboCopを実行するオプションがないかを探したところ、--no-server
という、おおよそ期待する挙動を満たすオプションがありましたので、こちらを利用することにしました。
以下のように、lint-stagedで実行するRuboCopに--no-server
を付与するようにしました。
まとめ
RubyMine 2023.3を使い始めたらlint-stagedで実行しているRuboCopの実行が終わらないという事象に遭遇し、lint-stagedでのRuboCopの実行の際は--no-server
オプションを付与して解決した件についてご紹介しました。