officer_neetzsche 0.3.0 → 0.4.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 +4 -4
- data/CHANGELOG.md +7 -1
- data/README.md +64 -2
- data/config/default.yml +5 -0
- data/lib/officer_neetzsche/version.rb +1 -1
- data/lib/rubocop/cop/neetzsche/multiline_conditional_body.rb +46 -0
- data/lib/rubocop/cop/neetzsche_cops.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 22890bd97c3719ada7fdb61dd55402c68b110045cdfc75e99961e85efbe6d2b6
|
|
4
|
+
data.tar.gz: 61c8a23f85804cfda9b60f5f7b86e79c5afb872d1b42ef72125ff9a364683dcb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 64d16df6a4336e4b0c39f7db504659e565831f581cc3dcbd135a17a034717e5ed75ff3be2c6da1ee2110c3c373c453fae707e393ab5e59b135fac9beaab759b7
|
|
7
|
+
data.tar.gz: 6dc9fcedae06886c4c967d5d74ff7091dbf12264f073b326dfb0c64932c42f0da05f5544051d7ef32b12d88005f6e2cb84e28166613a41172d209dfc2589afa0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
3
|
+
## 0.4.0 (unreleased)
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `NEETzsche/MultilineConditionalBody`: flags an `if`, `unless`, `elsif`, `else`, `while`, or `until` whose body is more than one statement, or one statement that spans lines, and asks for the body to be a method of its own. With `NEETzsche/StatementModifier`, that leaves a conditional two shapes: a modifier, or a block whose branches are one statement each. No autocorrect, since the method needs a name.
|
|
8
|
+
|
|
9
|
+
## 0.3.0 (2026-09-15)
|
|
4
10
|
|
|
5
11
|
### Added
|
|
6
12
|
|
data/README.md
CHANGED
|
@@ -9,6 +9,7 @@ RuboCop cops that enforce NEETzsche-isms. Every cop ships enabled: register the
|
|
|
9
9
|
| Cop | Enforces | Autocorrect |
|
|
10
10
|
| --- | --- | --- |
|
|
11
11
|
| `NEETzsche/GeneratedMigrationTimestamp` | Migration timestamps come from `bin/rails generate migration`, not a keyboard. | No |
|
|
12
|
+
| `NEETzsche/MultilineConditionalBody` | An `if`, `unless`, `while`, or `until` body of more than one statement, or more than one line, is a method of its own. | No |
|
|
12
13
|
| `NEETzsche/NoComments` | No comments. The code explains itself. | Yes |
|
|
13
14
|
| `NEETzsche/StatementModifier` | An `if`, `unless`, `while`, `until`, or `rescue` around one statement is a modifier. | Yes |
|
|
14
15
|
|
|
@@ -108,6 +109,67 @@ Projects that set `config.active_record.timestamped_migrations = false` number t
|
|
|
108
109
|
|
|
109
110
|
There is no autocorrect. The fix is to delete the file and run `bin/rails generate migration` again.
|
|
110
111
|
|
|
112
|
+
## NEETzsche/MultilineConditionalBody
|
|
113
|
+
|
|
114
|
+
Flags an `if`, `unless`, `elsif`, `else`, `while`, or `until` whose body is more than one statement, or one statement that spans lines. The fix is to name what the body does and move it into a method of its own, after which `NEETzsche/StatementModifier` rewrites the call site as a modifier. Between them, the two cops leave a conditional two shapes: a modifier, or a block whose branches are one statement each.
|
|
115
|
+
|
|
116
|
+
```ruby
|
|
117
|
+
# bad
|
|
118
|
+
if condition?
|
|
119
|
+
do_this
|
|
120
|
+
do_that
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
while queue.any?
|
|
124
|
+
item = queue.pop
|
|
125
|
+
item.call
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
if condition?
|
|
129
|
+
items.each do |item|
|
|
130
|
+
item.call
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# good
|
|
135
|
+
do_stuff if condition?
|
|
136
|
+
work_one_item while queue.any?
|
|
137
|
+
call_items if condition?
|
|
138
|
+
|
|
139
|
+
def do_stuff
|
|
140
|
+
do_this
|
|
141
|
+
do_that
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def work_one_item
|
|
145
|
+
item = queue.pop
|
|
146
|
+
item.call
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def call_items
|
|
150
|
+
items.each { |item| item.call }
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# good, because each branch is one statement
|
|
154
|
+
if condition?
|
|
155
|
+
do_this
|
|
156
|
+
else
|
|
157
|
+
do_that
|
|
158
|
+
end
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
The offense sits on the keyword of the branch: `if`, `unless`, `elsif`, `else`, `while`, or `until`. Each branch is judged on its own, so an `if` with a two-statement body and a one-statement `else` gets one offense, on the `if`. A heredoc counts as the lines it spans. A modifier whose body spans lines, such as `begin ... end if condition?`, is flagged too. A conditional nested inside another is flagged at every level whose body spans lines, and fixing the innermost usually clears the rest.
|
|
162
|
+
|
|
163
|
+
Left alone:
|
|
164
|
+
|
|
165
|
+
- A body of one statement on one line, which is `NEETzsche/StatementModifier`'s to rewrite.
|
|
166
|
+
- Ternaries, empty bodies, and `begin ... end while` loops.
|
|
167
|
+
- A condition that spans lines. Only the body is measured.
|
|
168
|
+
|
|
169
|
+
There is no autocorrect. The method needs a name that says what the body does, and that is a decision for a person. Moving the body by hand also means deciding what it reads and writes: a local variable the body uses becomes a parameter, one it assigns for later use becomes the return value, and a `return`, `break`, or `next` inside it means something else once it sits in another method. Once the body is one call, `NEETzsche/StatementModifier` turns the block into a modifier under `rubocop --autocorrect`.
|
|
170
|
+
|
|
171
|
+
`Style/GuardClause` and `Style/Next` may flag the same block with a different fix. Either fix satisfies this cop too, since a guard clause or a `next` leaves no block behind. Under `rubocop --autocorrect`, `Layout/LineLength` may wrap the arguments of a long modifier line and `Style/MultilineIfModifier` then restore the block form, which this cop flags. The way out is a method.
|
|
172
|
+
|
|
111
173
|
## NEETzsche/NoComments
|
|
112
174
|
|
|
113
175
|
Flags every comment. On autocorrect, a comment on its own line is deleted along with the line, and a trailing comment is deleted along with the whitespace before it.
|
|
@@ -168,7 +230,7 @@ def call
|
|
|
168
230
|
fetch rescue fallback
|
|
169
231
|
end
|
|
170
232
|
|
|
171
|
-
#
|
|
233
|
+
# left to NEETzsche/MultilineConditionalBody, because the body is more than one statement
|
|
172
234
|
if condition?
|
|
173
235
|
do_this
|
|
174
236
|
do_that
|
|
@@ -179,7 +241,7 @@ The offense sits on the keyword. A `rescue` counts when it is the only clause, r
|
|
|
179
241
|
|
|
180
242
|
Left alone, because the block form is the only correct one:
|
|
181
243
|
|
|
182
|
-
- A body of more than one statement, a statement that spans lines, or a condition that spans lines.
|
|
244
|
+
- A body of more than one statement, a statement that spans lines, or a condition that spans lines. The first two are for `NEETzsche/MultilineConditionalBody`.
|
|
183
245
|
- `else`, `elsif`, ternaries, and `begin ... end while` loops.
|
|
184
246
|
- A body that is itself an `if`, `unless`, `while`, `until`, `case`, or `rescue`, in either form. No chained modifiers.
|
|
185
247
|
- A `rescue` that names another class, lists several, binds a variable, has several clauses, an `else`, or an empty body or handler.
|
data/config/default.yml
CHANGED
|
@@ -9,6 +9,11 @@ NEETzsche/GeneratedMigrationTimestamp:
|
|
|
9
9
|
- "**/db/migrate/**/*.rb"
|
|
10
10
|
- "**/db/*_migrate/**/*.rb"
|
|
11
11
|
|
|
12
|
+
NEETzsche/MultilineConditionalBody:
|
|
13
|
+
Description: "Puts an `if`, `unless`, `elsif`, `else`, `while`, or `until` body that is more than one statement, or one statement over more than one line, in a method of its own."
|
|
14
|
+
Enabled: true
|
|
15
|
+
VersionAdded: "0.4.0"
|
|
16
|
+
|
|
12
17
|
NEETzsche/NoComments:
|
|
13
18
|
Description: "Forbids comments. Magic comments, shebangs, and rubocop directives are allowed."
|
|
14
19
|
Enabled: true
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module NEETzsche
|
|
6
|
+
class MultilineConditionalBody < Base
|
|
7
|
+
MSG = "Move a multi-line `%<keyword>s` body into its own method."
|
|
8
|
+
|
|
9
|
+
HEREDOC_TYPES = %i[str dstr xstr].freeze
|
|
10
|
+
|
|
11
|
+
def on_if(node)
|
|
12
|
+
return if node.ternary?
|
|
13
|
+
|
|
14
|
+
check(node.if_branch, node.loc.keyword, node.keyword)
|
|
15
|
+
check(node.else_branch, node.loc.else, "else") if node.else? && !node.elsif_conditional?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def on_while(node)
|
|
19
|
+
check(node.body, node.loc.keyword, node.keyword)
|
|
20
|
+
end
|
|
21
|
+
alias on_until on_while
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def check(body, keyword, name)
|
|
26
|
+
return if body.nil? || one_liner?(body)
|
|
27
|
+
|
|
28
|
+
add_offense(keyword, message: format(MSG, keyword: name))
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def one_liner?(body)
|
|
32
|
+
!multiple_statements?(body) && body.first_line == last_line(body)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def multiple_statements?(body)
|
|
36
|
+
(body.begin_type? || body.kwbegin_type?) && body.children.size > 1
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def last_line(body)
|
|
40
|
+
heredocs = body.each_node(*HEREDOC_TYPES).select(&:heredoc?)
|
|
41
|
+
[body.last_line, *heredocs.map { |heredoc| heredoc.loc.heredoc_end.line }].max
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: officer_neetzsche
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- TheStranjer
|
|
@@ -52,6 +52,7 @@ files:
|
|
|
52
52
|
- lib/officer_neetzsche/plugin.rb
|
|
53
53
|
- lib/officer_neetzsche/version.rb
|
|
54
54
|
- lib/rubocop/cop/neetzsche/generated_migration_timestamp.rb
|
|
55
|
+
- lib/rubocop/cop/neetzsche/multiline_conditional_body.rb
|
|
55
56
|
- lib/rubocop/cop/neetzsche/no_comments.rb
|
|
56
57
|
- lib/rubocop/cop/neetzsche/statement_modifier.rb
|
|
57
58
|
- lib/rubocop/cop/neetzsche_cops.rb
|