Merge pull request #12997 from Homebrew/dependabot/bundler/Library/Homebrew/rubocop-rails-2.14.0

build(deps): bump rubocop-rails from 2.13.2 to 2.14.0 in /Library/Homebrew
This commit is contained in:
Nanda H Krishna 2022-03-15 15:05:23 -04:00 committed by GitHub
commit fed93bb934
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
128 changed files with 924 additions and 37 deletions

View File

@ -137,7 +137,7 @@ GEM
rubocop-performance (1.13.3) rubocop-performance (1.13.3)
rubocop (>= 1.7.0, < 2.0) rubocop (>= 1.7.0, < 2.0)
rubocop-ast (>= 0.4.0) rubocop-ast (>= 0.4.0)
rubocop-rails (2.13.2) rubocop-rails (2.14.0)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
rack (>= 1.1) rack (>= 1.1)
rubocop (>= 1.7.0, < 2.0) rubocop (>= 1.7.0, < 2.0)

View File

@ -36,6 +36,10 @@ RuboCop::Cop::ActiveRecordMigrationsHelper::POSTGRES_SCHEMA_DEFINITIONS = T.let(
RuboCop::Cop::ActiveRecordMigrationsHelper::RAILS_ABSTRACT_SCHEMA_DEFINITIONS = T.let(T.unsafe(nil), Array) RuboCop::Cop::ActiveRecordMigrationsHelper::RAILS_ABSTRACT_SCHEMA_DEFINITIONS = T.let(T.unsafe(nil), Array)
RuboCop::Cop::ActiveRecordMigrationsHelper::RAILS_ABSTRACT_SCHEMA_DEFINITIONS_HELPERS = T.let(T.unsafe(nil), Array) RuboCop::Cop::ActiveRecordMigrationsHelper::RAILS_ABSTRACT_SCHEMA_DEFINITIONS_HELPERS = T.let(T.unsafe(nil), Array)
module RuboCop::Cop::ClassSendNodeHelper
def class_send_nodes(class_node); end
end
module RuboCop::Cop::EnforceSuperclass module RuboCop::Cop::EnforceSuperclass
def on_class(node); end def on_class(node); end
def on_send(node); end def on_send(node); end
@ -119,6 +123,16 @@ end
module RuboCop::Cop::Rails; end module RuboCop::Cop::Rails; end
class RuboCop::Cop::Rails::ActionControllerTestCase < ::RuboCop::Cop::Base
extend ::RuboCop::Cop::AutoCorrector
extend ::RuboCop::Cop::TargetRailsVersion
def action_controller_test_case?(param0 = T.unsafe(nil)); end
def on_class(node); end
end
RuboCop::Cop::Rails::ActionControllerTestCase::MSG = T.let(T.unsafe(nil), String)
class RuboCop::Cop::Rails::ActionFilter < ::RuboCop::Cop::Base class RuboCop::Cop::Rails::ActionFilter < ::RuboCop::Cop::Base
include ::RuboCop::Cop::ConfigurableEnforcedStyle include ::RuboCop::Cop::ConfigurableEnforcedStyle
extend ::RuboCop::Cop::AutoCorrector extend ::RuboCop::Cop::AutoCorrector
@ -217,12 +231,13 @@ RuboCop::Cop::Rails::AddColumnIndex::MSG = T.let(T.unsafe(nil), String)
RuboCop::Cop::Rails::AddColumnIndex::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array) RuboCop::Cop::Rails::AddColumnIndex::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array)
class RuboCop::Cop::Rails::AfterCommitOverride < ::RuboCop::Cop::Base class RuboCop::Cop::Rails::AfterCommitOverride < ::RuboCop::Cop::Base
include ::RuboCop::Cop::ClassSendNodeHelper
def on_class(class_node); end def on_class(class_node); end
private private
def after_commit_callback?(node); end def after_commit_callback?(node); end
def class_send_nodes(class_node); end
def each_after_commit_callback(class_node); end def each_after_commit_callback(class_node); end
def named_callback?(node); end def named_callback?(node); end
end end
@ -364,10 +379,12 @@ class RuboCop::Cop::Rails::BulkChangeTable < ::RuboCop::Cop::Base
def call_to_combinable_alter_method?(child_node); end def call_to_combinable_alter_method?(child_node); end
def combinable_alter_methods; end def combinable_alter_methods; end
def combinable_transformations; end def combinable_transformations; end
def count_transformations(send_nodes); end
def database; end def database; end
def database_from_yaml; end def database_from_yaml; end
def database_yaml; end def database_yaml; end
def include_bulk_options?(node); end def include_bulk_options?(node); end
def send_nodes_from_change_table_block(body); end
def support_bulk_alter?; end def support_bulk_alter?; end
end end
@ -521,6 +538,53 @@ end
RuboCop::Cop::Rails::DelegateAllowBlank::MSG = T.let(T.unsafe(nil), String) RuboCop::Cop::Rails::DelegateAllowBlank::MSG = T.let(T.unsafe(nil), String)
RuboCop::Cop::Rails::DelegateAllowBlank::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array) RuboCop::Cop::Rails::DelegateAllowBlank::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array)
class RuboCop::Cop::Rails::DeprecatedActiveModelErrorsMethods < ::RuboCop::Cop::Base
def any_manipulation?(param0 = T.unsafe(nil)); end
def messages_details_assignment?(param0 = T.unsafe(nil)); end
def messages_details_manipulation?(param0 = T.unsafe(nil)); end
def on_send(node); end
def receiver_matcher_inside_model(param0 = T.unsafe(nil)); end
def receiver_matcher_outside_model(param0 = T.unsafe(nil)); end
def root_assignment?(param0 = T.unsafe(nil)); end
def root_manipulation?(param0 = T.unsafe(nil)); end
private
def model_file?; end
def receiver_matcher(node); end
end
RuboCop::Cop::Rails::DeprecatedActiveModelErrorsMethods::MANIPULATIVE_METHODS = T.let(T.unsafe(nil), Set)
RuboCop::Cop::Rails::DeprecatedActiveModelErrorsMethods::MSG = T.let(T.unsafe(nil), String)
class RuboCop::Cop::Rails::DuplicateAssociation < ::RuboCop::Cop::Base
include ::RuboCop::Cop::RangeHelp
include ::RuboCop::Cop::ClassSendNodeHelper
extend ::RuboCop::Cop::AutoCorrector
def association(param0 = T.unsafe(nil)); end
def on_class(class_node); end
private
def offenses(class_node); end
end
RuboCop::Cop::Rails::DuplicateAssociation::MSG = T.let(T.unsafe(nil), String)
class RuboCop::Cop::Rails::DuplicateScope < ::RuboCop::Cop::Base
include ::RuboCop::Cop::ClassSendNodeHelper
def on_class(class_node); end
def scope(param0 = T.unsafe(nil)); end
private
def offenses(class_node); end
end
RuboCop::Cop::Rails::DuplicateScope::MSG = T.let(T.unsafe(nil), String)
class RuboCop::Cop::Rails::DurationArithmetic < ::RuboCop::Cop::Base class RuboCop::Cop::Rails::DurationArithmetic < ::RuboCop::Cop::Base
extend ::RuboCop::Cop::AutoCorrector extend ::RuboCop::Cop::AutoCorrector
@ -877,6 +941,22 @@ end
RuboCop::Cop::Rails::HttpStatus::SymbolicStyleChecker::DEFAULT_MSG = T.let(T.unsafe(nil), String) RuboCop::Cop::Rails::HttpStatus::SymbolicStyleChecker::DEFAULT_MSG = T.let(T.unsafe(nil), String)
RuboCop::Cop::Rails::HttpStatus::SymbolicStyleChecker::MSG = T.let(T.unsafe(nil), String) RuboCop::Cop::Rails::HttpStatus::SymbolicStyleChecker::MSG = T.let(T.unsafe(nil), String)
class RuboCop::Cop::Rails::I18nLazyLookup < ::RuboCop::Cop::Base
include ::RuboCop::Cop::VisibilityHelp
extend ::RuboCop::Cop::AutoCorrector
def on_send(node); end
def translate_call?(param0 = T.unsafe(nil)); end
private
def controller_and_action(node); end
def controller_path(controller); end
def get_scoped_key(key_node, controller, action); end
end
RuboCop::Cop::Rails::I18nLazyLookup::MSG = T.let(T.unsafe(nil), String)
class RuboCop::Cop::Rails::I18nLocaleAssignment < ::RuboCop::Cop::Base class RuboCop::Cop::Rails::I18nLocaleAssignment < ::RuboCop::Cop::Base
def i18n_locale_assignment?(param0 = T.unsafe(nil)); end def i18n_locale_assignment?(param0 = T.unsafe(nil)); end
def on_send(node); end def on_send(node); end
@ -885,6 +965,17 @@ end
RuboCop::Cop::Rails::I18nLocaleAssignment::MSG = T.let(T.unsafe(nil), String) RuboCop::Cop::Rails::I18nLocaleAssignment::MSG = T.let(T.unsafe(nil), String)
RuboCop::Cop::Rails::I18nLocaleAssignment::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array) RuboCop::Cop::Rails::I18nLocaleAssignment::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array)
class RuboCop::Cop::Rails::I18nLocaleTexts < ::RuboCop::Cop::Base
def flash_assignment?(param0 = T.unsafe(nil)); end
def mail_subject(param0); end
def on_send(node); end
def redirect_to_flash(param0); end
def validation_message(param0); end
end
RuboCop::Cop::Rails::I18nLocaleTexts::MSG = T.let(T.unsafe(nil), String)
RuboCop::Cop::Rails::I18nLocaleTexts::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array)
class RuboCop::Cop::Rails::IgnoredSkipActionFilterOption < ::RuboCop::Cop::Base class RuboCop::Cop::Rails::IgnoredSkipActionFilterOption < ::RuboCop::Cop::Base
def filter_options(param0 = T.unsafe(nil)); end def filter_options(param0 = T.unsafe(nil)); end
def on_send(node); end def on_send(node); end
@ -1038,6 +1129,20 @@ RuboCop::Cop::Rails::MatchRoute::HTTP_METHODS = T.let(T.unsafe(nil), Array)
RuboCop::Cop::Rails::MatchRoute::MSG = T.let(T.unsafe(nil), String) RuboCop::Cop::Rails::MatchRoute::MSG = T.let(T.unsafe(nil), String)
RuboCop::Cop::Rails::MatchRoute::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array) RuboCop::Cop::Rails::MatchRoute::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array)
class RuboCop::Cop::Rails::MigrationClassName < ::RuboCop::Cop::Base
extend ::RuboCop::Cop::AutoCorrector
def on_class(node); end
private
def basename_without_timestamp; end
def to_camelcase(word); end
def to_snakecase(word); end
end
RuboCop::Cop::Rails::MigrationClassName::MSG = T.let(T.unsafe(nil), String)
class RuboCop::Cop::Rails::NegateInclude < ::RuboCop::Cop::Base class RuboCop::Cop::Rails::NegateInclude < ::RuboCop::Cop::Base
extend ::RuboCop::Cop::AutoCorrector extend ::RuboCop::Cop::AutoCorrector
@ -1131,11 +1236,12 @@ class RuboCop::Cop::Rails::Pluck < ::RuboCop::Cop::Base
extend ::RuboCop::Cop::TargetRailsVersion extend ::RuboCop::Cop::TargetRailsVersion
def on_block(node); end def on_block(node); end
def on_numblock(node); end
def pluck_candidate?(param0 = T.unsafe(nil)); end def pluck_candidate?(param0 = T.unsafe(nil)); end
private private
def message(method, argument, element, value); end def message(value, node); end
def offense_range(node); end def offense_range(node); end
end end
@ -1692,6 +1798,15 @@ RuboCop::Cop::Rails::SquishedSQLHeredocs::MSG = T.let(T.unsafe(nil), String)
RuboCop::Cop::Rails::SquishedSQLHeredocs::SQL = T.let(T.unsafe(nil), String) RuboCop::Cop::Rails::SquishedSQLHeredocs::SQL = T.let(T.unsafe(nil), String)
RuboCop::Cop::Rails::SquishedSQLHeredocs::SQUISH = T.let(T.unsafe(nil), String) RuboCop::Cop::Rails::SquishedSQLHeredocs::SQUISH = T.let(T.unsafe(nil), String)
class RuboCop::Cop::Rails::TableNameAssignment < ::RuboCop::Cop::Base
include ::RuboCop::Cop::ActiveRecordHelper
def base_class?(param0 = T.unsafe(nil)); end
def on_class(class_node); end
end
RuboCop::Cop::Rails::TableNameAssignment::MSG = T.let(T.unsafe(nil), String)
class RuboCop::Cop::Rails::TimeZone < ::RuboCop::Cop::Base class RuboCop::Cop::Rails::TimeZone < ::RuboCop::Cop::Base
include ::RuboCop::Cop::ConfigurableEnforcedStyle include ::RuboCop::Cop::ConfigurableEnforcedStyle
extend ::RuboCop::Cop::AutoCorrector extend ::RuboCop::Cop::AutoCorrector
@ -1736,6 +1851,14 @@ end
RuboCop::Cop::Rails::TimeZoneAssignment::MSG = T.let(T.unsafe(nil), String) RuboCop::Cop::Rails::TimeZoneAssignment::MSG = T.let(T.unsafe(nil), String)
RuboCop::Cop::Rails::TimeZoneAssignment::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array) RuboCop::Cop::Rails::TimeZoneAssignment::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array)
class RuboCop::Cop::Rails::TransactionExitStatement < ::RuboCop::Cop::Base
def exit_statements(param0); end
def on_send(node); end
end
RuboCop::Cop::Rails::TransactionExitStatement::MSG = T.let(T.unsafe(nil), String)
RuboCop::Cop::Rails::TransactionExitStatement::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array)
class RuboCop::Cop::Rails::UniqBeforePluck < ::RuboCop::Cop::Base class RuboCop::Cop::Rails::UniqBeforePluck < ::RuboCop::Cop::Base
include ::RuboCop::Cop::ConfigurableEnforcedStyle include ::RuboCop::Cop::ConfigurableEnforcedStyle
include ::RuboCop::Cop::RangeHelp include ::RuboCop::Cop::RangeHelp

View File

@ -5033,7 +5033,11 @@ module RuboCop::AST::NodePattern::Sets
SET_BUILD_RECOMMENDED_TEST_OPTIONAL = ::T.let(nil, ::T.untyped) SET_BUILD_RECOMMENDED_TEST_OPTIONAL = ::T.let(nil, ::T.untyped)
SET_DEPENDS_ON_USES_FROM_MACOS = ::T.let(nil, ::T.untyped) SET_DEPENDS_ON_USES_FROM_MACOS = ::T.let(nil, ::T.untyped)
SET_INCLUDE_WITH_WITHOUT = ::T.let(nil, ::T.untyped) SET_INCLUDE_WITH_WITHOUT = ::T.let(nil, ::T.untyped)
SET_MESSAGES_DETAILS = ::T.let(nil, ::T.untyped)
SET_NOTICE_ALERT = ::T.let(nil, ::T.untyped)
SET_REJECT_DELETE_IF_REJECT = ::T.let(nil, ::T.untyped)
SET_SYSTEM_SHELL_OUTPUT_PIPE_OUTPUT = ::T.let(nil, ::T.untyped) SET_SYSTEM_SHELL_OUTPUT_PIPE_OUTPUT = ::T.let(nil, ::T.untyped)
SET_TRANSLATE_T = ::T.let(nil, ::T.untyped)
SET_WITH_WITHOUT = ::T.let(nil, ::T.untyped) SET_WITH_WITHOUT = ::T.let(nil, ::T.untyped)
end end

View File

@ -86,7 +86,7 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-progressbar-1.11
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unicode-display_width-2.1.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unicode-display_width-2.1.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-1.26.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-1.26.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-performance-1.13.3/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-performance-1.13.3/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rails-2.13.2/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rails-2.14.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-2.9.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-2.9.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-sorbet-0.6.7/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-sorbet-0.6.7/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-macho-3.0.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-macho-3.0.0/lib"

View File

@ -7,7 +7,9 @@ inherit_mode:
AllCops: AllCops:
Exclude: Exclude:
- bin/* - bin/*
- db/schema.rb # Exclude db/schema.rb and db/[CONFIGURATION_NAMESPACE]_schema.rb by default.
# See: https://guides.rubyonrails.org/active_record_multiple_databases.html#setting-up-your-application
- db/*schema.rb
# What version of Rails is the inspected code using? If a value is specified # What version of Rails is the inspected code using? If a value is specified
# for TargetRailsVersion then it is used. Acceptable values are specified # for TargetRailsVersion then it is used. Acceptable values are specified
# as a float (i.e. 5.1); the patch version of Rails should not be included. # as a float (i.e. 5.1); the patch version of Rails should not be included.
@ -38,6 +40,16 @@ Lint/NumberConversion:
- fortnights - fortnights
- in_milliseconds - in_milliseconds
Rails/ActionControllerTestCase:
Description: 'Use `ActionDispatch::IntegrationTest` instead of `ActionController::TestCase`.'
StyleGuide: 'https://rails.rubystyle.guide/#integration-testing'
Reference: 'https://api.rubyonrails.org/classes/ActionController/TestCase.html'
Enabled: 'pending'
SafeAutocorrect: false
VersionAdded: '2.14'
Include:
- '**/test/**/*.rb'
Rails/ActionFilter: Rails/ActionFilter:
Description: 'Enforces consistent use of action filter methods.' Description: 'Enforces consistent use of action filter methods.'
Enabled: true Enabled: true
@ -195,9 +207,12 @@ Rails/ContentTag:
Enabled: true Enabled: true
VersionAdded: '2.6' VersionAdded: '2.6'
VersionChanged: '2.12' VersionChanged: '2.12'
# This `Exclude` config prevents false positives for `tag` calls to `has_one: tag`. No helpers are used in normal models. # This `Exclude` config prevents false positives for `tag` calls to `has_one: tag` and Puma configuration:
# https://puma.io/puma/Puma/DSL.html#tag-instance_method
# No helpers are used in normal models and configs.
Exclude: Exclude:
- app/models/**/*.rb - app/models/**/*.rb
- config/**/*.rb
Rails/CreateTableWithTimestamps: Rails/CreateTableWithTimestamps:
Description: >- Description: >-
@ -251,6 +266,22 @@ Rails/DelegateAllowBlank:
Enabled: true Enabled: true
VersionAdded: '0.44' VersionAdded: '0.44'
Rails/DeprecatedActiveModelErrorsMethods:
Description: 'Avoid manipulating ActiveModel errors hash directly.'
Enabled: pending
Safe: false
VersionAdded: '2.14'
Rails/DuplicateAssociation:
Description: "Don't repeat associations in a model."
Enabled: pending
VersionAdded: '2.14'
Rails/DuplicateScope:
Description: 'Multiple scopes share this same where clause.'
Enabled: pending
VersionAdded: '2.14'
Rails/DurationArithmetic: Rails/DurationArithmetic:
Description: 'Do not use duration as arithmetic operand with `Time.current`.' Description: 'Do not use duration as arithmetic operand with `Time.current`.'
StyleGuide: 'https://rails.rubystyle.guide#duration-arithmetic' StyleGuide: 'https://rails.rubystyle.guide#duration-arithmetic'
@ -415,6 +446,15 @@ Rails/HttpStatus:
- numeric - numeric
- symbolic - symbolic
Rails/I18nLazyLookup:
Description: 'Checks for places where I18n "lazy" lookup can be used.'
StyleGuide: 'https://rails.rubystyle.guide/#lazy-lookup'
Reference: 'https://guides.rubyonrails.org/i18n.html#lazy-lookup'
Enabled: pending
VersionAdded: '2.14'
Include:
- 'controllers/**/*'
Rails/I18nLocaleAssignment: Rails/I18nLocaleAssignment:
Description: 'Prefer the usage of `I18n.with_locale` instead of manually updating `I18n.locale` value.' Description: 'Prefer the usage of `I18n.with_locale` instead of manually updating `I18n.locale` value.'
Enabled: 'pending' Enabled: 'pending'
@ -423,6 +463,12 @@ Rails/I18nLocaleAssignment:
- spec/**/*.rb - spec/**/*.rb
- test/**/*.rb - test/**/*.rb
Rails/I18nLocaleTexts:
Description: 'Enforces use of I18n and locale files instead of locale specific strings.'
StyleGuide: 'https://rails.rubystyle.guide/#locale-texts'
Enabled: pending
VersionAdded: '2.14'
Rails/IgnoredSkipActionFilterOption: Rails/IgnoredSkipActionFilterOption:
Description: 'Checks that `if` and `only` (or `except`) are not used together as options of `skip_*` action filter.' Description: 'Checks that `if` and `only` (or `except`) are not used together as options of `skip_*` action filter.'
Reference: 'https://api.rubyonrails.org/classes/AbstractController/Callbacks/ClassMethods.html#method-i-_normalize_callback_options' Reference: 'https://api.rubyonrails.org/classes/AbstractController/Callbacks/ClassMethods.html#method-i-_normalize_callback_options'
@ -495,6 +541,13 @@ Rails/MatchRoute:
- config/routes.rb - config/routes.rb
- config/routes/**/*.rb - config/routes/**/*.rb
Rails/MigrationClassName:
Description: 'The class name of the migration should match its file name.'
Enabled: pending
VersionAdded: '2.14'
Include:
- db/migrate/*.rb
Rails/NegateInclude: Rails/NegateInclude:
Description: 'Prefer `collection.exclude?(obj)` over `!collection.include?(obj)`.' Description: 'Prefer `collection.exclude?(obj)` over `!collection.include?(obj)`.'
StyleGuide: 'https://rails.rubystyle.guide#exclude' StyleGuide: 'https://rails.rubystyle.guide#exclude'
@ -817,6 +870,15 @@ Rails/SquishedSQLHeredocs:
# to be preserved in order to work, thus auto-correction is not safe. # to be preserved in order to work, thus auto-correction is not safe.
SafeAutoCorrect: false SafeAutoCorrect: false
Rails/TableNameAssignment:
Description: >-
Do not use `self.table_name =`. Use Inflections or `table_name_prefix` instead.
StyleGuide: 'https://rails.rubystyle.guide/#keep-ar-defaults'
Enabled: false
VersionAdded: '2.14'
Include:
- app/models/**/*.rb
Rails/TimeZone: Rails/TimeZone:
Description: 'Checks the correct usage of time zone aware methods.' Description: 'Checks the correct usage of time zone aware methods.'
StyleGuide: 'https://rails.rubystyle.guide#time' StyleGuide: 'https://rails.rubystyle.guide#time'
@ -843,6 +905,11 @@ Rails/TimeZoneAssignment:
- spec/**/*.rb - spec/**/*.rb
- test/**/*.rb - test/**/*.rb
Rails/TransactionExitStatement:
Description: 'Avoid the usage of `return`, `break` and `throw` in transaction blocks.'
Enabled: pending
VersionAdded: '2.14'
Rails/UniqBeforePluck: Rails/UniqBeforePluck:
Description: 'Prefer the use of uniq or distinct before pluck.' Description: 'Prefer the use of uniq or distinct before pluck.'
Enabled: true Enabled: true

View File

@ -0,0 +1,20 @@
# frozen_string_literal: true
module RuboCop
module Cop
# A mixin to return all of the class send nodes.
module ClassSendNodeHelper
def class_send_nodes(class_node)
class_def = class_node.body
return [] unless class_def
if class_def.send_type?
[class_def]
else
class_def.each_child_node(:send)
end
end
end
end
end

View File

@ -0,0 +1,47 @@
# frozen_string_literal: true
module RuboCop
module Cop
module Rails
# Using `ActionController::TestCase`` is discouraged and should be replaced by
# `ActionDispatch::IntegrationTest``. Controller tests are too close to the
# internals of a controller whereas integration tests mimic the browser/user.
#
# @safety
# This cop's autocorrection is unsafe because the API of each test case class is different.
# Make sure to update each test of your controller test cases after changing the superclass.
#
# @example
# # bad
# class MyControllerTest < ActionController::TestCase
# end
#
# # good
# class MyControllerTest < ActionDispatch::IntegrationTest
# end
#
class ActionControllerTestCase < Base
extend AutoCorrector
extend TargetRailsVersion
MSG = 'Use `ActionDispatch::IntegrationTest` instead.'
minimum_target_rails_version 5.0
def_node_matcher :action_controller_test_case?, <<~PATTERN
(class
(const nil? _)
(const (const {nil? cbase} :ActionController) :TestCase) nil?)
PATTERN
def on_class(node)
return unless action_controller_test_case?(node)
add_offense(node.parent_class) do |corrector|
corrector.replace(node.parent_class, 'ActionDispatch::IntegrationTest')
end
end
end
end
end
end

View File

@ -32,6 +32,8 @@ module RuboCop
# after_update_commit :log_update_action # after_update_commit :log_update_action
# #
class AfterCommitOverride < Base class AfterCommitOverride < Base
include ClassSendNodeHelper
MSG = 'There can only be one `after_*_commit :%<name>s` hook defined for a model.' MSG = 'There can only be one `after_*_commit :%<name>s` hook defined for a model.'
AFTER_COMMIT_CALLBACKS = %i[ AFTER_COMMIT_CALLBACKS = %i[
@ -63,18 +65,6 @@ module RuboCop
end end
end end
def class_send_nodes(class_node)
class_def = class_node.body
return [] unless class_def
if class_def.send_type?
[class_def]
else
class_def.each_child_node(:send).to_a
end
end
def after_commit_callback?(node) def after_commit_callback?(node)
AFTER_COMMIT_CALLBACKS.include?(node.method_name) AFTER_COMMIT_CALLBACKS.include?(node.method_name)
end end

View File

@ -155,17 +155,31 @@ module RuboCop
return if include_bulk_options?(node) return if include_bulk_options?(node)
return unless node.block_node return unless node.block_node
send_nodes = node.block_node.body.each_child_node(:send).to_a send_nodes = send_nodes_from_change_table_block(node.block_node.body)
transformations = send_nodes.select do |send_node| add_offense_for_change_table(node) if count_transformations(send_nodes) > 1
combinable_transformations.include?(send_node.method_name)
end
add_offense_for_change_table(node) if transformations.size > 1
end end
private private
def send_nodes_from_change_table_block(body)
if body.send_type?
[body]
else
body.each_child_node(:send).to_a
end
end
def count_transformations(send_nodes)
send_nodes.sum do |node|
if node.method?(:remove)
node.arguments.count { |arg| !arg.hash_type? }
else
combinable_transformations.include?(node.method_name) ? 1 : 0
end
end
end
# @param node [RuboCop::AST::SendNode] (send nil? :change_table ...) # @param node [RuboCop::AST::SendNode] (send nil? :change_table ...)
def include_bulk_options?(node) def include_bulk_options?(node)
# arguments: [{(sym :table)(str "table")} (hash (pair (sym :bulk) _))] # arguments: [{(sym :table)(str "table")} (hash (pair (sym :bulk) _))]

View File

@ -13,6 +13,12 @@ module RuboCop
# `[[1, 2], [3, nil]].compact_blank` are not compatible. The same is true for `blank?`. # `[[1, 2], [3, nil]].compact_blank` are not compatible. The same is true for `blank?`.
# This will work fine when the receiver is a hash object. # This will work fine when the receiver is a hash object.
# #
# And `compact_blank!` has different implementations for `Array`, `Hash`, and
# `ActionController::Parameters`.
# `Array#compact_blank!`, `Hash#compact_blank!` are equivalent to `delete_if(&:blank?)`.
# `ActionController::Parameters#compact_blank!` is equivalent to `reject!(&:blank?)`.
# If the cop makes a mistake, auto-corrected code may get unexpected behavior.
#
# @example # @example
# #
# # bad # # bad
@ -23,8 +29,10 @@ module RuboCop
# collection.compact_blank # collection.compact_blank
# #
# # bad # # bad
# collection.reject!(&:blank?) # collection.delete_if(&:blank?) # Same behavior as `Array#compact_blank!` and `Hash#compact_blank!`
# collection.reject! { |_k, v| v.blank? } # collection.delete_if { |_k, v| v.blank? } # Same behavior as `Array#compact_blank!` and `Hash#compact_blank!`
# collection.reject!(&:blank?) # Same behavior as `ActionController::Parameters#compact_blank!`
# collection.reject! { |_k, v| v.blank? } # Same behavior as `ActionController::Parameters#compact_blank!`
# #
# # good # # good
# collection.compact_blank! # collection.compact_blank!
@ -35,20 +43,20 @@ module RuboCop
extend TargetRailsVersion extend TargetRailsVersion
MSG = 'Use `%<preferred_method>s` instead.' MSG = 'Use `%<preferred_method>s` instead.'
RESTRICT_ON_SEND = %i[reject reject!].freeze RESTRICT_ON_SEND = %i[reject delete_if reject!].freeze
minimum_target_rails_version 6.1 minimum_target_rails_version 6.1
def_node_matcher :reject_with_block?, <<~PATTERN def_node_matcher :reject_with_block?, <<~PATTERN
(block (block
(send _ {:reject :reject!}) (send _ {:reject :delete_if :reject!})
$(args ...) $(args ...)
(send (send
$(lvar _) :blank?)) $(lvar _) :blank?))
PATTERN PATTERN
def_node_matcher :reject_with_block_pass?, <<~PATTERN def_node_matcher :reject_with_block_pass?, <<~PATTERN
(send _ {:reject :reject!} (send _ {:reject :delete_if :reject!}
(block_pass (block_pass
(sym :blank?))) (sym :blank?)))
PATTERN PATTERN

View File

@ -0,0 +1,108 @@
# frozen_string_literal: true
module RuboCop
module Cop
module Rails
# This cop checks direct manipulation of ActiveModel#errors as hash.
# These operations are deprecated in Rails 6.1 and will not work in Rails 7.
#
# @safety
# This cop is unsafe because it can report `errors` manipulation on non-ActiveModel,
# which is obviously valid.
# The cop has no way of knowing whether a variable is an ActiveModel or not.
#
# @example
# # bad
# user.errors[:name] << 'msg'
# user.errors.messages[:name] << 'msg'
#
# # good
# user.errors.add(:name, 'msg')
#
# # bad
# user.errors[:name].clear
# user.errors.messages[:name].clear
#
# # good
# user.errors.delete(:name)
#
class DeprecatedActiveModelErrorsMethods < Base
MSG = 'Avoid manipulating ActiveModel errors as hash directly.'
MANIPULATIVE_METHODS = Set[
*%i[
<< append clear collect! compact! concat
delete delete_at delete_if drop drop_while fill filter! keep_if
flatten! insert map! pop prepend push reject! replace reverse!
rotate! select! shift shuffle! slice! sort! sort_by! uniq! unshift
]
].freeze
def_node_matcher :receiver_matcher_outside_model, '{send ivar lvar}'
def_node_matcher :receiver_matcher_inside_model, '{nil? send ivar lvar}'
def_node_matcher :any_manipulation?, <<~PATTERN
{
#root_manipulation?
#root_assignment?
#messages_details_manipulation?
#messages_details_assignment?
}
PATTERN
def_node_matcher :root_manipulation?, <<~PATTERN
(send
(send
(send #receiver_matcher :errors) :[] ...)
MANIPULATIVE_METHODS
...
)
PATTERN
def_node_matcher :root_assignment?, <<~PATTERN
(send
(send #receiver_matcher :errors)
:[]=
...)
PATTERN
def_node_matcher :messages_details_manipulation?, <<~PATTERN
(send
(send
(send
(send #receiver_matcher :errors)
{:messages :details})
:[]
...)
MANIPULATIVE_METHODS
...)
PATTERN
def_node_matcher :messages_details_assignment?, <<~PATTERN
(send
(send
(send #receiver_matcher :errors)
{:messages :details})
:[]=
...)
PATTERN
def on_send(node)
any_manipulation?(node) do
add_offense(node)
end
end
private
def receiver_matcher(node)
model_file? ? receiver_matcher_inside_model(node) : receiver_matcher_outside_model(node)
end
def model_file?
processed_source.buffer.name.include?('/models/')
end
end
end
end
end

View File

@ -0,0 +1,56 @@
# frozen_string_literal: true
module RuboCop
module Cop
module Rails
# This cop looks for associations that have been defined multiple times in the same file.
#
# When an association is defined multiple times on a model, Active Record overrides the
# previously defined association with the new one. Because of this, this cop's autocorrection
# simply keeps the last of any duplicates and discards the rest.
#
# @example
#
# # bad
# belongs_to :foo
# belongs_to :bar
# has_one :foo
#
# # good
# belongs_to :bar
# has_one :foo
#
class DuplicateAssociation < Base
include RangeHelp
extend AutoCorrector
include ClassSendNodeHelper
MSG = "Association `%<name>s` is defined multiple times. Don't repeat associations."
def_node_matcher :association, <<~PATTERN
(send nil? {:belongs_to :has_one :has_many :has_and_belongs_to_many} ({sym str} $_) ...)
PATTERN
def on_class(class_node)
offenses(class_node).each do |name, nodes|
nodes.each do |node|
add_offense(node, message: format(MSG, name: name)) do |corrector|
next if nodes.last == node
corrector.remove(range_by_whole_lines(node.source_range, include_final_newline: true))
end
end
end
end
private
def offenses(class_node)
class_send_nodes(class_node).select { |node| association(node) }
.group_by { |node| association(node).to_sym }
.select { |_, nodes| nodes.length > 1 }
end
end
end
end
end

View File

@ -0,0 +1,46 @@
# frozen_string_literal: true
module RuboCop
module Cop
module Rails
# This cop checks for multiple scopes in a model that have the same `where` clause. This
# often means you copy/pasted a scope, updated the name, and forgot to change the condition.
#
# @example
#
# # bad
# scope :visible, -> { where(visible: true) }
# scope :hidden, -> { where(visible: true) }
#
# # good
# scope :visible, -> { where(visible: true) }
# scope :hidden, -> { where(visible: false) }
#
class DuplicateScope < Base
include ClassSendNodeHelper
MSG = 'Multiple scopes share this same where clause.'
def_node_matcher :scope, <<~PATTERN
(send nil? :scope _ $...)
PATTERN
def on_class(class_node)
offenses(class_node).each do |node|
add_offense(node)
end
end
private
def offenses(class_node)
class_send_nodes(class_node).select { |node| scope(node) }
.group_by { |node| scope(node) }
.select { |_, nodes| nodes.length > 1 }
.values
.flatten
end
end
end
end
end

View File

@ -0,0 +1,94 @@
# frozen_string_literal: true
module RuboCop
module Cop
module Rails
# This cop checks for places where I18n "lazy" lookup can be used.
#
# @example
# # en.yml
# # en:
# # books:
# # create:
# # success: Book created!
#
# # bad
# class BooksController < ApplicationController
# def create
# # ...
# redirect_to books_url, notice: t('books.create.success')
# end
# end
#
# # good
# class BooksController < ApplicationController
# def create
# # ...
# redirect_to books_url, notice: t('.success')
# end
# end
#
class I18nLazyLookup < Base
include VisibilityHelp
extend AutoCorrector
MSG = 'Use "lazy" lookup for the text used in controllers.'
def_node_matcher :translate_call?, <<~PATTERN
(send nil? {:translate :t} ${sym_type? str_type?} ...)
PATTERN
def on_send(node)
translate_call?(node) do |key_node|
key = key_node.value
return if key.to_s.start_with?('.')
controller, action = controller_and_action(node)
return unless controller && action
scoped_key = get_scoped_key(key_node, controller, action)
return unless key == scoped_key
add_offense(key_node) do |corrector|
unscoped_key = key_node.value.to_s.split('.').last
corrector.replace(key_node, "'.#{unscoped_key}'")
end
end
end
private
def controller_and_action(node)
action_node = node.each_ancestor(:def).first
return unless action_node && node_visibility(action_node) == :public
controller_node = node.each_ancestor(:class).first
return unless controller_node && controller_node.identifier.source.end_with?('Controller')
[controller_node, action_node]
end
def get_scoped_key(key_node, controller, action)
path = controller_path(controller).tr('/', '.')
action_name = action.method_name
key = key_node.value.to_s.split('.').last
"#{path}.#{action_name}.#{key}"
end
def controller_path(controller)
module_name = controller.parent_module_name
controller_name = controller.identifier.source
path = if module_name == 'Object'
controller_name
else
"#{module_name}::#{controller_name}"
end
path.delete_suffix('Controller').underscore
end
end
end
end
end

View File

@ -0,0 +1,110 @@
# frozen_string_literal: true
module RuboCop
module Cop
module Rails
# Enforces use of I18n and locale files instead of locale specific strings.
#
# @example
# # bad
# class User < ApplicationRecord
# validates :email, presence: { message: "must be present" }
# end
#
# # good
# # config/locales/en.yml
# # en:
# # activerecord:
# # errors:
# # models:
# # user:
# # blank: "must be present"
#
# class User < ApplicationRecord
# validates :email, presence: true
# end
#
# # bad
# class PostsController < ApplicationController
# def create
# # ...
# redirect_to root_path, notice: "Post created!"
# end
# end
#
# # good
# # config/locales/en.yml
# # en:
# # posts:
# # create:
# # success: "Post created!"
#
# class PostsController < ApplicationController
# def create
# # ...
# redirect_to root_path, notice: t(".success")
# end
# end
#
# # bad
# class UserMailer < ApplicationMailer
# def welcome(user)
# mail(to: user.email, subject: "Welcome to My Awesome Site")
# end
# end
#
# # good
# # config/locales/en.yml
# # en:
# # user_mailer:
# # welcome:
# # subject: "Welcome to My Awesome Site"
#
# class UserMailer < ApplicationMailer
# def welcome(user)
# mail(to: user.email)
# end
# end
#
class I18nLocaleTexts < Base
MSG = 'Move locale texts to the locale files in the `config/locales` directory.'
RESTRICT_ON_SEND = %i[validates redirect_to []= mail].freeze
def_node_search :validation_message, <<~PATTERN
(pair (sym :message) $str)
PATTERN
def_node_search :redirect_to_flash, <<~PATTERN
(pair (sym {:notice :alert}) $str)
PATTERN
def_node_matcher :flash_assignment?, <<~PATTERN
(send (send nil? :flash) :[]= _ $str)
PATTERN
def_node_search :mail_subject, <<~PATTERN
(pair (sym :subject) $str)
PATTERN
def on_send(node)
case node.method_name
when :validates
validation_message(node) do |text_node|
add_offense(text_node)
end
return
when :redirect_to
text_node = redirect_to_flash(node).to_a.last
when :[]=
text_node = flash_assignment?(node)
when :mail
text_node = mail_subject(node).to_a.last
end
add_offense(text_node) if text_node
end
end
end
end
end

View File

@ -0,0 +1,61 @@
# frozen_string_literal: true
module RuboCop
module Cop
module Rails
# This cop makes sure that each migration file defines a migration class
# whose name matches the file name.
# (e.g. `20220224111111_create_users.rb` should define `CreateUsers` class.)
#
# @example
# # db/migrate/20220224111111_create_users.rb
#
# # bad
# class SellBooks < ActiveRecord::Migration[7.0]
# end
#
# # good
# class CreateUsers < ActiveRecord::Migration[7.0]
# end
#
class MigrationClassName < Base
extend AutoCorrector
MSG = 'Replace with `%<corrected_class_name>s` that matches the file name.'
def on_class(node)
snake_class_name = to_snakecase(node.identifier.source)
return if snake_class_name == basename_without_timestamp
corrected_class_name = to_camelcase(basename_without_timestamp)
message = format(MSG, corrected_class_name: corrected_class_name)
add_offense(node.identifier, message: message) do |corrector|
corrector.replace(node.identifier, corrected_class_name)
end
end
private
def basename_without_timestamp
filepath = processed_source.file_path
basename = File.basename(filepath, '.rb')
basename.sub(/\A\d+_/, '')
end
def to_camelcase(word)
word.split('_').map(&:capitalize).join
end
def to_snakecase(word)
word
.gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
.tr('-', '_')
.downcase
end
end
end
end
end

View File

@ -21,25 +21,31 @@ module RuboCop
extend AutoCorrector extend AutoCorrector
extend TargetRailsVersion extend TargetRailsVersion
MSG = 'Prefer `pluck(:%<value>s)` over `%<method>s { |%<argument>s| %<element>s[:%<value>s] }`.' MSG = 'Prefer `pluck(:%<value>s)` over `%<current>s`.'
minimum_target_rails_version 5.0 minimum_target_rails_version 5.0
def_node_matcher :pluck_candidate?, <<~PATTERN def_node_matcher :pluck_candidate?, <<~PATTERN
(block (send _ ${:map :collect}) (args (arg $_argument)) (send (lvar $_element) :[] (sym $_value))) ({block numblock} (send _ {:map :collect}) $_argument (send (lvar $_element) :[] (sym $_value)))
PATTERN PATTERN
def on_block(node) def on_block(node)
pluck_candidate?(node) do |method, argument, element, value| pluck_candidate?(node) do |argument, element, value|
next unless argument == element match = if node.block_type?
argument.children.first.source.to_sym == element
else # numblock
argument == 1 && element == :_1
end
next unless match
message = message(method, argument, element, value) message = message(value, node)
add_offense(offense_range(node), message: message) do |corrector| add_offense(offense_range(node), message: message) do |corrector|
corrector.replace(offense_range(node), "pluck(:#{value})") corrector.replace(offense_range(node), "pluck(:#{value})")
end end
end end
end end
alias on_numblock on_block
private private
@ -47,8 +53,10 @@ module RuboCop
node.send_node.loc.selector.join(node.loc.end) node.send_node.loc.selector.join(node.loc.end)
end end
def message(method, argument, element, value) def message(value, node)
format(MSG, method: method, argument: argument, element: element, value: value) current = offense_range(node).source
format(MSG, value: value, current: current)
end end
end end
end end

Some files were not shown because too many files have changed in this diff Show More