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:
commit
fed93bb934
@ -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)
|
||||||
|
|||||||
@ -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
|
||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
@ -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
|
||||||
@ -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
|
||||||
@ -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
|
||||||
@ -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
|
||||||
@ -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) _))]
|
||||||
@ -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
|
||||||
@ -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
|
||||||
@ -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
|
||||||
@ -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
|
||||||
@ -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
|
||||||
@ -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
|
||||||
@ -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
|
||||||
@ -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
Loading…
x
Reference in New Issue
Block a user