rubocop-kata 0.8.0 → 0.9.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 +62 -0
- data/README.md +6 -6
- data/config/default.yml +356 -30
- data/lib/rubocop/cop/kata/agent_noun.rb +8 -21
- data/lib/rubocop/cop/kata/good_class_name.rb +41 -0
- data/lib/rubocop/cop/kata/good_method_name.rb +9 -2
- data/lib/rubocop/cop/kata/good_module_name.rb +41 -0
- data/lib/rubocop/kata/plan.rb +2 -2
- data/lib/rubocop/kata/version.rb +1 -1
- data/lib/rubocop-kata.rb +3 -2
- data/skills/rubocop-kata/SKILL.md +4 -3
- metadata +8 -7
- data/lib/rubocop/cop/kata/no_util_name.rb +0 -19
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6c1ecc1a90d7d43dba2861011f7f9c8c1ecc97e71040908f1018df3199aca660
|
|
4
|
+
data.tar.gz: 216cb124bc0565ab89d5cf3ee52225e24771d6f4d0812e8a272b0fc14517e45e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5a806b0b657d6fa01fe422361616304f6581e23e041f76a70d3dc33f61814a600a808439282417de3f8ea34d03612927fdfcbced3f18010b90660407ffa165f7
|
|
7
|
+
data.tar.gz: 687dd4b67fb477cd51e4440e79f7d81a020f4712c1802541447eb489f97be8fab728cb26460c947113a2789f1fddf1f0e93ecd9bad70d2eadd232cbe025bf74d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,67 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.9.0] - 2026-08-27
|
|
4
|
+
|
|
5
|
+
- The shared rule behind the naming cops is now explicit: compound syntax is
|
|
6
|
+
not the smell — multiple semantic concepts are. A name should name one thing,
|
|
7
|
+
not describe where it came from, what it manipulates, or which layer it
|
|
8
|
+
lives in.
|
|
9
|
+
- New `Kata/GoodClassName` replaces `Kata/AgentNoun` and the class half of
|
|
10
|
+
`Kata/NoUtilName`: a class names one object that exists in the model. It
|
|
11
|
+
keeps the doer check and its derived suggestions, adds junk-drawer names
|
|
12
|
+
matched whole or as a trailing segment (`Service` catches `InvoiceService`),
|
|
13
|
+
and flags names packing more than `MaxWords` concepts
|
|
14
|
+
(`CustomerOrderPayment`) unless `Terms` blesses them as one concept
|
|
15
|
+
(`CreditCard`). The default `Terms` ships the established technical
|
|
16
|
+
compounds: `AbstractSyntaxTree`, `RedBlackTree`, `UnitOfWork`,
|
|
17
|
+
`TimeWithZone`, `HashWithIndifferentAccess` and kin.
|
|
18
|
+
- New `Kata/GoodModuleName` replaces the module half of `Kata/NoUtilName`: a
|
|
19
|
+
module names a domain vocabulary, not an implementation category. Layer
|
|
20
|
+
buckets (`Services`, `Helpers`, `Logic` — so `BusinessLogic` too), vague
|
|
21
|
+
shared namespaces (`Common`, `Shared`, `Core`), doer modules, and crowded
|
|
22
|
+
names are flagged; `AccessControl` and `Billing` pass.
|
|
23
|
+
- `Kata/GoodMethodName` flags names chaining actions with a conjunction
|
|
24
|
+
(`validate_and_save`, `find_or_create`): each action wants its own method.
|
|
25
|
+
Traversal names (`customer_address`) were already priced by the word rule;
|
|
26
|
+
the message stays advisory — the cop cannot know your object model.
|
|
27
|
+
- `Kata/GoodMethodName` and `Kata/GoodVariableName` bless grammatical
|
|
28
|
+
suffixes `id` and `ms` (`user_id`, `timeout_ms`) alongside `at`, the role
|
|
29
|
+
prefixes `max`/`min`/`start`/`end` (`max_retries`, `start_time`), and ship
|
|
30
|
+
established lexical compounds and protocol vocabulary as default `Terms`:
|
|
31
|
+
`first_name`, `postal_code`, `time_zone`, `ip_address`, `user_agent`,
|
|
32
|
+
`mime_type`, `status_code`, `access_token` and kin — names that read as one
|
|
33
|
+
concept. Where names must mirror an external schema, `Exclude` the file:
|
|
34
|
+
the file is the boundary.
|
|
35
|
+
- The defaults were then pressure-tested against corpora of real stdlib, gem,
|
|
36
|
+
Rails, and business-domain names, and grew to absorb what any codebase hits:
|
|
37
|
+
role suffixes (`number`, `code`, `price`, `rate`, `date`, `path`, `url`,
|
|
38
|
+
`count`, `size`, `key`, `token`, `params`, `secret`, `level`, `file`, `dir`,
|
|
39
|
+
`period`, `seconds`, `cents`), role prefixes (`current`, `default`, `total`,
|
|
40
|
+
`new`, `other`, `raw`, `set`, `sort`, `expected`, `actual`, `assert`),
|
|
41
|
+
domain terms (`line_item`, `credit_card`, `payment_method`,
|
|
42
|
+
`billing_address`, `date_of_birth`, `dry_run`, `stack_trace` and kin), and
|
|
43
|
+
the contract names of Ruby, Rails, Sidekiq, Devise, Pundit and RSpec
|
|
44
|
+
(`perform_async`, `deconstruct_keys`, `authenticate_user!`, `policy_scope`,
|
|
45
|
+
`failure_message` and kin). Name suffixes that would bless owner+property
|
|
46
|
+
(`name`, `message`, `amount`) stayed out on purpose: `user_name` and
|
|
47
|
+
`error_message` are still priced.
|
|
48
|
+
- `Kata/GoodClassName` `AllowedNames` also covers the class families a
|
|
49
|
+
framework resolves or subclasses by name (`Validator`, `Decorator`,
|
|
50
|
+
`Presenter`, `Helper`, `Job`, `Logger`, `Delegator`, `Enumerator`,
|
|
51
|
+
`Driver`) and more thing-words (`Center`, `Transfer`);
|
|
52
|
+
`Kata/GoodModuleName` mirrors the class cop's allowed list, and its
|
|
53
|
+
`BannedNames` grows the layer plurals (`Jobs`, `Workers`, `Queries`,
|
|
54
|
+
`Policies`, `Forms`, `Decorators`, `Presenters`, `Serializers`,
|
|
55
|
+
`Validators`, `Mixins`, `Extensions`).
|
|
56
|
+
- The doer check no longer flags thing-words that merely end in `-er`/`-or`:
|
|
57
|
+
`User`, `Order`, `Customer`, `Monitor`, `Buffer` and kin ship in
|
|
58
|
+
`Kata/GoodClassName` `AllowedNames`. `Kata/GoodModuleName` ships the
|
|
59
|
+
framework suffixes (`Controller`, `Mailer`, `Serializer`) so reopening
|
|
60
|
+
`ActionController` is not an offense. `Kata/GoodMethodName` exempts the
|
|
61
|
+
names Ruby and Rails resolve by contract: `method_missing`,
|
|
62
|
+
`respond_to_missing?`, `marshal_dump`, `deep_dup`, `table_name`,
|
|
63
|
+
`primary_key` and kin.
|
|
64
|
+
|
|
3
65
|
## [0.8.0] - 2026-08-20
|
|
4
66
|
|
|
5
67
|
- New `rubocop-kata plan` command: buckets the backlog into `structure`,
|
data/README.md
CHANGED
|
@@ -14,10 +14,10 @@ that dodge with a shipped dictionary instead of a word list you maintain:
|
|
|
14
14
|
|
|
15
15
|
- **One dependency.** Bundles rubocop-rspec, rubocop-performance, rubocop-elegant, rubocop-packaging, and rubocop-thread_safety behind a single gem.
|
|
16
16
|
- **Opinionated defaults.** Methods under 5 lines, classes under 100, 4 parameters max, 120-column lines, double quotes, `NewCops: enable`. See [config/default.yml](config/default.yml).
|
|
17
|
-
- **Fifteen house cops.** Naming, dependency discipline, and data honesty in the Elegant Objects spirit — from `Kata/
|
|
17
|
+
- **Fifteen house cops.** Naming, dependency discipline, and data honesty in the Elegant Objects spirit — from `Kata/GoodClassName` to `Kata/ClockDiscipline`.
|
|
18
18
|
|
|
19
19
|
```ruby
|
|
20
|
-
class PaymentProcessor # Kata/
|
|
20
|
+
class PaymentProcessor # Kata/GoodClassName: `PaymentProcessor` names a doer; name the class
|
|
21
21
|
end # for the thing it is, not the work it does. Try `Payment`.
|
|
22
22
|
|
|
23
23
|
class Payment # OK
|
|
@@ -102,13 +102,13 @@ top-level constant by design.
|
|
|
102
102
|
|
|
103
103
|
| Cop | Default | What it enforces |
|
|
104
104
|
| --- | --- | --- |
|
|
105
|
-
| `Kata/
|
|
105
|
+
| `Kata/GoodClassName` | on | A class names one object that exists in the model: no `-er`/`-or` doers (suggests the better name when it can derive one), no junk drawers (`Service`, `Util`, `Data`), no packing several concepts into one name (`CustomerOrderPayment`). Compound syntax is not the smell — `CreditCard` is one concept, and `Terms` holds those. `AllowedNames` and `BannedNames` match a whole name or a trailing segment, so `Error` covers `UsageError` and `Service` catches `InvoiceService`. |
|
|
106
|
+
| `Kata/GoodModuleName` | on | A module names a domain vocabulary (`Billing`, `AccessControl`), not an implementation category: no layer buckets (`Services`, `Helpers`, `Logic`), no vague shared namespaces (`Common`, `Shared`, `Core`), no doers. Tune via `BannedNames`/`Terms`/`AllowedNames`. |
|
|
106
107
|
| `Kata/NoComments` | on | No prose comments; say it in the code. Magic comments, linter directives, and licence headers survive. Autocorrects. |
|
|
107
108
|
| `Kata/IoDiscipline` | on | No bare `puts`/`warn`/`pp`/`p` outside the test suite and the boot layer; write through an injected `@io` or an explicit receiver. |
|
|
108
109
|
| `Kata/ProsePlacement` | off | Sentence-length strings belong in the presentation layer. Enable with an `Include`/`Exclude` matching your layering. |
|
|
109
|
-
| `Kata/NoUtilName` | on | No junk-drawer names (`Util`, `Helper`, `Manager`, `Service`, …). Tune via `BannedNames`. |
|
|
110
110
|
| `Kata/RealWords` | on | Every name segment is a word the shipped dictionary knows — `errorcount` (smash) and `cfg` (abbreviation) both fail, with no word list to maintain. Tune via `Terms`/`BannedWords`/`AllowedNames`. |
|
|
111
|
-
| `Kata/GoodMethodName` | on | One word per method name; a second word needs a role prefix (`after_fork`), a role suffix (`file_of`), or a reviewed `Terms` entry. Tune via `MaxWords`/`Prefixes`/`Suffixes`/`Terms`/`AllowedNames`. |
|
|
111
|
+
| `Kata/GoodMethodName` | on | One word per method name; a second word needs a role prefix (`after_fork`), a role suffix (`file_of`), or a reviewed `Terms` entry. A name chaining actions (`validate_and_save`, `find_or_create`) is flagged as two methods in one. Tune via `MaxWords`/`Prefixes`/`Suffixes`/`Terms`/`AllowedNames`. |
|
|
112
112
|
| `Kata/GoodVariableName` | on | The same rule for locals, parameters, ivars, class variables, and globals; `_name` and `@_name` stay exempt. |
|
|
113
113
|
| `Kata/BuilderNoun` | on | Builders named for what they return: `total`, not `calculate_total`. Tune via `BannedPrefixes`/`AllowedNames`. |
|
|
114
114
|
| `Kata/NoBooleanFlag` | on | No positional boolean arguments; split the method or use a keyword. |
|
|
@@ -150,7 +150,7 @@ bundle exec rubocop-kata plan # or: plan path/to/project
|
|
|
150
150
|
|
|
151
151
|
```
|
|
152
152
|
structure 184 Kata/ConstructorDiscipline 92, Kata/NoHashAsObject 48, Kata/EnvDiscipline 44
|
|
153
|
-
naming 263 Kata/RealWords 141, Kata/GoodVariableName 88, Kata/
|
|
153
|
+
naming 263 Kata/RealWords 141, Kata/GoodVariableName 88, Kata/GoodClassName 34
|
|
154
154
|
prose 57 Kata/NoComments 57
|
|
155
155
|
rest 412 Elegant/PairedBrackets 300, Layout/LineLength 112
|
|
156
156
|
next: structure — 184 offenses in 61 files; these mint the names `naming` then prices, so take them first
|
data/config/default.yml
CHANGED
|
@@ -10,20 +10,159 @@ AllCops:
|
|
|
10
10
|
Exclude:
|
|
11
11
|
- "vendor/**/*"
|
|
12
12
|
|
|
13
|
-
Kata/
|
|
13
|
+
Kata/GoodClassName:
|
|
14
14
|
Description: >-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
A class names one object that exists in the model. Three shapes hide that
|
|
16
|
+
object: a doer name (`-er`/`-or`), a junk-drawer name (`Service`, `Util`,
|
|
17
|
+
`Data`), and a name packing several concepts (`CustomerOrderPayment`).
|
|
18
|
+
Compound syntax is not the smell — `CreditCard` is one concept, and belongs
|
|
19
|
+
in `Terms`. `AllowedNames` and `BannedNames` match a whole name or a
|
|
20
|
+
trailing segment, so `Error` also exempts `UsageError` and `Service` also
|
|
21
|
+
catches `InvoiceService`. The default `AllowedNames` holds the suffixes a
|
|
22
|
+
framework resolves a class by, which are contracts rather than naming
|
|
23
|
+
choices, plus thing-words that merely end in `-er`/`-or` — `User` and
|
|
24
|
+
`Order` are objects, not doers. Absorbs Kata/AgentNoun and the class half
|
|
25
|
+
of Kata/NoUtilName.
|
|
19
26
|
Enabled: true
|
|
20
|
-
VersionAdded: "0.
|
|
21
|
-
|
|
27
|
+
VersionAdded: "0.9"
|
|
28
|
+
MaxWords: 2
|
|
22
29
|
AllowedNames:
|
|
30
|
+
- Actor
|
|
31
|
+
- Author
|
|
32
|
+
- Buffer
|
|
33
|
+
- Center
|
|
34
|
+
- Chapter
|
|
35
|
+
- Character
|
|
36
|
+
- Color
|
|
37
|
+
- Container
|
|
38
|
+
- Controller
|
|
39
|
+
- Cursor
|
|
40
|
+
- Customer
|
|
41
|
+
- Decorator
|
|
42
|
+
- Delegator
|
|
43
|
+
- Driver
|
|
44
|
+
- Enumerator
|
|
23
45
|
- Error
|
|
46
|
+
- Fiber
|
|
47
|
+
- Folder
|
|
48
|
+
- Helper
|
|
49
|
+
- Job
|
|
50
|
+
- Ledger
|
|
51
|
+
- Logger
|
|
52
|
+
- Mailer
|
|
53
|
+
- Member
|
|
54
|
+
- Monitor
|
|
55
|
+
- Order
|
|
56
|
+
- Owner
|
|
57
|
+
- Presenter
|
|
58
|
+
- Serializer
|
|
59
|
+
- Server
|
|
60
|
+
- Supplier
|
|
61
|
+
- Timer
|
|
62
|
+
- Transfer
|
|
63
|
+
- User
|
|
64
|
+
- Validator
|
|
65
|
+
- Vector
|
|
66
|
+
BannedNames:
|
|
67
|
+
- Util
|
|
68
|
+
- Utils
|
|
69
|
+
- Utility
|
|
70
|
+
- Utilities
|
|
71
|
+
- Service
|
|
72
|
+
- Data
|
|
73
|
+
- Info
|
|
74
|
+
- Misc
|
|
75
|
+
Terms:
|
|
76
|
+
- AbstractSyntaxTree
|
|
77
|
+
- BillOfLading
|
|
78
|
+
- BinarySearchTree
|
|
79
|
+
- HashWithIndifferentAccess
|
|
80
|
+
- JsonWebToken
|
|
81
|
+
- OneTimePassword
|
|
82
|
+
- RedBlackTree
|
|
83
|
+
- StockKeepingUnit
|
|
84
|
+
- TimeWithZone
|
|
85
|
+
- UnitOfWork
|
|
86
|
+
|
|
87
|
+
Kata/GoodModuleName:
|
|
88
|
+
Description: >-
|
|
89
|
+
A module names a domain vocabulary or boundary, not an implementation
|
|
90
|
+
category. Layer buckets (`Services`, `Helpers`, `Logic`), vague shared
|
|
91
|
+
namespaces (`Common`, `Shared`, `Core`), doer names, and names packing
|
|
92
|
+
several concepts are flagged; a genuine compound domain like
|
|
93
|
+
`AccessControl` passes. `BannedNames` matches a whole name or a trailing
|
|
94
|
+
segment, so `Services` also catches `ApplicationServices`. The default
|
|
95
|
+
`AllowedNames` holds the framework suffixes, so reopening
|
|
96
|
+
`ActionController` or `ActionMailer` is not an offense; reopening another
|
|
97
|
+
library's junk drawer (`FileUtils`) is a file-boundary `Exclude`, not a
|
|
98
|
+
naming choice. Absorbs the module half of Kata/NoUtilName.
|
|
99
|
+
Enabled: true
|
|
100
|
+
VersionAdded: "0.9"
|
|
101
|
+
MaxWords: 2
|
|
102
|
+
AllowedNames:
|
|
103
|
+
- Actor
|
|
104
|
+
- Author
|
|
105
|
+
- Buffer
|
|
106
|
+
- Center
|
|
107
|
+
- Chapter
|
|
108
|
+
- Character
|
|
109
|
+
- Color
|
|
110
|
+
- Container
|
|
24
111
|
- Controller
|
|
112
|
+
- Cursor
|
|
113
|
+
- Customer
|
|
114
|
+
- Decorator
|
|
115
|
+
- Delegator
|
|
116
|
+
- Driver
|
|
117
|
+
- Enumerator
|
|
118
|
+
- Error
|
|
119
|
+
- Fiber
|
|
120
|
+
- Folder
|
|
121
|
+
- Helper
|
|
122
|
+
- Job
|
|
123
|
+
- Ledger
|
|
124
|
+
- Logger
|
|
25
125
|
- Mailer
|
|
126
|
+
- Member
|
|
127
|
+
- Monitor
|
|
128
|
+
- Order
|
|
129
|
+
- Owner
|
|
130
|
+
- Presenter
|
|
26
131
|
- Serializer
|
|
132
|
+
- Server
|
|
133
|
+
- Supplier
|
|
134
|
+
- Timer
|
|
135
|
+
- Transfer
|
|
136
|
+
- User
|
|
137
|
+
- Validator
|
|
138
|
+
- Vector
|
|
139
|
+
BannedNames:
|
|
140
|
+
- Common
|
|
141
|
+
- Core
|
|
142
|
+
- Decorators
|
|
143
|
+
- Extensions
|
|
144
|
+
- Forms
|
|
145
|
+
- Helpers
|
|
146
|
+
- Jobs
|
|
147
|
+
- Logic
|
|
148
|
+
- Managers
|
|
149
|
+
- Misc
|
|
150
|
+
- Mixins
|
|
151
|
+
- Models
|
|
152
|
+
- Policies
|
|
153
|
+
- Presenters
|
|
154
|
+
- Queries
|
|
155
|
+
- Serializers
|
|
156
|
+
- Service
|
|
157
|
+
- Services
|
|
158
|
+
- Shared
|
|
159
|
+
- Util
|
|
160
|
+
- Utilities
|
|
161
|
+
- Utility
|
|
162
|
+
- Utils
|
|
163
|
+
- Validators
|
|
164
|
+
- Workers
|
|
165
|
+
Terms: []
|
|
27
166
|
|
|
28
167
|
Kata/NoComments:
|
|
29
168
|
Description: "Say it in the code; keep only comments the machine or the law reads."
|
|
@@ -41,34 +180,52 @@ Kata/GoodMethodName:
|
|
|
41
180
|
Description: >-
|
|
42
181
|
One word per method name. A second word is allowed only when it does not
|
|
43
182
|
hide a missing object: a role prefix (`after_fork`), a role suffix
|
|
44
|
-
(`file_of`), or a reviewed domain term.
|
|
45
|
-
|
|
183
|
+
(`file_of`), or a reviewed domain term. A name that chains actions
|
|
184
|
+
(`validate_and_save`) or spells out another object's property
|
|
185
|
+
(`customer_address`) is a missing method home, not a naming problem.
|
|
186
|
+
Do not delete the underscore — Kata/RealWords catches the smash.
|
|
46
187
|
Enabled: true
|
|
47
188
|
VersionAdded: "0.5"
|
|
189
|
+
VersionChanged: "0.9"
|
|
48
190
|
MaxWords: 2
|
|
49
191
|
Pattern: "^[a-z][a-z0-9]{0,15}$"
|
|
50
192
|
Prefixes:
|
|
51
193
|
- after
|
|
52
194
|
- all
|
|
53
195
|
- any
|
|
196
|
+
- actual
|
|
54
197
|
- around
|
|
55
198
|
- as
|
|
199
|
+
- assert
|
|
56
200
|
- at
|
|
57
201
|
- before
|
|
58
202
|
- by
|
|
203
|
+
- current
|
|
204
|
+
- default
|
|
59
205
|
- each
|
|
206
|
+
- end
|
|
60
207
|
- every
|
|
208
|
+
- expected
|
|
61
209
|
- fake
|
|
62
210
|
- for
|
|
63
211
|
- from
|
|
64
212
|
- into
|
|
213
|
+
- max
|
|
214
|
+
- min
|
|
215
|
+
- new
|
|
65
216
|
- "no"
|
|
66
217
|
- non
|
|
67
218
|
- "on"
|
|
219
|
+
- other
|
|
68
220
|
- per
|
|
221
|
+
- raw
|
|
222
|
+
- set
|
|
223
|
+
- sort
|
|
224
|
+
- start
|
|
69
225
|
- test
|
|
70
226
|
- the
|
|
71
227
|
- to
|
|
228
|
+
- total
|
|
72
229
|
- unless
|
|
73
230
|
- until
|
|
74
231
|
- when
|
|
@@ -76,54 +233,178 @@ Kata/GoodMethodName:
|
|
|
76
233
|
- with
|
|
77
234
|
- without
|
|
78
235
|
Suffixes:
|
|
236
|
+
- after
|
|
79
237
|
- at
|
|
80
238
|
- by
|
|
239
|
+
- cents
|
|
240
|
+
- code
|
|
241
|
+
- count
|
|
242
|
+
- date
|
|
243
|
+
- dir
|
|
244
|
+
- directory
|
|
245
|
+
- file
|
|
81
246
|
- for
|
|
82
247
|
- from
|
|
248
|
+
- id
|
|
83
249
|
- in
|
|
84
250
|
- into
|
|
251
|
+
- key
|
|
252
|
+
- level
|
|
253
|
+
- ms
|
|
254
|
+
- number
|
|
85
255
|
- of
|
|
86
256
|
- on
|
|
87
257
|
- over
|
|
258
|
+
- params
|
|
259
|
+
- path
|
|
88
260
|
- per
|
|
261
|
+
- period
|
|
262
|
+
- price
|
|
263
|
+
- rate
|
|
264
|
+
- seconds
|
|
265
|
+
- secret
|
|
266
|
+
- size
|
|
89
267
|
- to
|
|
268
|
+
- token
|
|
90
269
|
- under
|
|
270
|
+
- url
|
|
91
271
|
- with
|
|
92
272
|
- without
|
|
93
|
-
Terms:
|
|
94
|
-
|
|
273
|
+
Terms:
|
|
274
|
+
- access_token
|
|
275
|
+
- bank_account
|
|
276
|
+
- billing_address
|
|
277
|
+
- checkout_session
|
|
278
|
+
- content_type
|
|
279
|
+
- credit_card
|
|
280
|
+
- date_of_birth
|
|
281
|
+
- display_name
|
|
282
|
+
- dry_run
|
|
283
|
+
- event_type
|
|
284
|
+
- exit_status
|
|
285
|
+
- first_name
|
|
286
|
+
- full_name
|
|
287
|
+
- gift_card
|
|
288
|
+
- grand_total
|
|
289
|
+
- in_stock
|
|
290
|
+
- ip_address
|
|
291
|
+
- last_name
|
|
292
|
+
- line_item
|
|
293
|
+
- line_items
|
|
294
|
+
- mark_as_read
|
|
295
|
+
- method_name
|
|
296
|
+
- middle_name
|
|
297
|
+
- mime_type
|
|
298
|
+
- out_of_stock
|
|
299
|
+
- page_title
|
|
300
|
+
- password_confirmation
|
|
301
|
+
- payment_intent
|
|
302
|
+
- payment_method
|
|
303
|
+
- query_string
|
|
304
|
+
- rate_limit
|
|
305
|
+
- search_term
|
|
306
|
+
- shipping_address
|
|
307
|
+
- soft_delete
|
|
308
|
+
- stack_trace
|
|
309
|
+
- time_zone
|
|
310
|
+
- user_agent
|
|
311
|
+
AllowedNames:
|
|
312
|
+
- active_for_authentication
|
|
313
|
+
- after_sign_in_path_for
|
|
314
|
+
- after_sign_out_path_for
|
|
315
|
+
- assign_attributes
|
|
316
|
+
- authenticate_user
|
|
317
|
+
- const_missing
|
|
318
|
+
- deconstruct_keys
|
|
319
|
+
- deep_dup
|
|
320
|
+
- default_scope
|
|
321
|
+
- define_method
|
|
322
|
+
- delete_if
|
|
323
|
+
- email_required
|
|
324
|
+
- failure_message
|
|
325
|
+
- failure_message_when_negated
|
|
326
|
+
- find_each
|
|
327
|
+
- force_encoding
|
|
328
|
+
- foreign_key
|
|
329
|
+
- inactive_message
|
|
330
|
+
- initialize_clone
|
|
331
|
+
- initialize_copy
|
|
332
|
+
- initialize_dup
|
|
333
|
+
- instance_method
|
|
334
|
+
- marshal_dump
|
|
335
|
+
- marshal_load
|
|
336
|
+
- method_added
|
|
337
|
+
- method_missing
|
|
338
|
+
- method_removed
|
|
339
|
+
- not_found
|
|
340
|
+
- password_required
|
|
341
|
+
- perform_async
|
|
342
|
+
- perform_later
|
|
343
|
+
- perform_now
|
|
344
|
+
- permitted_attributes
|
|
345
|
+
- policy_scope
|
|
346
|
+
- primary_key
|
|
347
|
+
- pundit_user
|
|
348
|
+
- read_nonblock
|
|
349
|
+
- record_not_found
|
|
350
|
+
- respond_to_missing
|
|
351
|
+
- send_devise_notification
|
|
352
|
+
- serializable_hash
|
|
353
|
+
- singleton_method_added
|
|
354
|
+
- supports_block_expectations
|
|
355
|
+
- table_name
|
|
356
|
+
- write_nonblock
|
|
95
357
|
|
|
96
358
|
Kata/GoodVariableName:
|
|
97
359
|
Description: >-
|
|
98
360
|
One word per variable name. A second word means a missing object, not a
|
|
99
361
|
name to smash together — Kata/RealWords catches the smash. Role prefixes, role
|
|
100
|
-
suffixes, and reviewed domain terms are the three exceptions.
|
|
362
|
+
suffixes, and reviewed domain terms are the three exceptions. Grammatical
|
|
363
|
+
suffixes (`created_at`, `user_id`, `timeout_ms`) are representation, not a
|
|
364
|
+
second concept. Where names must mirror an external schema, `Exclude` the
|
|
365
|
+
file: the file is the boundary.
|
|
101
366
|
Enabled: true
|
|
102
367
|
VersionAdded: "0.5"
|
|
368
|
+
VersionChanged: "0.9"
|
|
103
369
|
MaxWords: 2
|
|
104
370
|
Pattern: "^[a-z][a-z0-9]{0,15}$"
|
|
105
371
|
Prefixes:
|
|
106
372
|
- after
|
|
107
373
|
- all
|
|
108
374
|
- any
|
|
375
|
+
- actual
|
|
109
376
|
- around
|
|
110
377
|
- as
|
|
378
|
+
- assert
|
|
111
379
|
- at
|
|
112
380
|
- before
|
|
113
381
|
- by
|
|
382
|
+
- current
|
|
383
|
+
- default
|
|
114
384
|
- each
|
|
385
|
+
- end
|
|
115
386
|
- every
|
|
387
|
+
- expected
|
|
116
388
|
- fake
|
|
117
389
|
- for
|
|
118
390
|
- from
|
|
119
391
|
- into
|
|
392
|
+
- max
|
|
393
|
+
- min
|
|
394
|
+
- new
|
|
120
395
|
- "no"
|
|
121
396
|
- non
|
|
122
397
|
- "on"
|
|
398
|
+
- other
|
|
123
399
|
- per
|
|
400
|
+
- raw
|
|
401
|
+
- set
|
|
402
|
+
- sort
|
|
403
|
+
- start
|
|
124
404
|
- test
|
|
125
405
|
- the
|
|
126
406
|
- to
|
|
407
|
+
- total
|
|
127
408
|
- unless
|
|
128
409
|
- until
|
|
129
410
|
- when
|
|
@@ -131,23 +412,85 @@ Kata/GoodVariableName:
|
|
|
131
412
|
- with
|
|
132
413
|
- without
|
|
133
414
|
Suffixes:
|
|
415
|
+
- after
|
|
134
416
|
- at
|
|
135
417
|
- by
|
|
418
|
+
- cents
|
|
419
|
+
- code
|
|
420
|
+
- count
|
|
421
|
+
- date
|
|
422
|
+
- dir
|
|
423
|
+
- directory
|
|
424
|
+
- file
|
|
136
425
|
- for
|
|
137
426
|
- from
|
|
427
|
+
- id
|
|
138
428
|
- in
|
|
139
429
|
- into
|
|
430
|
+
- key
|
|
431
|
+
- level
|
|
432
|
+
- ms
|
|
433
|
+
- number
|
|
140
434
|
- of
|
|
141
435
|
- on
|
|
142
436
|
- over
|
|
437
|
+
- params
|
|
438
|
+
- path
|
|
143
439
|
- per
|
|
440
|
+
- period
|
|
441
|
+
- price
|
|
442
|
+
- rate
|
|
443
|
+
- seconds
|
|
444
|
+
- secret
|
|
445
|
+
- size
|
|
144
446
|
- to
|
|
447
|
+
- token
|
|
145
448
|
- under
|
|
449
|
+
- url
|
|
146
450
|
- with
|
|
147
451
|
- without
|
|
148
|
-
Terms:
|
|
452
|
+
Terms:
|
|
453
|
+
- access_token
|
|
454
|
+
- bank_account
|
|
455
|
+
- billing_address
|
|
456
|
+
- checkout_session
|
|
457
|
+
- content_type
|
|
458
|
+
- credit_card
|
|
459
|
+
- date_of_birth
|
|
460
|
+
- display_name
|
|
461
|
+
- dry_run
|
|
462
|
+
- event_type
|
|
463
|
+
- exit_status
|
|
464
|
+
- first_name
|
|
465
|
+
- full_name
|
|
466
|
+
- gift_card
|
|
467
|
+
- grand_total
|
|
468
|
+
- in_stock
|
|
469
|
+
- ip_address
|
|
470
|
+
- last_name
|
|
471
|
+
- line_item
|
|
472
|
+
- line_items
|
|
473
|
+
- mark_as_read
|
|
474
|
+
- method_name
|
|
475
|
+
- middle_name
|
|
476
|
+
- mime_type
|
|
477
|
+
- out_of_stock
|
|
478
|
+
- page_title
|
|
479
|
+
- password_confirmation
|
|
480
|
+
- payment_intent
|
|
481
|
+
- payment_method
|
|
482
|
+
- query_string
|
|
483
|
+
- rate_limit
|
|
484
|
+
- search_term
|
|
485
|
+
- shipping_address
|
|
486
|
+
- soft_delete
|
|
487
|
+
- stack_trace
|
|
488
|
+
- time_zone
|
|
489
|
+
- user_agent
|
|
149
490
|
AllowedNames:
|
|
150
491
|
- _include_private
|
|
492
|
+
- include_private
|
|
493
|
+
- resource_or_scope
|
|
151
494
|
|
|
152
495
|
Kata/IoDiscipline:
|
|
153
496
|
Description: "Write through an injected io, not bare puts/warn/pp/p."
|
|
@@ -172,23 +515,6 @@ Kata/ProsePlacement:
|
|
|
172
515
|
Enabled: false
|
|
173
516
|
VersionAdded: "0.1"
|
|
174
517
|
|
|
175
|
-
Kata/NoUtilName:
|
|
176
|
-
Description: "Junk-drawer names hide the concept the code is missing."
|
|
177
|
-
Enabled: true
|
|
178
|
-
VersionAdded: "0.3"
|
|
179
|
-
BannedNames:
|
|
180
|
-
- Util
|
|
181
|
-
- Utils
|
|
182
|
-
- Utility
|
|
183
|
-
- Utilities
|
|
184
|
-
- Helper
|
|
185
|
-
- Helpers
|
|
186
|
-
- Manager
|
|
187
|
-
- Service
|
|
188
|
-
- Common
|
|
189
|
-
- Misc
|
|
190
|
-
- Shared
|
|
191
|
-
|
|
192
518
|
Kata/RealWords:
|
|
193
519
|
Description: >-
|
|
194
520
|
Every name segment is a dictionary word: `errorcount` is a smash, `cfg`
|
|
@@ -1,28 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
module RuboCop::Cop::Kata::AgentNoun
|
|
4
|
+
DOER_MSG = "`%s` names a doer; name the %s for the thing it is, not the work it does."
|
|
5
|
+
DOER_HINT = "#{DOER_MSG} Try `%s`.".freeze
|
|
6
|
+
DOER = /(?:er|or)\z/
|
|
7
7
|
SEGMENT = /[A-Z]+(?=[A-Z][a-z]|\z)|[A-Z][a-z0-9]*/
|
|
8
8
|
DERIVATIONS = [[/ator\z/, "ation"], [/ector\z/, "ection"], [/isor\z/, "ision"], [/i[zs]er\z/, "is"]].freeze
|
|
9
9
|
|
|
10
|
-
def on_class(node) = check(node)
|
|
11
|
-
|
|
12
|
-
def on_module(node) = check(node)
|
|
13
|
-
|
|
14
10
|
private
|
|
15
11
|
|
|
16
|
-
def
|
|
17
|
-
name = node.identifier.short_name.to_s
|
|
18
|
-
return unless SUFFIX.match?(name)
|
|
19
|
-
return if allowed?(name)
|
|
20
|
-
add_offense(node.identifier, message: message(name))
|
|
21
|
-
end
|
|
12
|
+
def doer?(name) = DOER.match?(name)
|
|
22
13
|
|
|
23
|
-
def
|
|
14
|
+
def doer(name)
|
|
24
15
|
hint = suggestion(name)
|
|
25
|
-
hint ? format(
|
|
16
|
+
hint ? format(DOER_HINT, name, kind, hint) : format(DOER_MSG, name, kind)
|
|
26
17
|
end
|
|
27
18
|
|
|
28
19
|
def suggestion(name)
|
|
@@ -36,14 +27,10 @@ class RuboCop::Cop::Kata::AgentNoun < RuboCop::Cop::Base
|
|
|
36
27
|
end
|
|
37
28
|
|
|
38
29
|
def proposal(name)
|
|
39
|
-
return if name.empty? ||
|
|
30
|
+
return if name.empty? || DOER.match?(name)
|
|
40
31
|
return unless known?(name)
|
|
41
32
|
name
|
|
42
33
|
end
|
|
43
34
|
|
|
44
35
|
def known?(name) = RuboCop::Kata::Dictionary::ENTRIES.include?(name.scan(SEGMENT).last.to_s.downcase)
|
|
45
|
-
|
|
46
|
-
def allowed?(name) = list.any? { name.end_with?(it) }
|
|
47
|
-
|
|
48
|
-
def list = Array(cop_config["AllowedNames"]).map(&:to_s).reject(&:empty?)
|
|
49
36
|
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class RuboCop::Cop::Kata::GoodClassName < RuboCop::Cop::Base
|
|
4
|
+
include RuboCop::Cop::Kata::AgentNoun
|
|
5
|
+
|
|
6
|
+
BUCKET_MSG = "`%s` is a junk drawer; it hides the concept the code is missing."
|
|
7
|
+
CROWD_MSG = "`%s` packs %d concepts into one name; a class names one object that exists " \
|
|
8
|
+
"in the model — or, if `%s` reads as one concept here, add it to `Terms`."
|
|
9
|
+
|
|
10
|
+
def on_class(node) = check(node)
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def check(node)
|
|
15
|
+
name = node.identifier.short_name.to_s
|
|
16
|
+
return if allowed?(name)
|
|
17
|
+
complaint = complaint(name)
|
|
18
|
+
add_offense(node.identifier, message: complaint) if complaint
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def complaint(name)
|
|
22
|
+
return format(BUCKET_MSG, name) if banned?(name)
|
|
23
|
+
return doer(name) if doer?(name)
|
|
24
|
+
crowd(name)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def crowd(name)
|
|
28
|
+
count = name.scan(SEGMENT).size
|
|
29
|
+
format(CROWD_MSG, name, count, name) if count > max
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def kind = "class"
|
|
33
|
+
|
|
34
|
+
def banned?(name) = list("BannedNames").any? { name.end_with?(it) }
|
|
35
|
+
|
|
36
|
+
def allowed?(name) = list("AllowedNames").any? { name.end_with?(it) } || list("Terms").include?(name)
|
|
37
|
+
|
|
38
|
+
def list(key) = Array(cop_config[key]).map(&:to_s).reject(&:empty?)
|
|
39
|
+
|
|
40
|
+
def max = Integer(cop_config.fetch("MaxWords", 2))
|
|
41
|
+
end
|
|
@@ -4,6 +4,8 @@ class RuboCop::Cop::Kata::GoodMethodName < RuboCop::Cop::Base
|
|
|
4
4
|
MSG = "`%s` needs two words: either a concept is missing, or the method belongs on the object " \
|
|
5
5
|
"the second word names. Say it in one word, move it, give the role a `Prefixes`/`Suffixes` " \
|
|
6
6
|
"word — or, if `%s` is one domain concept here, add it to `Terms`."
|
|
7
|
+
CHAIN_MSG = "`%s` chains actions with `%s`; each action wants its own method."
|
|
8
|
+
JOINTS = %w[and or then].freeze
|
|
7
9
|
|
|
8
10
|
def on_def(node) = check(node, node.method_name)
|
|
9
11
|
|
|
@@ -15,8 +17,13 @@ class RuboCop::Cop::Kata::GoodMethodName < RuboCop::Cop::Base
|
|
|
15
17
|
return unless name.match?(/\A[a-z_]/)
|
|
16
18
|
stem = name.to_s.sub(/[?!=]\z/, "")
|
|
17
19
|
return if allowed?(name.to_s) || allowed?(stem)
|
|
18
|
-
|
|
19
|
-
add_offense(node.loc.name, message:
|
|
20
|
+
complaint = chain(name, stem) || (format(MSG, name, name) unless good?(stem))
|
|
21
|
+
add_offense(node.loc.name, message: complaint) if complaint
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def chain(name, stem)
|
|
25
|
+
joint = (stem.split("_") & JOINTS).first
|
|
26
|
+
format(CHAIN_MSG, name, joint) if joint
|
|
20
27
|
end
|
|
21
28
|
|
|
22
29
|
def good?(stem)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class RuboCop::Cop::Kata::GoodModuleName < RuboCop::Cop::Base
|
|
4
|
+
include RuboCop::Cop::Kata::AgentNoun
|
|
5
|
+
|
|
6
|
+
LAYER_MSG = "`%s` names a layer or a junk drawer; a module names a domain vocabulary."
|
|
7
|
+
CROWD_MSG = "`%s` packs %d concepts into one name; a module names one domain — " \
|
|
8
|
+
"or, if `%s` reads as one concept here, add it to `Terms`."
|
|
9
|
+
|
|
10
|
+
def on_module(node) = check(node)
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def check(node)
|
|
15
|
+
name = node.identifier.short_name.to_s
|
|
16
|
+
return if allowed?(name)
|
|
17
|
+
complaint = complaint(name)
|
|
18
|
+
add_offense(node.identifier, message: complaint) if complaint
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def complaint(name)
|
|
22
|
+
return format(LAYER_MSG, name) if banned?(name)
|
|
23
|
+
return doer(name) if doer?(name)
|
|
24
|
+
crowd(name)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def crowd(name)
|
|
28
|
+
count = name.scan(SEGMENT).size
|
|
29
|
+
format(CROWD_MSG, name, count, name) if count > max
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def kind = "module"
|
|
33
|
+
|
|
34
|
+
def banned?(name) = list("BannedNames").any? { name.end_with?(it) }
|
|
35
|
+
|
|
36
|
+
def allowed?(name) = list("AllowedNames").any? { name.end_with?(it) } || list("Terms").include?(name)
|
|
37
|
+
|
|
38
|
+
def list(key) = Array(cop_config[key]).map(&:to_s).reject(&:empty?)
|
|
39
|
+
|
|
40
|
+
def max = Integer(cop_config.fetch("MaxWords", 2))
|
|
41
|
+
end
|
data/lib/rubocop/kata/plan.rb
CHANGED
|
@@ -10,8 +10,8 @@ class RuboCop::Kata::Plan
|
|
|
10
10
|
Kata/NoBooleanFlag Kata/IoDiscipline Kata/ClockDiscipline Kata/EnvDiscipline
|
|
11
11
|
],
|
|
12
12
|
"naming" => %w[
|
|
13
|
-
Kata/RealWords Kata/GoodMethodName Kata/GoodVariableName Kata/
|
|
14
|
-
Kata/
|
|
13
|
+
Kata/RealWords Kata/GoodMethodName Kata/GoodVariableName Kata/GoodClassName
|
|
14
|
+
Kata/GoodModuleName Kata/BuilderNoun
|
|
15
15
|
],
|
|
16
16
|
"prose" => %w[Kata/NoComments Kata/ProsePlacement]
|
|
17
17
|
}.freeze
|
data/lib/rubocop/kata/version.rb
CHANGED
data/lib/rubocop-kata.rb
CHANGED
|
@@ -12,19 +12,20 @@ module RuboCop
|
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
require_relative "rubocop/cop/kata/agent_noun"
|
|
16
15
|
require_relative "rubocop/cop/kata/builder_noun"
|
|
17
16
|
require_relative "rubocop/cop/kata/clock_discipline"
|
|
18
17
|
require_relative "rubocop/cop/kata/constructor_discipline"
|
|
19
18
|
require_relative "rubocop/cop/kata/env_discipline"
|
|
19
|
+
require_relative "rubocop/cop/kata/agent_noun"
|
|
20
|
+
require_relative "rubocop/cop/kata/good_class_name"
|
|
20
21
|
require_relative "rubocop/cop/kata/good_method_name"
|
|
22
|
+
require_relative "rubocop/cop/kata/good_module_name"
|
|
21
23
|
require_relative "rubocop/cop/kata/good_variable_name"
|
|
22
24
|
require_relative "rubocop/cop/kata/io_discipline"
|
|
23
25
|
require_relative "rubocop/cop/kata/no_boolean_flag"
|
|
24
26
|
require_relative "rubocop/cop/kata/no_class_method_logic"
|
|
25
27
|
require_relative "rubocop/cop/kata/no_comments"
|
|
26
28
|
require_relative "rubocop/cop/kata/no_hash_as_object"
|
|
27
|
-
require_relative "rubocop/cop/kata/no_util_name"
|
|
28
29
|
require_relative "rubocop/cop/kata/prose_placement"
|
|
29
30
|
require_relative "rubocop/cop/kata/real_words"
|
|
30
31
|
require_relative "rubocop/kata/dictionary"
|
|
@@ -4,7 +4,7 @@ description: >-
|
|
|
4
4
|
Adopt rubocop-kata's rules on an existing codebase without the offense count going
|
|
5
5
|
the wrong way. Kata's structural cops (ConstructorDiscipline, NoHashAsObject,
|
|
6
6
|
Io/Clock/EnvDiscipline, NoClassMethodLogic, NoBooleanFlag) create names, and its naming
|
|
7
|
-
cops (RealWords, GoodMethodName, GoodVariableName,
|
|
7
|
+
cops (RealWords, GoodMethodName, GoodVariableName, GoodClassName, GoodModuleName, BuilderNoun)
|
|
8
8
|
charge for every name created — so a structural refactor removes offenses and adds more,
|
|
9
9
|
and a single total cannot tell progress from regression. This skill sequences the work by
|
|
10
10
|
stage, picks names that are already clean by checking them against the dictionary the cops
|
|
@@ -79,8 +79,9 @@ This is the step that keeps the count honest. Kata's naming rules, condensed:
|
|
|
79
79
|
| a second word only via a role prefix (`after_fork`), a role suffix (`file_of`), or a reviewed `Terms` entry | same |
|
|
80
80
|
| never smash the underscore out — `errorcount` fails too | `RealWords` |
|
|
81
81
|
| every segment is a real word; no `cfg`, `ctx`, `msg`, `tmp`, … | `RealWords` |
|
|
82
|
-
|
|
|
83
|
-
|
|
|
82
|
+
| a class is one object, not a `-er`/`-or` doer, a junk drawer (`Service`, `Util`, `Data`), or three concepts packed together | `GoodClassName` |
|
|
83
|
+
| a module is a domain vocabulary, not a layer (`Services`, `Helpers`, `Common`, `Shared`, `Core`) | `GoodModuleName` |
|
|
84
|
+
| a method is one action — no `_and_`/`_or_` chains | `GoodMethodName` |
|
|
84
85
|
| a method that returns something is named for what it returns, not `get_`/`calculate_`/`compute_` | `BuilderNoun` |
|
|
85
86
|
| memoization ivars are `@_name` | `Naming/MemoizedInstanceVariableName` |
|
|
86
87
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubocop-kata
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Giacomo GK
|
|
@@ -110,11 +110,11 @@ dependencies:
|
|
|
110
110
|
description: Bundles a curated RuboCop stack (rspec, performance, elegant, packaging,
|
|
111
111
|
thread_safety) behind one dependency, layers opinionated style defaults on top,
|
|
112
112
|
and adds fifteen cops of its own — naming (GoodMethodName, GoodVariableName, dictionary-backed
|
|
113
|
-
RealWords,
|
|
114
|
-
EnvDiscipline, ConstructorDiscipline, NoClassMethodLogic), and
|
|
115
|
-
NoBooleanFlag, NoHashAsObject, ProsePlacement). The rubocop-kata
|
|
116
|
-
dead configuration (doctor), buckets a backlog into the stages that
|
|
117
|
-
(plan), and prints an agent skill for working it (skill).
|
|
113
|
+
RealWords, GoodClassName, GoodModuleName, BuilderNoun), discipline (IoDiscipline,
|
|
114
|
+
ClockDiscipline, EnvDiscipline, ConstructorDiscipline, NoClassMethodLogic), and
|
|
115
|
+
shape (NoComments, NoBooleanFlag, NoHashAsObject, ProsePlacement). The rubocop-kata
|
|
116
|
+
command reports dead configuration (doctor), buckets a backlog into the stages that
|
|
117
|
+
cause each other (plan), and prints an agent skill for working it (skill).
|
|
118
118
|
email:
|
|
119
119
|
- giaco@hey.com
|
|
120
120
|
executables:
|
|
@@ -138,14 +138,15 @@ files:
|
|
|
138
138
|
- lib/rubocop/cop/kata/clock_discipline.rb
|
|
139
139
|
- lib/rubocop/cop/kata/constructor_discipline.rb
|
|
140
140
|
- lib/rubocop/cop/kata/env_discipline.rb
|
|
141
|
+
- lib/rubocop/cop/kata/good_class_name.rb
|
|
141
142
|
- lib/rubocop/cop/kata/good_method_name.rb
|
|
143
|
+
- lib/rubocop/cop/kata/good_module_name.rb
|
|
142
144
|
- lib/rubocop/cop/kata/good_variable_name.rb
|
|
143
145
|
- lib/rubocop/cop/kata/io_discipline.rb
|
|
144
146
|
- lib/rubocop/cop/kata/no_boolean_flag.rb
|
|
145
147
|
- lib/rubocop/cop/kata/no_class_method_logic.rb
|
|
146
148
|
- lib/rubocop/cop/kata/no_comments.rb
|
|
147
149
|
- lib/rubocop/cop/kata/no_hash_as_object.rb
|
|
148
|
-
- lib/rubocop/cop/kata/no_util_name.rb
|
|
149
150
|
- lib/rubocop/cop/kata/prose_placement.rb
|
|
150
151
|
- lib/rubocop/cop/kata/real_words.rb
|
|
151
152
|
- lib/rubocop/kata/checkup.rb
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class RuboCop::Cop::Kata::NoUtilName < RuboCop::Cop::Base
|
|
4
|
-
MSG = "`%s` is a junk drawer; it hides the concept the code is missing."
|
|
5
|
-
|
|
6
|
-
def on_class(node) = check(node)
|
|
7
|
-
|
|
8
|
-
def on_module(node) = check(node)
|
|
9
|
-
|
|
10
|
-
private
|
|
11
|
-
|
|
12
|
-
def check(node)
|
|
13
|
-
name = node.identifier.short_name.to_s
|
|
14
|
-
return unless banned?(name)
|
|
15
|
-
add_offense(node.identifier, message: format(MSG, name))
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def banned?(name) = Array(cop_config["BannedNames"]).map(&:to_s).include?(name)
|
|
19
|
-
end
|