rubocop-rails 2.26.0 → 2.29.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +51 -1
  4. data/config/default.yml +30 -6
  5. data/lib/rubocop/cop/mixin/index_method.rb +12 -5
  6. data/lib/rubocop/cop/mixin/routes_helper.rb +20 -0
  7. data/lib/rubocop/cop/mixin/target_rails_version.rb +3 -5
  8. data/lib/rubocop/cop/rails/action_controller_flash_before_render.rb +5 -5
  9. data/lib/rubocop/cop/rails/action_order.rb +1 -5
  10. data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +1 -5
  11. data/lib/rubocop/cop/rails/add_column_index.rb +1 -0
  12. data/lib/rubocop/cop/rails/application_record.rb +4 -0
  13. data/lib/rubocop/cop/rails/bulk_change_table.rb +1 -0
  14. data/lib/rubocop/cop/rails/compact_blank.rb +8 -4
  15. data/lib/rubocop/cop/rails/dangerous_column_names.rb +2 -0
  16. data/lib/rubocop/cop/rails/duplicate_association.rb +8 -4
  17. data/lib/rubocop/cop/rails/enum_syntax.rb +18 -14
  18. data/lib/rubocop/cop/rails/env_local.rb +26 -3
  19. data/lib/rubocop/cop/rails/file_path.rb +26 -3
  20. data/lib/rubocop/cop/rails/http_positional_arguments.rb +7 -0
  21. data/lib/rubocop/cop/rails/index_by.rb +28 -12
  22. data/lib/rubocop/cop/rails/index_with.rb +28 -12
  23. data/lib/rubocop/cop/rails/match_route.rb +1 -9
  24. data/lib/rubocop/cop/rails/multiple_route_paths.rb +50 -0
  25. data/lib/rubocop/cop/rails/not_null_column.rb +6 -2
  26. data/lib/rubocop/cop/rails/pluck.rb +20 -0
  27. data/lib/rubocop/cop/rails/pluralization_grammar.rb +1 -1
  28. data/lib/rubocop/cop/rails/present.rb +0 -2
  29. data/lib/rubocop/cop/rails/redundant_active_record_all_method.rb +1 -30
  30. data/lib/rubocop/cop/rails/redundant_foreign_key.rb +1 -1
  31. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +1 -1
  32. data/lib/rubocop/cop/rails/reflection_class_name.rb +1 -1
  33. data/lib/rubocop/cop/rails/request_referer.rb +1 -1
  34. data/lib/rubocop/cop/rails/reversible_migration.rb +3 -1
  35. data/lib/rubocop/cop/rails/root_pathname_methods.rb +17 -8
  36. data/lib/rubocop/cop/rails/save_bang.rb +4 -3
  37. data/lib/rubocop/cop/rails/schema_comment.rb +1 -0
  38. data/lib/rubocop/cop/rails/select_map.rb +3 -2
  39. data/lib/rubocop/cop/rails/skips_model_validations.rb +4 -2
  40. data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +1 -1
  41. data/lib/rubocop/cop/rails/strong_parameters_expect.rb +104 -0
  42. data/lib/rubocop/cop/rails/three_state_boolean_column.rb +2 -1
  43. data/lib/rubocop/cop/rails/time_zone.rb +13 -6
  44. data/lib/rubocop/cop/rails/transaction_exit_statement.rb +5 -0
  45. data/lib/rubocop/cop/rails/where_equals.rb +6 -1
  46. data/lib/rubocop/cop/rails/where_not.rb +6 -1
  47. data/lib/rubocop/cop/rails/where_range.rb +7 -2
  48. data/lib/rubocop/cop/rails_cops.rb +3 -0
  49. data/lib/rubocop/rails/migration_file_skippable.rb +54 -0
  50. data/lib/rubocop/rails/version.rb +1 -1
  51. data/lib/rubocop/rails.rb +0 -1
  52. data/lib/rubocop-rails.rb +3 -0
  53. metadata +8 -7
@@ -28,6 +28,8 @@ module RuboCop
28
28
  # Time.zone.now
29
29
  # Time.zone.parse('2015-03-02T19:05:37')
30
30
  # Time.zone.parse('2015-03-02T19:05:37Z') # Respect ISO 8601 format with timezone specifier.
31
+ # Time.parse('2015-03-02T19:05:37Z') # Also respects ISO 8601
32
+ # '2015-03-02T19:05:37Z'.to_time # Also respects ISO 8601
31
33
  #
32
34
  # @example EnforcedStyle: flexible (default)
33
35
  # # `flexible` allows usage of `in_time_zone` instead of `zone`.
@@ -67,6 +69,7 @@ module RuboCop
67
69
 
68
70
  def on_send(node)
69
71
  return if !node.receiver&.str_type? || !node.method?(:to_time)
72
+ return if attach_timezone_specifier?(node.receiver)
70
73
 
71
74
  add_offense(node.loc.selector, message: MSG_STRING_TO_TIME) do |corrector|
72
75
  corrector.replace(node, "Time.zone.parse(#{node.receiver.source})") unless node.csend_type?
@@ -94,11 +97,9 @@ module RuboCop
94
97
  end
95
98
 
96
99
  def autocorrect_time_new(node, corrector)
97
- if node.arguments?
98
- corrector.replace(node.loc.selector, 'local')
99
- else
100
- corrector.replace(node.loc.selector, 'now')
101
- end
100
+ replacement = replacement(node)
101
+
102
+ corrector.replace(node.loc.selector, replacement)
102
103
  end
103
104
 
104
105
  # remove redundant `.in_time_zone` from `Time.zone.now.in_time_zone`
@@ -180,7 +181,7 @@ module RuboCop
180
181
 
181
182
  def safe_method(method_name, node)
182
183
  if %w[new current].include?(method_name)
183
- node.arguments? ? 'local' : 'now'
184
+ replacement(node)
184
185
  else
185
186
  method_name
186
187
  end
@@ -256,6 +257,12 @@ module RuboCop
256
257
  pair.key.sym_type? && pair.key.value == :in && !pair.value.nil_type?
257
258
  end
258
259
  end
260
+
261
+ def replacement(node)
262
+ return 'now' unless node.arguments?
263
+
264
+ node.first_argument.str_type? ? 'parse' : 'local'
265
+ end
259
266
  end
260
267
  end
261
268
  end
@@ -15,6 +15,10 @@ module RuboCop
15
15
  #
16
16
  # If you are defining custom transaction methods, you can configure it with `TransactionMethods`.
17
17
  #
18
+ # NOTE: This cop is disabled on Rails >= 7.2 because transactions were restored
19
+ # to their historical behavior. In Rails 7.1, the behavior is controlled with
20
+ # the config `active_record.commit_transaction_on_non_local_return`.
21
+ #
18
22
  # @example
19
23
  # # bad
20
24
  # ApplicationRecord.transaction do
@@ -76,6 +80,7 @@ module RuboCop
76
80
  PATTERN
77
81
 
78
82
  def on_send(node)
83
+ return if target_rails_version >= 7.2
79
84
  return unless in_transaction_block?(node)
80
85
 
81
86
  exit_statements(node.parent.body).each do |statement_node|
@@ -74,6 +74,7 @@ module RuboCop
74
74
  range_between(node.loc.selector.begin_pos, node.source_range.end_pos)
75
75
  end
76
76
 
77
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
77
78
  def extract_column_and_value(template_node, value_node)
78
79
  value =
79
80
  case template_node.value
@@ -90,8 +91,12 @@ module RuboCop
90
91
  return
91
92
  end
92
93
 
93
- [Regexp.last_match(1), value]
94
+ column_qualifier = Regexp.last_match(1)
95
+ return if column_qualifier.count('.') > 1
96
+
97
+ [column_qualifier, value]
94
98
  end
99
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
95
100
 
96
101
  def build_good_method(method_name, column, value)
97
102
  if column.include?('.')
@@ -68,6 +68,7 @@ module RuboCop
68
68
  range_between(node.loc.selector.begin_pos, node.source_range.end_pos)
69
69
  end
70
70
 
71
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
71
72
  def extract_column_and_value(template_node, value_node)
72
73
  value =
73
74
  case template_node.value
@@ -84,8 +85,12 @@ module RuboCop
84
85
  return
85
86
  end
86
87
 
87
- [Regexp.last_match(1), value]
88
+ column_qualifier = Regexp.last_match(1)
89
+ return if column_qualifier.count('.') > 1
90
+
91
+ [column_qualifier, value]
88
92
  end
93
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
89
94
 
90
95
  def build_good_method(dot, column, value)
91
96
  dot ||= '.'
@@ -89,7 +89,7 @@ module RuboCop
89
89
 
90
90
  def where_not?(node)
91
91
  receiver = node.receiver
92
- receiver&.send_type? && receiver&.method?(:where)
92
+ receiver&.send_type? && receiver.method?(:where)
93
93
  end
94
94
 
95
95
  # rubocop:disable Metrics
@@ -140,6 +140,8 @@ module RuboCop
140
140
  rhs = pair2.value
141
141
  end
142
142
  end
143
+ else
144
+ return
143
145
  end
144
146
 
145
147
  if lhs
@@ -150,7 +152,10 @@ module RuboCop
150
152
  rhs_source = parentheses_needed?(rhs) ? "(#{rhs.source})" : rhs.source
151
153
  end
152
154
 
153
- [Regexp.last_match(1), "#{lhs_source}#{operator}#{rhs_source}"] if operator
155
+ column_qualifier = Regexp.last_match(1)
156
+ return if column_qualifier.count('.') > 1
157
+
158
+ [column_qualifier, "#{lhs_source}#{operator}#{rhs_source}"] if operator
154
159
  end
155
160
  # rubocop:enable Metrics
156
161
 
@@ -7,9 +7,11 @@ require_relative 'mixin/database_type_resolvable'
7
7
  require_relative 'mixin/enforce_superclass'
8
8
  require_relative 'mixin/index_method'
9
9
  require_relative 'mixin/migrations_helper'
10
+ require_relative 'mixin/routes_helper'
10
11
  require_relative 'mixin/target_rails_version'
11
12
 
12
13
  require_relative 'rails/action_controller_flash_before_render'
14
+ require_relative 'rails/strong_parameters_expect'
13
15
  require_relative 'rails/action_controller_test_case'
14
16
  require_relative 'rails/action_filter'
15
17
  require_relative 'rails/action_order'
@@ -77,6 +79,7 @@ require_relative 'rails/link_to_blank'
77
79
  require_relative 'rails/mailer_name'
78
80
  require_relative 'rails/match_route'
79
81
  require_relative 'rails/migration_class_name'
82
+ require_relative 'rails/multiple_route_paths'
80
83
  require_relative 'rails/negate_include'
81
84
  require_relative 'rails/not_null_column'
82
85
  require_relative 'rails/order_by_id'
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Rails
5
+ # This module allows cops to detect and ignore files that have already been migrated
6
+ # by leveraging the `AllCops: MigratedSchemaVersion` configuration.
7
+ #
8
+ # [source,yaml]
9
+ # -----
10
+ # AllCops:
11
+ # MigratedSchemaVersion: '20241225000000'
12
+ # -----
13
+ #
14
+ # When applied to cops, it overrides the `add_global_offense` and `add_offense` methods,
15
+ # ensuring that cops skip processing if the file is determined to be a migrated file
16
+ # based on the schema version.
17
+ #
18
+ # @api private
19
+ module MigrationFileSkippable
20
+ def add_global_offense(message = nil, severity: nil)
21
+ return if already_migrated_file?
22
+
23
+ super if method(__method__).super_method
24
+ end
25
+
26
+ def add_offense(node_or_range, message: nil, severity: nil, &block)
27
+ return if already_migrated_file?
28
+
29
+ super if method(__method__).super_method
30
+ end
31
+
32
+ def self.apply_to_cops!
33
+ RuboCop::Cop::Registry.all.each { |cop| cop.prepend(MigrationFileSkippable) }
34
+ end
35
+
36
+ private
37
+
38
+ def already_migrated_file?
39
+ return false unless migrated_schema_version
40
+
41
+ match_data = File.basename(processed_source.file_path).match(/(?<timestamp>\d{14})/)
42
+ schema_version = match_data['timestamp'] if match_data
43
+
44
+ return false unless schema_version
45
+
46
+ schema_version <= migrated_schema_version.to_s # Ignore applied migration files.
47
+ end
48
+
49
+ def migrated_schema_version
50
+ @migrated_schema_version ||= config.for_all_cops.fetch('MigratedSchemaVersion', nil)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Rails
5
5
  # This module holds the RuboCop Rails version information.
6
6
  module Version
7
- STRING = '2.26.0'
7
+ STRING = '2.29.1'
8
8
 
9
9
  def self.document_version
10
10
  STRING.match('\d+\.\d+').to_s
data/lib/rubocop/rails.rb CHANGED
@@ -5,7 +5,6 @@ module RuboCop
5
5
  module Rails
6
6
  PROJECT_ROOT = Pathname.new(__dir__).parent.parent.expand_path.freeze
7
7
  CONFIG_DEFAULT = PROJECT_ROOT.join('config', 'default.yml').freeze
8
- CONFIG = YAML.safe_load(CONFIG_DEFAULT.read, permitted_classes: [Regexp, Symbol]).freeze
9
8
 
10
9
  private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
11
10
 
data/lib/rubocop-rails.rb CHANGED
@@ -15,6 +15,9 @@ RuboCop::Rails::Inject.defaults!
15
15
 
16
16
  require_relative 'rubocop/cop/rails_cops'
17
17
 
18
+ require_relative 'rubocop/rails/migration_file_skippable'
19
+ RuboCop::Rails::MigrationFileSkippable.apply_to_cops!
20
+
18
21
  RuboCop::Cop::Style::HashExcept.minimum_target_ruby_version(2.0)
19
22
 
20
23
  RuboCop::Cop::Style::InverseMethods.singleton_class.prepend(
metadata CHANGED
@@ -1,16 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.26.0
4
+ version: 2.29.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
8
8
  - Jonas Arvidsson
9
9
  - Yuji Nakayama
10
- autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2024-08-24 00:00:00.000000000 Z
12
+ date: 2025-01-25 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: activesupport
@@ -102,6 +101,7 @@ files:
102
101
  - lib/rubocop/cop/mixin/enforce_superclass.rb
103
102
  - lib/rubocop/cop/mixin/index_method.rb
104
103
  - lib/rubocop/cop/mixin/migrations_helper.rb
104
+ - lib/rubocop/cop/mixin/routes_helper.rb
105
105
  - lib/rubocop/cop/mixin/target_rails_version.rb
106
106
  - lib/rubocop/cop/rails/action_controller_flash_before_render.rb
107
107
  - lib/rubocop/cop/rails/action_controller_test_case.rb
@@ -171,6 +171,7 @@ files:
171
171
  - lib/rubocop/cop/rails/mailer_name.rb
172
172
  - lib/rubocop/cop/rails/match_route.rb
173
173
  - lib/rubocop/cop/rails/migration_class_name.rb
174
+ - lib/rubocop/cop/rails/multiple_route_paths.rb
174
175
  - lib/rubocop/cop/rails/negate_include.rb
175
176
  - lib/rubocop/cop/rails/not_null_column.rb
176
177
  - lib/rubocop/cop/rails/order_by_id.rb
@@ -214,6 +215,7 @@ files:
214
215
  - lib/rubocop/cop/rails/skips_model_validations.rb
215
216
  - lib/rubocop/cop/rails/squished_sql_heredocs.rb
216
217
  - lib/rubocop/cop/rails/strip_heredoc.rb
218
+ - lib/rubocop/cop/rails/strong_parameters_expect.rb
217
219
  - lib/rubocop/cop/rails/table_name_assignment.rb
218
220
  - lib/rubocop/cop/rails/three_state_boolean_column.rb
219
221
  - lib/rubocop/cop/rails/time_zone.rb
@@ -237,6 +239,7 @@ files:
237
239
  - lib/rubocop/cop/rails_cops.rb
238
240
  - lib/rubocop/rails.rb
239
241
  - lib/rubocop/rails/inject.rb
242
+ - lib/rubocop/rails/migration_file_skippable.rb
240
243
  - lib/rubocop/rails/schema_loader.rb
241
244
  - lib/rubocop/rails/schema_loader/schema.rb
242
245
  - lib/rubocop/rails/version.rb
@@ -247,10 +250,9 @@ metadata:
247
250
  homepage_uri: https://docs.rubocop.org/rubocop-rails/
248
251
  changelog_uri: https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md
249
252
  source_code_uri: https://github.com/rubocop/rubocop-rails/
250
- documentation_uri: https://docs.rubocop.org/rubocop-rails/2.26/
253
+ documentation_uri: https://docs.rubocop.org/rubocop-rails/2.29/
251
254
  bug_tracker_uri: https://github.com/rubocop/rubocop-rails/issues
252
255
  rubygems_mfa_required: 'true'
253
- post_install_message:
254
256
  rdoc_options: []
255
257
  require_paths:
256
258
  - lib
@@ -265,8 +267,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
265
267
  - !ruby/object:Gem::Version
266
268
  version: '0'
267
269
  requirements: []
268
- rubygems_version: 3.5.11
269
- signing_key:
270
+ rubygems_version: 3.6.2
270
271
  specification_version: 4
271
272
  summary: Automatic Rails code style checking tool.
272
273
  test_files: []