既存プロジェクトでRuboCopを始めるヒント

開発者が入れ替わりながら、直期間にわたって開発が続いているプロジェクトにRuboCopを導入することを考える。

このとき、コードの書き方にいろんなスタイルがあるとめんどくさいことになる。いきおいEnabled: falseにしてしまおうかという話になったりもする。

しかし考えてみると、そういうスタイルの問題はRuboCopによる自動修正が効くことが多い。となると、既存コードからの乖離が小さくなるようなスタイルを選択した上で、スタイルのみ自動修正すればよさそうだ。

そこで、どのスタイルを選択するのがよいか、そのヒントとして、各種スタイルを選択したときに実際にどれくらい引っかかるかを計測するスクリプトを作成してみた。

好みのスタイルを探す

たとえばRailsプロジェクトであれば、以下のようにapp、libあたりを指定して実行する。

ruby start_rubocop.rb -r rubocop-rails -r rubocop-performance -- app lilb > start_rubocop_hint.yml

コマンドラインの--の後にはファイル名やディレクトリ名を指定できる。指定したものを対象に実際にrubocopを実行し、その結果を集計してRuboCopの設定ファイルの形式で出力する。

ただし出力には複数のEnforcedStyleを含むので、適宜選択する必要がある。

たとえば以下のように、特定の一つだけが明らかに良い結果の場合はそれを選択するとよいかもしれない。

Layout/IndentFirstHashElement:
  EnforcedStyle: consistent                 # 11 offenses
  EnforcedStyle: special_inside_parentheses # 270 offenses (default)
  EnforcedStyle: align_braces               # 1718 offenses

また、どのスタイルを選んでも大きな違いがないようならRuboCopのデフォルトスタイルにする、つまり設定ファイルは特に記述しないという選択をするとよいかもしれない。

Style/FormatString:
  EnforcedStyle: percent # 8 offenses
  EnforcedStyle: format  # 10 offenses (default)
  EnforcedStyle: sprintf # 13 offenses

スタイル統一してみよう

こうした出力をもとに.rubocop.ymlを作成したら、コードスタイルを統一してしまおう。

まずはLayoutのみを対象として自動修正を実行する。

rubocop -x

改行位置や空白の入れ方の違いが修正の中心となるはずなので、修正後にgit diff -wなどとして意図せぬ差分が出ていないかを確認する。必要なら除外設定を加えておく。

また、自動修正により文法エラーが発していないかを確認しておく。(実際にそういうケースに出会ったことがある。)

rubocop -l

続いてStyleのみを対象として自動修正を試みる。

rubocop --only Style --safe --safe-auto-correct

設定によってはコードの構造を変える変更が行われることがある。テストを通すのはもちろんだが修正内容を個別に確認したほうがよい。その場合、複数のCopによる自動修正を一度に行ってしまうと差分が大きくなって、確認作業が煩雑になり過ぎるかもしれない。

少し手間がかかるが、いったん以下のようにして実際に行われる自動修正の内容を確認しておく。

rubocop --only Style --safe --safe-auto-correct --format json | \
  ruby -rjson -e 'pp JSON.parse(ARGF.read)["files"]
    .map {|f| f["offenses"].select {|o| o["corrected"] } }
    .flatten.group_by {|o| o["cop_name"] }
    .transform_values(&:size).sort_by {|_, v| v }'

自動修正された状態になってい婦のでgit restoreでいったん元に戻し、そして--onlyを指定して自動修正を実行していくとよい。たとえば次のように。

rubocop --only Style/SymbolArray --safe --safe-auto-correct

実際にやってみると、設定内容に不満が出てきたりするもので、何度かやり直しが必要になるかもしれない。

最初は少数のファイルだけを対象にして自動修正を行ってみて、その差分を確認してスタイルが好みに合っているか見てみるとよいだろう。RuboCopのドキュメントをながめながら「このスタイルの中からならこれだろう」と決めたものを、実際のコードに適用するとなんだか違った印象になることもままあるのだ。