YOSHINO日記

プログラミングに関すること

自作アプリにrubocopのデフォルト設定を適用した

はじめに

github.com

を参考にさせていただいてアプリを作成していたのでですが、やはりデフォルトから自分で設定を変えていく方向に変更する。

現時点。

120 files inspected, 585 offenses detected

Metrics/BlockLength:

spec無いのblockは説明するために日本語を入れるし、除外して良いと判断。 他にも長くなってもしょうがないだろうというのを除外。

Metrics/BlockLength:
  Exclude:
    - 'spec/**/*'
    - 'config/routes.rb'
    - 'db/migrate/**/*'
    - 'db/schema.rb'
    - 'lib/tasks/**/*
120 files inspected, 561 offenses detected

Style/FrozenStringLiteralComment

【Ruby】RuboCopのFrozenStringLiteralCommentについて - TASK NOTES

Ruby 2.3 から# frozen_string_literal: trueというマジックコメントを使用すると、文字列リテラルがデフォルトでfreezeされるようになりました。これは Ruby 3.0 では文字列リテラルがデフォルトで freeze (=不変) になる予定なので、互換性の問題もあり移行シュミレーションが可能なように導入されています。

Style/FrozenStringLiteralComment:
  EnforcedStyle: when_needed
  SupportedStyles:
    # `when_needed` will add the frozen string literal comment to files
    # only when the `TargetRubyVersion` is set to 2.3+.
    - when_needed
    # `always` will always add the frozen string literal comment to a file
    # regardless of the Ruby version or if `freeze` or `<<` are called on a
    # string literal. If you run code against multiple versions of Ruby, it is
    # possible that this will create errors in Ruby 2.3.0+.
    - always
    # `never` will enforce that the frozen string literal comment does not
    # exist in a file.
    - never

ファイルの先頭についきしていくのも冗長なので、

Style/FrozenStringLiteralComment:
  Enabled: false
120 files inspected, 442 offenses detected

Style/AsciiComments:

enabled.yml

デフォルトではASciiが設定されている

Style/AsciiComments:
  Description: 'Use only ascii symbols in comments.'
  StyleGuide: '#english-comments'
  Enabled: true

なのでこれをfalseにしてあげる。

Style/AsciiComments:
  Enabled: false
120 files inspected, 335 offenses detected

Metrics/MethodLength:

Metrics/MethodLength:
  CountComments: false  # count full line comments?
  Max: 1

db/migrate/はどうしてもメソッド名が長くなるので除外。 その他も同様のため除外。

後は既存のコードリファクタリングした。

Metrics/MethodLength:
  Exclude:
    - 'db/migrate/**/*'
    - 'lib/workers/europe_nutritional_requirement.rb'
    - 'lib/tasks/**/*
120 files inspected, 324 offenses detected

Metrics/LineLength

行の長さ。 デフォルト値は80。この値はけっこう厳しい。。。。

おもしろい記事がこちらにありました。

Metrics/LineLength のより良いデフォルト値を模索したい · Issue #32 · rubocop-hq/rubocop-jp · GitHub

こんな感じに修正

Metrics/LineLength:
  Max: 100
  # To make it possible to copy or click on URIs in the code, we allow lines
  # containing a URI to be longer than Max.
  AllowHeredoc: true
  AllowURI: true
  URISchemes:
    - http
    - https
  # The IgnoreCopDirectives option causes the LineLength rule to ignore cop
  # directives like '# rubocop: enable ...' when calculating a line's length.
  IgnoreCopDirectives: false
  # The IgnoredPatterns option is a list of !ruby/regexp and/or string
  # elements. Strings will be converted to Regexp objects. A line that matches
  # any regular expression listed in this option will be ignored by LineLength.
  IgnoredPatterns: []
  Exclude:
    - 'spec/**/*' # データ作成の時は1ラインのが好ましいと判断
    - 'config/**/*'
    - 'db/**/*'
    - 'Gemfile'
    - 'Rakefile'
    - 'app/models/stuff.rb' # hash.exceptするカラムを選ぶので

Style/ExpandPathArguments

FILE_ を使うのをやめて、dir__を使いましょう。

理由としてはこちらでdiscussionされていた。

ruby - Why is __FILE__ uppercase and __dir__ lowercase? - Stack Overflow

実際はキーワードではなくて、メソッドなのでdirのほうが名前的に適切ということだと思います。。。。

関連ファイルを修正しました。

いまさらながら、  --auto-correct

いや、最初からやろう。

120 files inspected, 784 offenses detected, 561 offenses corrected

自動補正されたcopたち 

Layout/IndentationWidth: Use 2

Layout/EmptyLinesAroundBlockBody: Extra empty line detected at block body beginning.

Style/TrailingCommaInArguments: Avoid comma after the last parameter of a method call

hashの終わりとかにコンマは残さない方が良いんですね。

Layout/AlignArray: Align the elements of an array literal if they span more than one line.

hash配列とかになったら、1行に1要素。補正されたところは、specのところで、あえてそうしていた部分もあるけど。

Layout/SpaceInsideArrayLiteralBrackets: Do not use space inside array brackets.

[ { hoge: 123 } ] はだめ。 [{ hoge: 123 }] は良い。 たしかに。

Style/ConditionalAssignment: Use the return of the conditional for variable assignment and comparison.

このルール自体は知っていたけれど、まさか自動補正してくれるとは。。。。

bad

if ENV['HEADED']
  options = Selenium::WebDriver::Chrome::Options.new(args: ['disable-gpu'])
else
   options = Selenium::WebDriver::Chrome::Options.new(args: ['headless', 'disable-gpu'])
end

good

  options = if ENV['HEADED']
              Selenium::WebDriver::Chrome::Options.new(args: ['disable-gpu'])
            else
              Selenium::WebDriver::Chrome::Options.new(args: ['headless', 'disable-gpu'])
            end

Style/BlockComments: Do not use block comments.

=begin =endのブロックコメントアウトは推奨されていないらしい。

  • Layout/CommentIndentation: Incorrect indentation detected これは相当、コレクトしてもらった。 コメントもrubyコードとところから書き始めると良いみたい。

このCOPは結構従っていない有名なgemとかも多そうだから、OSSできるかもしれん。。。?

でも見やすさからいったら、このCOPは外す人もいるかもしれん。

そうかもしれん。

Style/RescueStandardError: Avoid rescuing without specifying an error class.

こんなもんも、補正してくれるんかいシリーズ。

bad

begin
  user.save!
rescue
  puts 'skip user diplication error'
end

good

begin
  user.save!
rescue StandardError
  puts 'skip user diplication error'
end

Style/RescueModifier: Avoid using rescue in its modifier form.

これは使いたい衝動にかられる(機能的にコアではないところで)。

122 / 0 rescue puts "ok"

Layout/AlignHash: Align the elements of a hash literal if they span more than one line

hashのアライメントをそろえましょう。というはなし。

こういう部分を補正してくれるのなら、コードのインデントに気をくばることはそこそこに、 コミットしたら自動補正というサイクルが、コードを書く上で非常に効率が良さそうだと思った。

Style/SymbolArray: Use %i or %I for an array of symbols.

デフォルトで入ってきたコードだけど。

bad

t.index [ :record_type, :record_id, :name, :blob_id ], name: 'index_active_storage_attachments_uniqueness', unique: true

good

t.index %i[record_type record_id name blob_id], name: 'index_active_storage_attachments_uniqueness', unique: true

Layout/AlignParameters: Align the parameters of a method call if they span more than one line.

パラメーターもこんな感じにそろえると良いみたい。

ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
                                           Pathname.new(__FILE__).realpath)

Style/SymbolProc: Pass &:read as an argument to open instead of a block.

こんなのも補正してくれるんかい!!シリーズ。

content = File.open(yaml_path, &:read)
content = File.open(yaml_path) { |file| file.read }

未来を感じた。

Style/NilComparison: Prefer the use of the nil? predicate.

ルビーストなら絶対こんな書き方してるはずはないけど、補正してくれるみたい。

うっかりやってしまうこともある。

bad!!

 if max_size == nil

int/UnusedBlockArgument: Unused block argument - value. If it's necessary, use _ or _value as an argument name to indicate that it won't be used.

hashのループで使われていないなら、"_"を使いましょうというもの。

Style/EmptyLiteral: Use hash literal {} instead of Hash.new.

bad

options = Hash.new

good

options = {}

Style/IfUnlessModifier: Favor modifier unless usage when having a single-line body. Another good alternative is the usage of control flow &&/||.

bad

unless current_user.try(:admin?)
  puts "one line!!"
end

good!

puts "one line" unless current_user.try(:admin?)

Bundler/OrderedGems: Gems should be sorted in an alphabetical order within their section of the Gemfile

Gemfileの並び替えもしてくれるのさ

ここから手動でまたいろいろ見ていきます。

120 files inspected, 116 offenses detected

先は長いです。

Style/Documentation: Missing top-level class documentation comment

false。

※enabled.ymlで定義されていた。

Style/DocumentationMethod:
  Enabled: false

W: Lint/UselessAssignment

以下のように警告が出た。 英語前提なのだなあ。

offにすることにしました。

Gemfile:5:3: W: Lint/UselessAssignment: Useless assignment to variable - repo_name.
lib/tasks/food.rake:17:3: W: Lint/UselessAssignment: Useless assignment to variable - foods.
spec/models/recipe_spec.rb:27:7: W: Lint/UselessAssignment: Useless assignment to variable - katsuo.
spec/models/recipe_spec.rb:28:7: W: Lint/UselessAssignment: Useless assignment to variable - katsuo_quantity.
Lint/UselessAssignment:
  Description: 'Checks for useless assignment to a local variable.'
  StyleGuide: '#underscore-unused-vars'
  Enabled: false

Style/MixinUsage: include is used at the top level. Use inside class or module.

includeは文頭に書く。

Railsのデフォルトでもrequireの方が先頭に書かれていたけども。

Style/MixinUsage:

binディレクトリは例外でOK。

Style/MixinUsage:
  Description: 'Checks that `include`, `extend` and `prepend` exists at the top level.'
  Enabled: true
  Exclude:
    - 'bin/**/*'

Metrics/AbcSize:

データ作成のためのファイルとかは除外した。

デフォルト値は15で18に変更した。

コントローラーで、jsonとの分岐とかがあるときには、15はすごく厳しかった。

Metrics/AbcSize:
  # The ABC size is a calculated magnitude, so this number can be an Integer or
  # a Float.
  Max: 18
  Exclude:
    - 'db/migrate/**/*'
    - 'lib/tasks/**/*'
    - 'lib/workers/**/*'

Style/ClassAndModuleChildren:

ネストしたModule/ClassをRubyで定義する時のコーディングスタイルの話。 - Sooey

親のModule/Classが未定義になるケースを回避できるという点のようです。

なるほど。 でも、controllerで階層構造を作る時は、すごくまどろっこしい感じがする。

それに、Hoge::Fooみたいな書き方は、単純に名前空間で利用したいこともあると思うし、 falseでも良い気がしてきた。

今回は、直近、controllerだけ適用。

Style/ClassAndModuleChildren:
  # Checks the style of children definitions at classes and modules.
  #
  # Basically there are two different styles:
  #
  # `nested` - have each child on a separate line
  #   class Foo
  #     class Bar
  #     end
  #   end
  #
  # `compact` - combine definitions as much as possible
  #   class Foo::Bar
  #   end
  #
  # The compact style is only forced, for classes or modules with one child.
  EnforcedStyle: nested
  SupportedStyles:
    - nested
    - compact
  Exclude:
    - 'app/controllers/**/*'