Skip to content

Commit 166cfc6

Browse files
authored
Merge pull request #1650 from koic/lazy_load_cops
Load cops lazily
2 parents 0b20dad + 3dd6378 commit 166cfc6

11 files changed

Lines changed: 262 additions & 152 deletions

File tree

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ jobs:
8383
-e "/gem 'rubocop-performance',/d" \
8484
-e "/gem 'rubocop-rspec',/d" -i Gemfile
8585
cat << EOF > Gemfile.local
86-
gem 'rubocop', '1.75.0' # Specify the oldest supported RuboCop version
86+
gem 'rubocop', '1.89.0' # Specify the oldest supported RuboCop version
8787
EOF
8888
- uses: ruby/setup-ruby@v1
8989
with:

.rubocop.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ Naming/PredicatePrefix:
7979
Rails:
8080
Enabled: false
8181

82+
Style/Documentation:
83+
Exclude:
84+
- lib/rubocop/cop/mixin.rb
85+
- spec/support/file_helper.rb
86+
8287
Style/FormatStringToken:
8388
# Because we parse a lot of source codes from strings. Percent arrays
8489
# look like unannotated format string tokens to this cop.
@@ -112,6 +117,10 @@ Layout/ClassStructure:
112117
- protected_methods
113118
- private_methods
114119

120+
Layout/LineLength:
121+
AllowedPatterns:
122+
- !ruby/regexp /\A +register_cop :/
123+
115124
Layout/RedundantLineBreak:
116125
Enabled: true
117126

@@ -146,6 +155,8 @@ Naming/FileName:
146155
Metrics/ModuleLength:
147156
Exclude:
148157
- 'spec/**/*.rb'
158+
# The department module is a generated list of `register_cop` directives.
159+
- lib/rubocop/cop/rails.rb
149160

150161
Performance/DeletePrefix:
151162
SafeMultiline: false

Rakefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ task :new_cop, [:cop] do |_task, args|
5656

5757
generator.write_source
5858
generator.write_spec
59-
generator.inject_require(root_file_path: 'lib/rubocop/cop/rails_cops.rb')
59+
generator.inject_registration
6060
generator.inject_config(config_file_path: 'config/default.yml')
6161

6262
puts generator.todo
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* [#1650](https://github.com/rubocop/rubocop-rails/pull/1650): Speed up loading rubocop-rails by lazily loading only the cops and mixins needed for a run. This requires RuboCop 1.89.0+. ([@koic][])

lib/rubocop-rails.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
require_relative 'rubocop/rails/schema_loader'
1010
require_relative 'rubocop/rails/schema_loader/schema'
1111
require_relative 'rubocop/rails/plugin'
12-
require_relative 'rubocop/cop/rails_cops'
12+
require_relative 'rubocop/cop/rails'
1313

1414
require_relative 'rubocop/rails/migration_file_skippable'
1515

lib/rubocop/cop/mixin.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# frozen_string_literal: true
2+
3+
module RuboCop
4+
module Cop
5+
# Autoloads mixin modules included by cops. Mixins are autoloaded to reduce the number of requires
6+
# because they're used only when the relevant cop class is loaded.
7+
autoload :ActiveRecordHelper, "#{__dir__}/mixin/active_record_helper"
8+
autoload :ActiveRecordMigrationsHelper, "#{__dir__}/mixin/active_record_migrations_helper"
9+
autoload :ClassSendNodeHelper, "#{__dir__}/mixin/class_send_node_helper"
10+
autoload :DatabaseTypeResolvable, "#{__dir__}/mixin/database_type_resolvable"
11+
autoload :EnforceSuperclass, "#{__dir__}/mixin/enforce_superclass"
12+
autoload :IndexMethod, "#{__dir__}/mixin/index_method"
13+
autoload :MigrationsHelper, "#{__dir__}/mixin/migrations_helper"
14+
autoload :RoutesHelper, "#{__dir__}/mixin/routes_helper"
15+
autoload :TargetRailsVersion, "#{__dir__}/mixin/target_rails_version"
16+
end
17+
end

lib/rubocop/cop/rails.rb

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# frozen_string_literal: true
2+
3+
require_relative 'mixin'
4+
5+
module RuboCop
6+
module Cop
7+
# Cops for the `Rails` department. The department's cops are registered for lazy loading
8+
# and their files are loaded on demand.
9+
module Rails
10+
extend LazyLoader
11+
12+
register_cop :ActionControllerFlashBeforeRender, "#{__dir__}/rails/action_controller_flash_before_render"
13+
register_cop :StrongParametersExpect, "#{__dir__}/rails/strong_parameters_expect"
14+
register_cop :ActionControllerTestCase, "#{__dir__}/rails/action_controller_test_case"
15+
register_cop :ActionFilter, "#{__dir__}/rails/action_filter"
16+
register_cop :ActionOrder, "#{__dir__}/rails/action_order"
17+
register_cop :ActiveRecordAliases, "#{__dir__}/rails/active_record_aliases"
18+
register_cop :ActiveRecordCallbacksOrder, "#{__dir__}/rails/active_record_callbacks_order"
19+
register_cop :ActiveRecordOverride, "#{__dir__}/rails/active_record_override"
20+
register_cop :ActiveSupportAliases, "#{__dir__}/rails/active_support_aliases"
21+
register_cop :ActiveSupportOnLoad, "#{__dir__}/rails/active_support_on_load"
22+
register_cop :AddColumnIndex, "#{__dir__}/rails/add_column_index"
23+
register_cop :AfterCommitOverride, "#{__dir__}/rails/after_commit_override"
24+
register_cop :ApplicationController, "#{__dir__}/rails/application_controller"
25+
register_cop :ApplicationJob, "#{__dir__}/rails/application_job"
26+
register_cop :ApplicationMailer, "#{__dir__}/rails/application_mailer"
27+
register_cop :ApplicationRecord, "#{__dir__}/rails/application_record"
28+
register_cop :ArelStar, "#{__dir__}/rails/arel_star"
29+
register_cop :AssertNot, "#{__dir__}/rails/assert_not"
30+
register_cop :AttributeDefaultBlockValue, "#{__dir__}/rails/attribute_default_block_value"
31+
register_cop :BelongsTo, "#{__dir__}/rails/belongs_to"
32+
register_cop :Blank, "#{__dir__}/rails/blank"
33+
register_cop :BulkChangeTable, "#{__dir__}/rails/bulk_change_table"
34+
register_cop :CompactBlank, "#{__dir__}/rails/compact_blank"
35+
register_cop :ContentTag, "#{__dir__}/rails/content_tag"
36+
register_cop :CreateTableWithTimestamps, "#{__dir__}/rails/create_table_with_timestamps"
37+
register_cop :DangerousColumnNames, "#{__dir__}/rails/dangerous_column_names"
38+
register_cop :Date, "#{__dir__}/rails/date"
39+
register_cop :DefaultScope, "#{__dir__}/rails/default_scope"
40+
register_cop :Delegate, "#{__dir__}/rails/delegate"
41+
register_cop :DelegateAllowBlank, "#{__dir__}/rails/delegate_allow_blank"
42+
register_cop :DeprecatedActiveModelErrorsMethods, "#{__dir__}/rails/deprecated_active_model_errors_methods"
43+
register_cop :DotSeparatedKeys, "#{__dir__}/rails/dot_separated_keys"
44+
register_cop :DuplicateAssociation, "#{__dir__}/rails/duplicate_association"
45+
register_cop :DuplicateScope, "#{__dir__}/rails/duplicate_scope"
46+
register_cop :DurationArithmetic, "#{__dir__}/rails/duration_arithmetic"
47+
register_cop :DynamicFindBy, "#{__dir__}/rails/dynamic_find_by"
48+
register_cop :EagerEvaluationLogMessage, "#{__dir__}/rails/eager_evaluation_log_message"
49+
register_cop :EnumHash, "#{__dir__}/rails/enum_hash"
50+
register_cop :EnumSyntax, "#{__dir__}/rails/enum_syntax"
51+
register_cop :EnumUniqueness, "#{__dir__}/rails/enum_uniqueness"
52+
register_cop :Env, "#{__dir__}/rails/env"
53+
register_cop :EnvLocal, "#{__dir__}/rails/env_local"
54+
register_cop :EnvironmentComparison, "#{__dir__}/rails/environment_comparison"
55+
register_cop :EnvironmentVariableAccess, "#{__dir__}/rails/environment_variable_access"
56+
register_cop :Exit, "#{__dir__}/rails/exit"
57+
register_cop :ExpandedDateRange, "#{__dir__}/rails/expanded_date_range"
58+
register_cop :FilePath, "#{__dir__}/rails/file_path"
59+
register_cop :FindBy, "#{__dir__}/rails/find_by"
60+
register_cop :FindById, "#{__dir__}/rails/find_by_id"
61+
register_cop :FindByOrAssignmentMemoization, "#{__dir__}/rails/find_by_or_assignment_memoization"
62+
register_cop :FindEach, "#{__dir__}/rails/find_each"
63+
register_cop :FreezeTime, "#{__dir__}/rails/freeze_time"
64+
register_cop :HasAndBelongsToMany, "#{__dir__}/rails/has_and_belongs_to_many"
65+
register_cop :HasManyOrHasOneDependent, "#{__dir__}/rails/has_many_or_has_one_dependent"
66+
register_cop :HelperInstanceVariable, "#{__dir__}/rails/helper_instance_variable"
67+
register_cop :HttpPositionalArguments, "#{__dir__}/rails/http_positional_arguments"
68+
register_cop :HttpStatus, "#{__dir__}/rails/http_status"
69+
register_cop :HttpStatusNameConsistency, "#{__dir__}/rails/http_status_name_consistency"
70+
register_cop :I18nLazyLookup, "#{__dir__}/rails/i18n_lazy_lookup"
71+
register_cop :I18nLocaleAssignment, "#{__dir__}/rails/i18n_locale_assignment"
72+
register_cop :I18nLocaleTexts, "#{__dir__}/rails/i18n_locale_texts"
73+
register_cop :IgnoredColumnsAssignment, "#{__dir__}/rails/ignored_columns_assignment"
74+
register_cop :IgnoredSkipActionFilterOption, "#{__dir__}/rails/ignored_skip_action_filter_option"
75+
register_cop :IndexBy, "#{__dir__}/rails/index_by"
76+
register_cop :IndexWith, "#{__dir__}/rails/index_with"
77+
register_cop :Inquiry, "#{__dir__}/rails/inquiry"
78+
register_cop :InverseOf, "#{__dir__}/rails/inverse_of"
79+
register_cop :LexicallyScopedActionFilter, "#{__dir__}/rails/lexically_scoped_action_filter"
80+
register_cop :LinkToBlank, "#{__dir__}/rails/link_to_blank"
81+
register_cop :MailerName, "#{__dir__}/rails/mailer_name"
82+
register_cop :MatchRoute, "#{__dir__}/rails/match_route"
83+
register_cop :MigrationClassName, "#{__dir__}/rails/migration_class_name"
84+
register_cop :MultipleRoutePaths, "#{__dir__}/rails/multiple_route_paths"
85+
register_cop :NegateInclude, "#{__dir__}/rails/negate_include"
86+
register_cop :NotNullColumn, "#{__dir__}/rails/not_null_column"
87+
register_cop :OrderArguments, "#{__dir__}/rails/order_arguments"
88+
register_cop :OrderById, "#{__dir__}/rails/order_by_id"
89+
register_cop :Output, "#{__dir__}/rails/output"
90+
register_cop :OutputSafety, "#{__dir__}/rails/output_safety"
91+
register_cop :Pick, "#{__dir__}/rails/pick"
92+
register_cop :Pluck, "#{__dir__}/rails/pluck"
93+
register_cop :PluckId, "#{__dir__}/rails/pluck_id"
94+
register_cop :PluckInWhere, "#{__dir__}/rails/pluck_in_where"
95+
register_cop :PluralizationGrammar, "#{__dir__}/rails/pluralization_grammar"
96+
register_cop :Presence, "#{__dir__}/rails/presence"
97+
register_cop :Present, "#{__dir__}/rails/present"
98+
register_cop :RakeEnvironment, "#{__dir__}/rails/rake_environment"
99+
register_cop :ReadWriteAttribute, "#{__dir__}/rails/read_write_attribute"
100+
register_cop :RedundantActiveRecordAllMethod, "#{__dir__}/rails/redundant_active_record_all_method"
101+
register_cop :RedundantAllowNil, "#{__dir__}/rails/redundant_allow_nil"
102+
register_cop :RedundantForeignKey, "#{__dir__}/rails/redundant_foreign_key"
103+
register_cop :RedundantPresenceValidationOnBelongsTo, "#{__dir__}/rails/redundant_presence_validation_on_belongs_to"
104+
register_cop :RedundantReceiverInWithOptions, "#{__dir__}/rails/redundant_receiver_in_with_options"
105+
register_cop :RedundantTravelBack, "#{__dir__}/rails/redundant_travel_back"
106+
register_cop :RedirectBackOrTo, "#{__dir__}/rails/redirect_back_or_to"
107+
register_cop :ReflectionClassName, "#{__dir__}/rails/reflection_class_name"
108+
register_cop :RefuteMethods, "#{__dir__}/rails/refute_methods"
109+
register_cop :RelativeDateConstant, "#{__dir__}/rails/relative_date_constant"
110+
register_cop :RenderInline, "#{__dir__}/rails/render_inline"
111+
register_cop :RenderPlainText, "#{__dir__}/rails/render_plain_text"
112+
register_cop :RequestReferer, "#{__dir__}/rails/request_referer"
113+
register_cop :RequireDependency, "#{__dir__}/rails/require_dependency"
114+
register_cop :ResponseParsedBody, "#{__dir__}/rails/response_parsed_body"
115+
register_cop :ReversibleMigration, "#{__dir__}/rails/reversible_migration"
116+
register_cop :ReversibleMigrationMethodDefinition, "#{__dir__}/rails/reversible_migration_method_definition"
117+
register_cop :RootJoinChain, "#{__dir__}/rails/root_join_chain"
118+
register_cop :RootPathnameMethods, "#{__dir__}/rails/root_pathname_methods"
119+
register_cop :RootPublicPath, "#{__dir__}/rails/root_public_path"
120+
register_cop :SafeNavigation, "#{__dir__}/rails/safe_navigation"
121+
register_cop :SafeNavigationWithBlank, "#{__dir__}/rails/safe_navigation_with_blank"
122+
register_cop :SaveBang, "#{__dir__}/rails/save_bang"
123+
register_cop :SchemaComment, "#{__dir__}/rails/schema_comment"
124+
register_cop :ScopeArgs, "#{__dir__}/rails/scope_args"
125+
register_cop :SelectMap, "#{__dir__}/rails/select_map"
126+
register_cop :ShortI18n, "#{__dir__}/rails/short_i18n"
127+
register_cop :SkipsModelValidations, "#{__dir__}/rails/skips_model_validations"
128+
register_cop :SquishedSQLHeredocs, "#{__dir__}/rails/squished_sql_heredocs"
129+
register_cop :StripHeredoc, "#{__dir__}/rails/strip_heredoc"
130+
register_cop :TableNameAssignment, "#{__dir__}/rails/table_name_assignment"
131+
register_cop :ThreeStateBooleanColumn, "#{__dir__}/rails/three_state_boolean_column"
132+
register_cop :TimeZone, "#{__dir__}/rails/time_zone"
133+
register_cop :TimeZoneAssignment, "#{__dir__}/rails/time_zone_assignment"
134+
register_cop :ToFormattedS, "#{__dir__}/rails/to_formatted_s"
135+
register_cop :ToSWithArgument, "#{__dir__}/rails/to_s_with_argument"
136+
register_cop :TopLevelHashWithIndifferentAccess, "#{__dir__}/rails/top_level_hash_with_indifferent_access"
137+
register_cop :TransactionExitStatement, "#{__dir__}/rails/transaction_exit_statement"
138+
register_cop :UniqBeforePluck, "#{__dir__}/rails/uniq_before_pluck"
139+
register_cop :UniqueValidationWithoutIndex, "#{__dir__}/rails/unique_validation_without_index"
140+
register_cop :UnknownEnv, "#{__dir__}/rails/unknown_env"
141+
register_cop :UnusedIgnoredColumns, "#{__dir__}/rails/unused_ignored_columns"
142+
register_cop :UnusedRenderContent, "#{__dir__}/rails/unused_render_content"
143+
register_cop :Validation, "#{__dir__}/rails/validation"
144+
register_cop :WhereEquals, "#{__dir__}/rails/where_equals"
145+
register_cop :WhereExists, "#{__dir__}/rails/where_exists"
146+
register_cop :WhereMissing, "#{__dir__}/rails/where_missing"
147+
register_cop :WhereNot, "#{__dir__}/rails/where_not"
148+
register_cop :WhereNotWithMultipleConditions, "#{__dir__}/rails/where_not_with_multiple_conditions"
149+
register_cop :WhereRange, "#{__dir__}/rails/where_range"
150+
end
151+
end
152+
end

0 commit comments

Comments
 (0)