rubocop 指摘点の修正手順

そもそも、 SideCI などをいれるとか、Editor に組み込むのがよいと思います。
以下は、なんらかの理由によりあえて rubocop を手元で動かしてチェックする手順です。

# 手順

## 全体感の把握

rubocop 指摘点がないかどうかチェック

```
% rubocop -D

  :
566 files inspected, 27 offenses detected
```

27 点の指摘があります。
内訳はこんな感じ。

```
% rubocop -D | egrep '[WC]:' | awk -F: '{print $5}' | sort | uniq -c
   3  Lint/UnneededSplatExpansion
   1  Lint/UselessAssignment
   3  Performance/SortWithBlock
   5  Style/CommentAnnotation
   2  Style/ConditionalAssignment
   2  Style/EmptyLines
   1  Style/EmptyLinesAroundBlockBody
   1  Style/EmptyLinesAroundMethodBody
   8  Style/GuardClause
   1  Style/SafeNavigation
```

## Auto Correct

とりあえず autocorrect できるものは autocorrect してしまってから考えます。

```
for cop in `rubocop -D | egrep '[WC]:' | awk -F: '{print $5}' | sort -u`; do rubocop -a --only $cop && git commit -a -m "Fix '$cop'" ; done
```

こんな感じで Auto Correct されました。

```
e2b9f82 Fix 'Style/SafeNavigation'
004623f Fix 'Style/EmptyLinesAroundMethodBody'
6ad69a8 Fix 'Style/EmptyLinesAroundBlockBody'
5e0bbb3 Fix 'Style/EmptyLines'
914c7ff Fix 'Style/ConditionalAssignment'
0ddddbc Fix 'Style/CommentAnnotation'
9268067 Fix 'Performance/SortWithBlock'
57de2e6 Fix 'Lint/UnneededSplatExpansion'
70fcd3f Fix Lint/UnderscorePrefixedVariableName
```

## Auto Correct されたものを確認

動作に影響のある修正もあるので1つずつ変更点を確認します。

```diff
-          password_chars = [*'0'..'9', *'a'..'z', *'A'..'Z', *%w(! @ # $ % & * ?)]
+          password_chars = [*'0'..'9', *'a'..'z', *'A'..'Z', %w(! @ # $ % & * ?)]
```

これは動作に影響があるので修正します。

まず、その cop がどういうものなのかを確認するため、cop のソースコードを確認します。
https://github.com/bbatsov/rubocop/blob/master/lib/rubocop/cop/lint/unneeded_splat_expansion.rb

このケースは `*[...]` のような書き方をやめましょうということでした。
一度変数などに格納してから配列展開をするのは good と書いているのでそうします。
さらに、この際 PasswordGenerator を作ってそこに移譲してしまうことにした。
行う修正箇所が、既存のテストでカバーされていないようなら、まずテスト書いてしまったほうが楽なのでそうします。

詳細は割愛して次にいきます。


```diff
-      case score.to_f - i
+      tag_text += case score.to_f - i
       when 1..Float::INFINITY
-        tag_text += image_tag asset_path('img/common/star_yellow.svg'), alt: ''
+        image_tag asset_path('img/common/star_yellow.svg'), alt: ''
       when 0.5..1
-        tag_text += image_tag asset_path('img/common/star_half.svg'), alt: ''
+        image_tag asset_path('img/common/star_half.svg'), alt: ''
       else
-        tag_text += image_tag asset_path('img/common/star_gray.svg'), alt: ''
-      end
+        image_tag asset_path('img/common/star_gray.svg'), alt: ''
+                  end
```

これは end の indent がおかしいですね。
どうやら `end` は `if` や `case` の位置に合わせるようにしているらしいが `else` や `when` はそうならならないのでちぐはぐな結果になってしまっているように見えます。
修正します。これはさすがにテストなしでOK。


すべての変更を確認したら、もういちど rubocop をかけてみる。

```
% rubocop -D | egrep '[WC]:' | awk -F: '{print $5}' | sort | uniq -c
   1  Lint/AmbiguousRegexpLiteral
   2  Lint/EndAlignment
   1  Lint/UselessAssignment
   1  Performance/TimesMap
   2  Style/CaseIndentation
   1  Style/ElseAlignment
   8  Style/GuardClause
   1  Style/IndentationWidth
   1  Style/TrailingBlankLines
```

けっこう残ってるなぁ。。


## 手で修正

あとは１つ１つ手動で確認していきます。

```
% rubocop -D --only Style/GuardClause

Offenses:

lib/.../product.rb:10:7: C: Style/GuardClause: Use a guard clause instead of wrapping the code inside a conditional expression.
      if defined_css.text =~ /品番/
      ^^
  :
568 files inspected, 8 offenses detected
```

まず、修正すべきなのか、プロジェクトルールとして許容したほうがよさそうなのか確認します。
もし、プロジェクトルールに追加すべきなら `.rubocop.yml` に追加します。

```.rubocop.yml.patch
+# https://github.com/bbatsov/rubocop/issues/3516
+Style/VariableNumber:
+  Enabled: false
```

COPごとプロジェクトルールにすべきではないが、個別に無視したいものもあります。
これらも `.rubocop.yml` に追加します。

```.rubocop.yml.patch
+Lint/ParenthesesAsGroupedExpression:
+  Exclude:
+    - 'app/uploaders/abstract_uploader.rb'
```

あとは、コードを修正します。
インターンの練習用にとてもよい題材なので、あとはインターンに任せます。