runger_style 5.17.0 → 5.19.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eb6defe797f70ab9b1335060521e1f49e4cf509c30ac7bf3139e04a0a3e8cae5
4
- data.tar.gz: 95c757a383b153f087aaff78b4514043a9029b491e2fec26942991fb318d8331
3
+ metadata.gz: 5d0866b9fa941c5b96a5732b330129509a16efc47fe6a1799dd9411caa08f643
4
+ data.tar.gz: ad6473ae391654855f60734076e007984434d699e72adf3f66b3db5adb2b3037
5
5
  SHA512:
6
- metadata.gz: 04c29fd64211c7dca6756bfe470a6ce0b0fd5d3f584f0ed437d3410771cd16e1f5f8bf25804d9c1483af833065e2290ff04d185071832be10c0efaf174dad972
7
- data.tar.gz: cc4ed34f1d5a1366305c9e3b8018dd109e3f80d556980db9c10721fbea985e47d5b47ebb2d1576b53d2c113089a579ab58b95f219f9dc151d43ece979986886d
6
+ metadata.gz: 2cbd10d7aa282b5eae4f653c413ecaf32e76fbd385f9e4bf35a432ce7b53faea090ba37857bb1568e3351a55caefadc44397db8ff4bec61f4585f45c466a5873
7
+ data.tar.gz: f3e56148b897dce81b3505d46b26b064092157e95be434a8e8d50fe41222580083a2932ba9df2c51f48fdcfb787c186372f3968a3ce1d2bf114b093e26265d64
data/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
1
  ## Unreleased
2
2
  [no unreleased changes yet]
3
3
 
4
+ ## v5.19.0 (2026-08-23)
5
+ - Remove eight methods from `Style/MethodCallWithArgsParentheses` allowlist.
6
+ - Remove five methods from `Style/MethodCallWithArgsParentheses` allowlist.
7
+
8
+ ## v5.18.0 (2026-08-22)
9
+ - [default] Add `RungerStyle/ParenthesesAroundMultilineCondition` to require parentheses around multiline `if`, `unless`, and `elsif` conditions, except for multiline block conditions and parenthesized receivers.
10
+
4
11
  ## v5.17.0 (2026-08-21)
5
12
  - [default] Add report-only `RungerStyle/NoReturn` to forbid explicit `return` statements.
6
13
 
data/Gemfile.lock CHANGED
@@ -10,7 +10,7 @@ GIT
10
10
  PATH
11
11
  remote: .
12
12
  specs:
13
- runger_style (5.17.0)
13
+ runger_style (5.19.0)
14
14
  prism (>= 0.24.0)
15
15
  rubocop (>= 1.72.0)
16
16
 
@@ -235,7 +235,7 @@ CHECKSUMS
235
235
  ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
236
236
  runger_byebug (11.4.0) sha256=569e22ba2215f57e7f69e145fcb63be401e29fcd312f7936d813e12d0c7bbee6
237
237
  runger_release_assistant (4.3.1) sha256=3246c925240739eb12b9e6b9526a77ea00fcf0a0941441ff5ffacefb7e3e4d83
238
- runger_style (5.17.0)
238
+ runger_style (5.19.0)
239
239
  securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
240
240
  slop (4.10.1) sha256=844322b5ffcf17ed4815fdb173b04a20dd82b4fd93e3744c88c8fafea696d9c7
241
241
  tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f
@@ -12,9 +12,11 @@ module RungerStyle # rubocop:disable Style/ClassAndModuleChildren
12
12
  # When a method call uses keyword arguments without braces,
13
13
  # the parser produces a single hash node. In that case, inspect its pairs.
14
14
  arguments =
15
- if node.arguments.one? &&
15
+ if (
16
+ node.arguments.one? &&
16
17
  node.arguments.first.hash_type? &&
17
18
  !node.arguments.first.braces?
19
+ )
18
20
  node.arguments.first.pairs
19
21
  else
20
22
  node.arguments
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RungerStyle # rubocop:disable Style/ClassAndModuleChildren
4
+ class ParenthesesAroundMultilineCondition < ::RuboCop::Cop::Base
5
+ extend ::RuboCop::Cop::AutoCorrector
6
+ include ::RuboCop::Cop::RangeHelp
7
+
8
+ MSG = 'Wrap multiline `%<keyword>s` conditions in parentheses.'
9
+
10
+ def on_if(node)
11
+ if offense?(node)
12
+ add_offense(node.loc.keyword, message: format(MSG, keyword: node.keyword)) do |corrector|
13
+ autocorrect(corrector, node)
14
+ end
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def offense?(node)
21
+ multiline_conditional?(node) &&
22
+ !permitted_multiline_condition?(node) &&
23
+ !correctly_parenthesized?(node)
24
+ end
25
+
26
+ def correctly_parenthesized?(node)
27
+ inner_condition = parenthesized_condition(node.condition)
28
+
29
+ if inner_condition
30
+ condition_starts_on_next_line?(node, inner_condition) &&
31
+ closing_parenthesis_on_own_line?(node.condition, inner_condition)
32
+ end
33
+ end
34
+
35
+ def multiline_conditional?(node)
36
+ !node.modifier_form? && !node.ternary? && node.condition.multiline?
37
+ end
38
+
39
+ def permitted_multiline_condition?(node)
40
+ condition = node.condition
41
+
42
+ condition.any_block_type? || multiline_parenthesized_receiver?(condition)
43
+ end
44
+
45
+ def multiline_parenthesized_receiver?(condition)
46
+ if condition.send_type? || condition.csend_type?
47
+ receiver = condition.receiver
48
+ receiver&.begin_type? && receiver.multiline?
49
+ end
50
+ end
51
+
52
+ def autocorrect(corrector, node)
53
+ condition = node.condition
54
+ inner_condition = parenthesized_condition(condition)
55
+ condition_start =
56
+ if inner_condition
57
+ inner_condition.source_range.begin_pos
58
+ else
59
+ condition.source_range.begin_pos
60
+ end
61
+
62
+ if inner_condition
63
+ if !condition_starts_on_next_line?(node, inner_condition)
64
+ corrector.replace(
65
+ range_between(node.loc.keyword.end_pos, condition_start),
66
+ " (\n#{condition_indentation(node)}",
67
+ )
68
+ end
69
+
70
+ if !closing_parenthesis_on_own_line?(condition, inner_condition)
71
+ corrector.replace(
72
+ range_between(inner_condition.source_range.end_pos, condition.loc.end.end_pos),
73
+ "\n#{base_indentation(node)})",
74
+ )
75
+ end
76
+ else
77
+ corrector.replace(
78
+ range_between(node.loc.keyword.end_pos, condition_start),
79
+ " (\n#{condition_indentation(node)}",
80
+ )
81
+
82
+ condition_end = condition_end_position(condition)
83
+ corrector.insert_after(
84
+ range_between(condition_end, condition_end),
85
+ "\n#{base_indentation(node)})",
86
+ )
87
+ end
88
+ end
89
+
90
+ def condition_starts_on_next_line?(node, inner_condition)
91
+ inner_condition.first_line > node.loc.keyword.line
92
+ end
93
+
94
+ def closing_parenthesis_on_own_line?(condition, inner_condition)
95
+ condition.loc.end.line > inner_condition.source_range.last_line
96
+ end
97
+
98
+ def parenthesized_condition(condition)
99
+ if (
100
+ condition.begin_type? &&
101
+ condition.children.one? &&
102
+ condition.loc.begin &&
103
+ condition.loc.end
104
+ )
105
+ condition.children.first
106
+ end
107
+ end
108
+
109
+ def condition_end_position(condition)
110
+ end_position = condition.source_range.end_pos
111
+ last_line = condition.source_range.last_line
112
+
113
+ processed_source.comments.each do |comment|
114
+ if comment.location.line == last_line && comment.source_range.begin_pos >= end_position
115
+ end_position = comment.source_range.end_pos
116
+ end
117
+ end
118
+
119
+ end_position
120
+ end
121
+
122
+ def base_indentation(node)
123
+ node.loc.keyword.source_line[/\A[ \t]*/]
124
+ end
125
+
126
+ def condition_indentation(node)
127
+ base_indentation(node) + (' ' * indentation_width)
128
+ end
129
+
130
+ def indentation_width
131
+ config.for_cop('Layout/IndentationWidth')['Width'] || 2
132
+ end
133
+ end
134
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RungerStyle
4
- VERSION = '5.17.0'
4
+ VERSION = '5.19.0'
5
5
  end
data/rulesets/default.yml CHANGED
@@ -186,7 +186,6 @@ Style/MethodCallWithArgsParentheses:
186
186
  - add_index
187
187
  - add_reference
188
188
  - and
189
- - belongs_to
190
189
  - bigint
191
190
  - boolean
192
191
  - change
@@ -196,16 +195,11 @@ Style/MethodCallWithArgsParentheses:
196
195
  - change_table
197
196
  - create_table
198
197
  - datetime
199
- - desc
200
198
  - describe
201
199
  - drop_table
202
- - fail
203
- - file
204
200
  - float
205
201
  - foreign_key
206
- - gem
207
202
  - head
208
- - include
209
203
  - index
210
204
  - inet
211
205
  - integer
@@ -213,24 +207,17 @@ Style/MethodCallWithArgsParentheses:
213
207
  - jsonb
214
208
  - load
215
209
  - not_to
216
- - p
217
- - print
218
- - puts
219
210
  - references
220
211
  - remove_column
221
212
  - remove_index
222
213
  - render
223
214
  - require
224
215
  - require_relative
225
- - ruby
226
- - run
227
- - source
228
216
  - string
229
217
  - text
230
218
  - timestamp
231
219
  - timestamps
232
220
  - to
233
- - visit
234
221
  Style/MethodCalledOnDoEndBlock:
235
222
  Enabled: false
236
223
  Style/MissingElse:
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runger_style
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.17.0
4
+ version: 5.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Runger
@@ -77,6 +77,7 @@ files:
77
77
  - lib/runger_style/cops/default/multiline_hash_value_indentation.rb
78
78
  - lib/runger_style/cops/default/multiline_method_arguments_line_breaks.rb
79
79
  - lib/runger_style/cops/default/no_return.rb
80
+ - lib/runger_style/cops/default/parentheses_around_multiline_condition.rb
80
81
  - lib/runger_style/cops/default/require_all_custom_cops.rb
81
82
  - lib/runger_style/cops/default/require_all_monkeypatches.rb
82
83
  - lib/runger_style/version.rb