Rubyでそれなりの規模のコード書くなら必ずと言っていいほど使いますよね。
僕はお仕事だとRailsを使っているのでRuboCopもガッツリ使っています。
最近RuboCopを実行しようとすると起動までがめっちゃ遅いっていう現象に悩まされていたんですよね。いったん動き出してしまえば普通なんですが。
bundle exec rubocop -Lとかして対象ファイルをリストアップするだけなのに4分とかかかるんです。原因と解決方法を調べてみました。
原因はどうもRuboCopが検索するファイル数が多いと遅くなるってことのようです。
解決するには以下のような感じで除外ディレクトリを指定すれば良かったです。
AllCops:
Exclude:
- '.git/**/*'
- 'public/**/*'
- 'log/**/*'
- 'tmp/**/*'
こんな感じにしたら4分かかっていたのが2秒以下になりました。劇的に改善してますね。
これで実行するのにストレスを感じずに済みそうです。
Railsのデフォルトで用意される
public、log、tmpあたりのディレクトリは、通常はRubyコード置きませんしファイル数も多くなりがちなので除外しちゃうのが良いです。そしてビックリすることにRuboCopは
.gitディレクトリも検索対象に含んでしまうのです!
.gitt配下のファイルをRuboCopで処理したいことなんてないと思うのでデフォルトで除外してほしいところですよね。※ちなみに2018/2/1現在の最新のRuboCop v0.52.1で確認してます。
普通は
.gitディレクトリが含まれたくらいでそこまでファイル数増えないはずなので問題ないと思うのですが、git subtreeを使っていると話が変わってきます。git subtree pushしたりすると.git/subtree-cacheにファイルが溜まります。今の案件ではgit subtreeを結構使っていて、1万コミットくらいあるリポジトリでsubtree pushしたらsubtree pushするたびに
.git/subtree-cacheに1万ファイルくらい増えているのを観測しました。僕の環境では200万ファイルくらい溜まっていました。これがRuboCopが激遅になってしまった原因だったのです。まさかgit subtreeがRuboCopに影響するなんて思ってもみませんでした。
git subtree便利なんですが、ハマりどころも多くてまたかーって気持ちになりました。
まぁひとまずRuboCopの起動速度改善してよかったです。
これで快適なRuboCopライフが送れます。
追記(2018/03/25)
.gitディレクトリが検索対象に含まれてしまう問題はv0.53.0で解消したようです。
こんにちは。
返信削除記事を読んでデフォルトの修正を直すべきだなーと思ったので、直してみました。 https://github.com/bbatsov/rubocop/pull/5542
次のリリースからは .git/ がデフォルトでExcludeされるようになります。
とてもわかりやすいブログ記事をありがとうございました!
コメントありがとうございます。
削除たしかにRubocopのデフォルトの設定を修正すべきですね。英語を書くのが億劫でPRしていませんでした……。
PRありがとうございました!