require:
  - rubocop-minitest
  - rubocop-packaging
  - rubocop-performance
  - rubocop-rails

# gem "rubocop", "1.65.1", require: false
# gem "rubocop-minitest", "0.35.1", require: false
# gem "rubocop-performance", "1.21.1", require: false
# gem "rubocop-packaging", "0.5.2", require: false
AllCops:
  NewCops: enable # pending cops get enabled by default and must be disabled by hand, if needed


# BEGIN Customizations
# BEGIN Gemspec
# our custom gems are not uploaded to rubygems.org, so this is unnecessary
Gemspec/RequireMFA:
  Enabled: false
# END Gemspec

# BEGIN Layout
# only before, enforcing also after adds too many blank lines
Layout/EmptyLinesAroundAccessModifier:
  EnforcedStyle: only_before # default: around

# indent first element one level deeper than the 'parent'
Layout/FirstArrayElementIndentation:
  EnforcedStyle: consistent # default: special_inside_parentheses

# indent first element one level deeper than the 'parent'
Layout/FirstHashElementIndentation:
  EnforcedStyle: consistent # default: special_inside_parentheses

# every screen should be able to handle 150 characters
Layout/LineLength:
  Max: 150 # default: 120

# indent each method call one level deeper than the 'parent'
Layout/MultilineMethodCallIndentation:
  EnforcedStyle: indented # default: aligned
# END Layout


# BEGIN Metrics
# too restrictive, this kind of high complexity is needed at times
Metrics/AbcSize:
  Enabled: false

# default is too restrictive, however, having some restriction incentivizes to use helper methods
Metrics/BlockLength:
  AllowedMethods: ['class_eval', 'module_eval', 'refine'] # default: 'refine'
  CountAsOne: &array_hash_heredoc_method_call ['array', 'hash', 'heredoc', 'method_call'] # default: []
  Exclude: &test_config_db ['*.gemspec', '*/config/**/*', 'test/**/*', 'config/**/*', 'db/**/*']

# default is too restrictive, having some restriction incentivizes to split up overly large classes
Metrics/ClassLength:
  CountAsOne: *array_hash_heredoc_method_call # default: []
  Max: 200 # default: 100
  Exclude: *test_config_db

# default is too restrictive, allow higher complexity
Metrics/CyclomaticComplexity:
  Max: 14 # default: 7

# default is too restrictive, allow longer methods
Metrics/MethodLength:
  CountAsOne: *array_hash_heredoc_method_call # default: []
  Max: 30 # default: 10
  Exclude: *test_config_db

# default is too restrictive, allow longer modules
Metrics/ModuleLength:
  CountAsOne: *array_hash_heredoc_method_call # default: []
  Max: 200 # default: 100
  Exclude: *test_config_db

# long parameter lists add too much complexity, keyword args are named and thus more obvious what is expected, ignore them
Metrics/ParameterLists:
  CountKeywordArgs: false # default: true

# default is too restrictive, allow higher complexity
Metrics/PerceivedComplexity:
  Max: 16 # default: 8
# END Metrics


# BEGIN Minitest
# seems kind of buggy, when a custom message is given, this is flagged
Minitest/AssertWithExpectedArgument:
  Enabled: false

# allow more assertions than default, but also not too many
Minitest/MultipleAssertions:
  Max: 8 # default: 3
# END Minitest


# BEGIN Naming
# the default gem module must be named like the gem, so allow dashes
Naming/FileName:
  Exclude: ['lib/*.rb']
# END Naming


# BEGIN Rails
# file paths should be built with arguments instead of a single string
Rails/ApplicationController:
  Exclude: ['app/controllers/api/**/*', 'app/controllers/a_p_i/**/*'] # exclude API namespace, but not others (convention)

# exclude migrations since non-ApplicationRecord behavior might be desired
Rails/ApplicationRecord:
  Exclude: ['db/migrate/*']

# ensure paths are built using a filesystem agnostic way, i.e. arguments instead of a single string
Rails/FilePath:
  EnforcedStyle: arguments # default: slashes

# no reason not to use an established Rails feature if developers see fit
Rails/HasAndBelongsToMany:
  Enabled: false

# prevent puts, but exclude test, config, db since Rails Logger may not have been loaded
Rails/Output:
  Exclude: ['test/**/*', 'config/**/*', 'db/**/*']

# allow usage of methods that skip validations; we trust developers know what they are doing
Rails/SkipsModelValidations:
  Enabled: false

# allow usage of three-state boolean columns, it may be an STI table
Rails/ThreeStateBooleanColumn:
  Enabled: false
# END Rails


# BEGIN Style
# allow compact style for gems that contain app directory for rails integration
Style/ClassAndModuleChildren:
  Exclude: ['app/**/*']

# documentation of classes in migrations and tests is not needed
Style/Documentation:
  Exclude: *test_config_db

# allow in auto-generated files
Style/GlobalStdStream:
  Exclude: *test_config_db

# allow empty parentheses to differentiate method calls vs attributes
Style/MethodCallWithoutArgsParentheses:
  Enabled: false

# explicit returns are nice and convey meaning, so allow them
Style/RedundantReturn:
  Enabled: false

# allow for explicit calls to self to help differentiate between method calls vs local variables
Style/RedundantSelf:
  Enabled: false

# enforce double quotes in string literals
Style/StringLiterals:
  EnforcedStyle: double_quotes # default: single_quotes

# enforce double quotes inside string interpolations
Style/StringLiteralsInInterpolation:
  EnforcedStyle: double_quotes # default: single_quotes

# allow only brackets, not %i or %I
Style/SymbolArray:
  EnforcedStyle: brackets # default: percent
  MinSize: 1 # default: 2

# allow only brackets, not %w or %W
Style/WordArray:
  EnforcedStyle: brackets # default: percent
  MinSize: 1 # default: 2
# END Style
