Rubocop
Standard
Now we switch to standard gem https://github.com/testdouble/standard which provides better defaults than rubocop
Install with
gem "standard", "~> 1.0", require: false
and add
# .rubocop.yml
require: standard
inherit_gem:
standard: config/base.yml
If you want to use todos https://evilmartians.com/chronicles/rubocoping-with-legacy-bring-your-ruby-code-up-to-standard
# .rubocop.yml
# We want Exclude directives from different
# config files to get merged, not overwritten
inherit_mode:
merge:
- Exclude
require:
# Standard's config uses custom cops, # so it must be loaded
- standard
inherit_gem:
standard: config/base.yml
# You can also choose a Ruby-version-specific config
# standard: config/ruby-3.0.yml
inherit_from:
- .rubocop_todo.yml
- .rubocop_strict.yml
# Sometimes we enable metrics cops
# (which are disabled in Standard by default)
#
# Metrics:
# Enabled: true
# Global options, like Ruby version
AllCops:
SuggestExtensions: false
TargetRubyVersion: 3.2
Enable in editors https://github.com/testdouble/standard#language-server-protocol-support
Rubocop
rubocop my-file.rb
# safe auto correct
rubocop -a
# auto correct all
rubocop -A
# auto correct only layout (formatting offenses)
rubocop -x
# only specific cops
rubocop --only Rails/Blank,Naming/FileName
# add rubocop comments that disable warnings and fix what can be fixes
rubocop --auto-correct --disable-uncorrectable
Cache is used by default AllCopps: UseCache
is true and stored in
~/.cache/rubocop_cache/
Configuration
https://docs.rubocop.org/rubocop/configuration.html Default configuration https://github.com/rubocop-hq/rubocop/blob/master/config/default.yml
Configuration can inherit parent configuration and override (hash are merged or
canceled with ~
, other types are overriden.
# rubocop --auto-gen-config # generate .rubocop_todo.yml
inherit_from: .rubocop_todo.yml
Rails/HasAndBelongsToMany:
Include:
- app/models/*.rb
Exclude:
- app/models/problematic.rb
Layout/LineLength:
Enabled: false
# info (still returns zero 0 value), refactor, convention, warning, error and fatal.
Lint:
Severity: error
Extension
# .rubocop.yml
require:
- ../my/file.rb
- rubocop-extension
Create using https://github.com/rubocop-hq/rubocop-extension-generator
rubocop-extension-generator rubocop-dependent
Instructions https://docs.rubocop.org/rubocop/development.html
Note pattern https://github.com/rubocop-hq/rubocop-ast/blob/master/docs/modules/ROOT/pages/node_pattern.adoc
Example how rubocop-rails check if there is an unique index for that column name https://github.com/rubocop-hq/rubocop-rails/blob/master/lib/rubocop/cop/rails/unique_validation_without_index.rb#L61
CI
TODO: https://nvuillam.github.io/mega-linter/installation/ for github action
https://docs.rubocop.org/rubocop/automated_code_review.html for example pronto
My defaults
Do not use home ~/.rubocop.yml
since it can be different for different
projects (it is by default included if there is no local .rubocop.yml
)
# http://blog.trk.in.rs/2021/02/06/rubocop/
# ~/.rubocop.yml is used when there is no local .rubocop.yml
AllCops:
Exclude:
- db/schema.rb
- node_modules/**/*
- db/migrate/*
# 'class ActionDispatch::IntegrationTest' in single line, no need two lines
Style/ClassAndModuleChildren:
Enabled: false
# it is OK that code explains instead top-level class documentation comment
Style/Documentation:
Enabled: false
# config, tasks and test for setup data could be very long
Metrics/BlockLength:
Exclude:
- 'lib/**/*'
- 'test/**/*'
- 'config/**/*'
# big test big ABC size
Metrics/AbcSize:
Max: 25
Exclude:
- 'test/**/*'
# line length is not important in db and tests
Layout/LineLength:
Max: 135
Exclude:
- 'db/**/*'
- 'test/**/*'
- 'spec/**/*'
# put comma after each line [1,]
Style/TrailingCommaInArrayLiteral:
Enabled: false
# put comma after each line {a:1,}
Style/TrailingCommaInHashLiteral:
Enabled: false
# also in arguments
Style/TrailingCommaInArguments:
Enabled: false
# methods in 10 lines are OK but some are bigger
Metrics/MethodLength:
Max: 15
Exclude:
- 'lib/**/*'
- 'test/**/*'
# classes could be huge in tests
Metrics/ClassLength:
Exclude:
- 'test/**/*'
# do not need to write # frozen_string_literal: true
Style/FrozenStringLiteralComment:
Enabled: false
# Rails:
# Enabled: true
# Rails/FilePath:
# Enabled: false
# errors.add(:base, 'Failed') and return false # no need to use &&
Style/AndOr:
Enabled: false
# assert_match /regexp/, response.body # no need for parenthesis
Lint/AmbiguousRegexpLiteral:
Enabled: false
# s = %q{Hi} # no need to use `%q` only for strings that contain both single quotes and double quotes
# Style/UnneededPercentQ:
# Style/RedudantPercentQ:
# Enabled: false
# class Post < ActiveRecord::Base # no need to subclass `ApplicationRecord`
# Rails/ApplicationRecord:
# Enabled: false
# $:.push File.expand_path('lib', __dir__) # no need to use $LOAD_PATH
Style/SpecialGlobalVars:
Enabled: false
# in scripts I like to define methods at the end using BEGIN block
Style/BeginBlock:
Enabled: false
# use refute_ instead of assert_not _ in minitest
# Rails/RefuteMethods:
# Enabled: false
# port: (Rails.env.production? ? nil : Rails.env.development? ? Rack::Server.new.options[:Port] : 3333),
Style/NestedTernaryOperator:
Enabled: false
Style/LambdaCall:
Enabled: false
# method(*%i[a b])
# Lint/UnneededSplatExpansion:
# Lint/RedudantSplatExpansion:
# Enabled: false
# new pending cops
Style/HashEachMethods:
Enabled: true
Style/HashTransformKeys:
Enabled: true
Style/HashTransformValues:
Enabled: true
# use two spaces for indent
Layout/MultilineMethodCallIndentation:
EnforcedStyle: indented
# Use attr_accessor in different places, near the related usage
Style/AccessorGrouping:
Enabled: false