rubocop-rails 2.25.0 → 2.25.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cad5e6d0c6f188b6ff87adb04fbfb73c7c574b901de45256eb7fa6e50b7a136d
4
- data.tar.gz: c8ab8f1d1c3284054af5847231dd996df24ee5441f638f95bc7e32420a3baf04
3
+ metadata.gz: b55703b258e4df9bae3a9a8c1b77a4fa143af6af3ed9b1b22118fd839d1ce06c
4
+ data.tar.gz: 24568d7d8d22d69469ae9a4aaf426ea45bf848989604a8744ab6493bc0b222a3
5
5
  SHA512:
6
- metadata.gz: ea0ebe45e988d115aa45d7bdba2b728b0583e1e2d996d43af424eb8abc17ced35b528741fcc47b8b258de52edd2fb7bc1c92dd609b49ddeeaaaf26bce123e783
7
- data.tar.gz: 7eb06cfce19f2a4ba78c6d571c65cf386e211b48ca2c9b5b9ca436ec9055e49f9737cbb3f9ce1b44ab432de87121295439effc59f093446cea88199bd08ba8a4
6
+ metadata.gz: 47d5668b744967fc740b47552e9d05068fc5ce5c209a4a994a429262a0628b13e0f1e48d6a39018430fb7e874f88e4badbd9427219b9a77220e522d6706b1c3c
7
+ data.tar.gz: 242030d6fe9063d51f18e98869e2a048a4b7b847f0f6a25937fc3d9781dbb7749de8b015b3fa0b4933511b83487ad060fbdbf9adb7942a20bfc035d5fc9e2f04
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # RuboCop Rails
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/rubocop-rails.svg)](https://badge.fury.io/rb/rubocop-rails)
4
- [![CircleCI](https://circleci.com/gh/rubocop/rubocop-rails.svg?style=svg)](https://circleci.com/gh/rubocop/rubocop-rails)
4
+ [![CI](https://github.com/rubocop/rubocop-rails/actions/workflows/test.yml/badge.svg)](https://github.com/rubocop/rubocop-rails/actions/workflows/test.yml)
5
5
 
6
6
  A [RuboCop](https://github.com/rubocop/rubocop) extension focused on enforcing Rails best practices and coding conventions.
7
7
 
data/config/default.yml CHANGED
@@ -1018,8 +1018,9 @@ Rails/SkipsModelValidations:
1018
1018
  See reference for more information.
1019
1019
  Reference: 'https://guides.rubyonrails.org/active_record_validations.html#skipping-validations'
1020
1020
  Enabled: true
1021
+ Safe: false
1021
1022
  VersionAdded: '0.47'
1022
- VersionChanged: '2.7'
1023
+ VersionChanged: '2.25'
1023
1024
  ForbiddenMethods:
1024
1025
  - decrement!
1025
1026
  - decrement_counter
@@ -1226,6 +1227,7 @@ Rails/WhereRange:
1226
1227
  Description: 'Use ranges in `where` instead of manually constructing SQL.'
1227
1228
  StyleGuide: 'https://rails.rubystyle.guide/#where-ranges'
1228
1229
  Enabled: pending
1230
+ SafeAutoCorrect: false
1229
1231
  VersionAdded: '2.25'
1230
1232
 
1231
1233
  # Accept `redirect_to(...) and return` and similar cases.
@@ -113,8 +113,10 @@ module RuboCop
113
113
  MYSQL_COMBINABLE_ALTER_METHODS = %i[rename_column add_index remove_index].freeze
114
114
 
115
115
  POSTGRESQL_COMBINABLE_TRANSFORMATIONS = %i[change_default].freeze
116
+ POSTGRESQL_COMBINABLE_TRANSFORMATIONS_SINCE_6_1 = %i[change_null].freeze
116
117
 
117
118
  POSTGRESQL_COMBINABLE_ALTER_METHODS = %i[change_column_default].freeze
119
+ POSTGRESQL_COMBINABLE_ALTER_METHODS_SINCE_6_1 = %i[change_column_null].freeze
118
120
 
119
121
  def on_def(node)
120
122
  return unless support_bulk_alter?
@@ -196,7 +198,9 @@ module RuboCop
196
198
  when MYSQL
197
199
  COMBINABLE_ALTER_METHODS + MYSQL_COMBINABLE_ALTER_METHODS
198
200
  when POSTGRESQL
199
- COMBINABLE_ALTER_METHODS + POSTGRESQL_COMBINABLE_ALTER_METHODS
201
+ result = COMBINABLE_ALTER_METHODS + POSTGRESQL_COMBINABLE_ALTER_METHODS
202
+ result += POSTGRESQL_COMBINABLE_ALTER_METHODS_SINCE_6_1 if target_rails_version >= 6.1
203
+ result
200
204
  end
201
205
  end
202
206
 
@@ -205,7 +209,9 @@ module RuboCop
205
209
  when MYSQL
206
210
  COMBINABLE_TRANSFORMATIONS + MYSQL_COMBINABLE_TRANSFORMATIONS
207
211
  when POSTGRESQL
208
- COMBINABLE_TRANSFORMATIONS + POSTGRESQL_COMBINABLE_TRANSFORMATIONS
212
+ result = COMBINABLE_TRANSFORMATIONS + POSTGRESQL_COMBINABLE_TRANSFORMATIONS
213
+ result += POSTGRESQL_COMBINABLE_TRANSFORMATIONS_SINCE_6_1 if target_rails_version >= 6.1
214
+ result
209
215
  end
210
216
  end
211
217
 
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Rails
6
- # Checks for calls to `link_to` that contain a
6
+ # Checks for calls to `link_to`, `link_to_if`, and `link_to_unless` methods that contain a
7
7
  # `target: '_blank'` but no `rel: 'noopener'`. This can be a security
8
8
  # risk as the loaded page will have control over the previous page
9
9
  # and could change its location for phishing purposes.
@@ -24,7 +24,7 @@ module RuboCop
24
24
  extend AutoCorrector
25
25
 
26
26
  MSG = 'Specify a `:rel` option containing noopener.'
27
- RESTRICT_ON_SEND = %i[link_to].freeze
27
+ RESTRICT_ON_SEND = %i[link_to link_to_if link_to_unless].freeze
28
28
 
29
29
  def_node_matcher :blank_target?, <<~PATTERN
30
30
  (pair {(sym :target) (str "target")} {(str "_blank") (sym :_blank)})
@@ -136,6 +136,8 @@ module RuboCop
136
136
 
137
137
  def check_change_table(node)
138
138
  change_table?(node) do |table|
139
+ next unless node.body
140
+
139
141
  children = node.body.begin_type? ? node.body.children : [node.body]
140
142
  children.each do |child|
141
143
  check_add_column_in_change_table(child, table)
@@ -9,6 +9,9 @@ module RuboCop
9
9
  #
10
10
  # Methods may be ignored from this rule by configuring a `AllowedMethods`.
11
11
  #
12
+ # @safety
13
+ # This cop is unsafe if the receiver object is not an Active Record object.
14
+ #
12
15
  # @example
13
16
  # # bad
14
17
  # Article.first.decrement!(:view_count)
@@ -8,6 +8,7 @@ module RuboCop
8
8
  # @example
9
9
  # # bad
10
10
  # validates_acceptance_of :foo
11
+ # validates_comparison_of :foo
11
12
  # validates_confirmation_of :foo
12
13
  # validates_exclusion_of :foo
13
14
  # validates_format_of :foo
@@ -22,6 +23,7 @@ module RuboCop
22
23
  # # good
23
24
  # validates :foo, acceptance: true
24
25
  # validates :foo, confirmation: true
26
+ # validates :foo, comparison: true
25
27
  # validates :foo, exclusion: true
26
28
  # validates :foo, format: true
27
29
  # validates :foo, inclusion: true
@@ -39,6 +41,7 @@ module RuboCop
39
41
 
40
42
  TYPES = %w[
41
43
  acceptance
44
+ comparison
42
45
  confirmation
43
46
  exclusion
44
47
  format
@@ -6,6 +6,14 @@ module RuboCop
6
6
  # Identifies places where manually constructed SQL
7
7
  # in `where` can be replaced with ranges.
8
8
  #
9
+ # @safety
10
+ # This cop's autocorrection is unsafe because it can change the query
11
+ # by explicitly attaching the column to the wrong table.
12
+ # For example, `Booking.joins(:events).where('end_at < ?', Time.current)` will correctly
13
+ # implicitly attach the `end_at` column to the `events` table. But when autocorrected to
14
+ # `Booking.joins(:events).where(end_at: ...Time.current)`, it will now be incorrectly
15
+ # explicitly attached to the `bookings` table.
16
+ #
9
17
  # @example
10
18
  # # bad
11
19
  # User.where('age >= ?', 18)
@@ -37,17 +45,17 @@ module RuboCop
37
45
  RESTRICT_ON_SEND = %i[where not].freeze
38
46
 
39
47
  # column >= ?
40
- GTEQ_ANONYMOUS_RE = /\A([\w.]+)\s+>=\s+\?\z/.freeze
48
+ GTEQ_ANONYMOUS_RE = /\A\s*([\w.]+)\s+>=\s+\?\s*\z/.freeze
41
49
  # column <[=] ?
42
- LTEQ_ANONYMOUS_RE = /\A([\w.]+)\s+(<=?)\s+\?\z/.freeze
50
+ LTEQ_ANONYMOUS_RE = /\A\s*([\w.]+)\s+(<=?)\s+\?\s*\z/.freeze
43
51
  # column >= ? AND column <[=] ?
44
- RANGE_ANONYMOUS_RE = /\A([\w.]+)\s+>=\s+\?\s+AND\s+\1\s+(<=?)\s+\?\z/i.freeze
52
+ RANGE_ANONYMOUS_RE = /\A\s*([\w.]+)\s+>=\s+\?\s+AND\s+\1\s+(<=?)\s+\?\s*\z/i.freeze
45
53
  # column >= :value
46
- GTEQ_NAMED_RE = /\A([\w.]+)\s+>=\s+:(\w+)\z/.freeze
54
+ GTEQ_NAMED_RE = /\A\s*([\w.]+)\s+>=\s+:(\w+)\s*\z/.freeze
47
55
  # column <[=] :value
48
- LTEQ_NAMED_RE = /\A([\w.]+)\s+(<=?)\s+:(\w+)\z/.freeze
56
+ LTEQ_NAMED_RE = /\A\s*([\w.]+)\s+(<=?)\s+:(\w+)\s*\z/.freeze
49
57
  # column >= :value1 AND column <[=] :value2
50
- RANGE_NAMED_RE = /\A([\w.]+)\s+>=\s+:(\w+)\s+AND\s+\1\s+(<=?)\s+:(\w+)\z/i.freeze
58
+ RANGE_NAMED_RE = /\A\s*([\w.]+)\s+>=\s+:(\w+)\s+AND\s+\1\s+(<=?)\s+:(\w+)\s*\z/i.freeze
51
59
 
52
60
  minimum_target_ruby_version 2.6
53
61
  minimum_target_rails_version 6.0
@@ -86,47 +94,63 @@ module RuboCop
86
94
 
87
95
  # rubocop:disable Metrics
88
96
  def extract_column_and_value(template_node, values_node)
89
- value =
90
- case template_node.value
91
- when GTEQ_ANONYMOUS_RE
92
- "#{values_node[0].source}.."
93
- when LTEQ_ANONYMOUS_RE
94
- range_operator = range_operator(Regexp.last_match(2))
95
- "#{range_operator}#{values_node[0].source}" if target_ruby_version >= 2.7
96
- when RANGE_ANONYMOUS_RE
97
- if values_node.size >= 2
98
- range_operator = range_operator(Regexp.last_match(2))
99
- "#{values_node[0].source}#{range_operator}#{values_node[1].source}"
100
- end
101
- when GTEQ_NAMED_RE
102
- value_node = values_node[0]
97
+ case template_node.value
98
+ when GTEQ_ANONYMOUS_RE
99
+ lhs = values_node[0]
100
+ operator = '..'
101
+ when LTEQ_ANONYMOUS_RE
102
+ if target_ruby_version >= 2.7
103
+ operator = range_operator(Regexp.last_match(2))
104
+ rhs = values_node[0]
105
+ end
106
+ when RANGE_ANONYMOUS_RE
107
+ if values_node.size >= 2
108
+ lhs = values_node[0]
109
+ operator = range_operator(Regexp.last_match(2))
110
+ rhs = values_node[1]
111
+ end
112
+ when GTEQ_NAMED_RE
113
+ value_node = values_node[0]
103
114
 
104
- if value_node.hash_type?
105
- pair = find_pair(value_node, Regexp.last_match(2))
106
- "#{pair.value.source}.." if pair
107
- end
108
- when LTEQ_NAMED_RE
109
- value_node = values_node[0]
110
-
111
- if value_node.hash_type?
112
- pair = find_pair(value_node, Regexp.last_match(2))
113
- if pair && target_ruby_version >= 2.7
114
- range_operator = range_operator(Regexp.last_match(2))
115
- "#{range_operator}#{pair.value.source}"
116
- end
115
+ if value_node.hash_type?
116
+ pair = find_pair(value_node, Regexp.last_match(2))
117
+ lhs = pair.value
118
+ operator = '..'
119
+ end
120
+ when LTEQ_NAMED_RE
121
+ value_node = values_node[0]
122
+
123
+ if value_node.hash_type?
124
+ pair = find_pair(value_node, Regexp.last_match(2))
125
+ if pair && target_ruby_version >= 2.7
126
+ operator = range_operator(Regexp.last_match(2))
127
+ rhs = pair.value
117
128
  end
118
- when RANGE_NAMED_RE
119
- value_node = values_node[0]
120
-
121
- if value_node.hash_type?
122
- range_operator = range_operator(Regexp.last_match(3))
123
- pair1 = find_pair(value_node, Regexp.last_match(2))
124
- pair2 = find_pair(value_node, Regexp.last_match(4))
125
- "#{pair1.value.source}#{range_operator}#{pair2.value.source}" if pair1 && pair2
129
+ end
130
+ when RANGE_NAMED_RE
131
+ value_node = values_node[0]
132
+
133
+ if value_node.hash_type?
134
+ pair1 = find_pair(value_node, Regexp.last_match(2))
135
+ pair2 = find_pair(value_node, Regexp.last_match(4))
136
+
137
+ if pair1 && pair2
138
+ lhs = pair1.value
139
+ operator = range_operator(Regexp.last_match(3))
140
+ rhs = pair2.value
126
141
  end
127
142
  end
143
+ end
128
144
 
129
- [Regexp.last_match(1), value] if value
145
+ if lhs
146
+ lhs_source = parentheses_needed?(lhs) ? "(#{lhs.source})" : lhs.source
147
+ end
148
+
149
+ if rhs
150
+ rhs_source = parentheses_needed?(rhs) ? "(#{rhs.source})" : rhs.source
151
+ end
152
+
153
+ [Regexp.last_match(1), "#{lhs_source}#{operator}#{rhs_source}"] if operator
130
154
  end
131
155
  # rubocop:enable Metrics
132
156
 
@@ -151,6 +175,23 @@ module RuboCop
151
175
  "#{method_name}(#{column}: #{value})"
152
176
  end
153
177
  end
178
+
179
+ def parentheses_needed?(node)
180
+ !parentheses_not_needed?(node)
181
+ end
182
+
183
+ def parentheses_not_needed?(node)
184
+ node.variable? ||
185
+ node.literal? ||
186
+ node.reference? ||
187
+ node.const_type? ||
188
+ node.begin_type? ||
189
+ parenthesized_call_node?(node)
190
+ end
191
+
192
+ def parenthesized_call_node?(node)
193
+ node.call_type? && (node.arguments.empty? || node.parenthesized_call?)
194
+ end
154
195
  end
155
196
  end
156
197
  end
@@ -178,7 +178,7 @@ module RuboCop
178
178
  attr_reader :table_name
179
179
 
180
180
  def initialize(node)
181
- super(node)
181
+ super
182
182
 
183
183
  @table_name = node.first_argument.value
184
184
  @columns, @expression = build_columns_or_expr(node.arguments[1])
@@ -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.25.0'
7
+ STRING = '2.25.1'
8
8
 
9
9
  def self.document_version
10
10
  STRING.match('\d+\.\d+').to_s
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.25.0
4
+ version: 2.25.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-05-17 00:00:00.000000000 Z
13
+ date: 2024-06-29 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -264,7 +264,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
264
264
  - !ruby/object:Gem::Version
265
265
  version: '0'
266
266
  requirements: []
267
- rubygems_version: 3.5.3
267
+ rubygems_version: 3.5.11
268
268
  signing_key:
269
269
  specification_version: 4
270
270
  summary: Automatic Rails code style checking tool.