rubocop-kata 0.8.0 → 0.10.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: da7876f7f43029f7dfb90b0fb9527987fe9c50ee40336d0ba4fffdcc2cbad83f
4
- data.tar.gz: 902e0c01d3cc5e71553d3c90c68a707b7f3a554cc3e6ec1228f0640ae8772d6a
3
+ metadata.gz: 0d5931b8e8bdf39595150f5f4c4785fd1e7c267c4abfda47d02999913aa4bdd2
4
+ data.tar.gz: 56fdf88f035c7833469f0a290351696b2a1197f1f5cee2282ad60928201b3323
5
5
  SHA512:
6
- metadata.gz: 99fdeb3a9f112fbc7232f59da504bde048071f20d50e55ef367e5516119a307a68a4f071a371cdbbe7810248268ef526f5bbdec08c5e9068e14d17cee03661ca
7
- data.tar.gz: 9603d8560c96c877a5cb8f614bf10cab2aabf63aa5aace3209cc0596b06dab7a0edd4372919068a5c345b48cff076c1964b453ba38caa1dd3d026a96ad6c8371
6
+ metadata.gz: 122b3da618e42d4137b1c4986bd21ba63374e275168d84181afa87cfae319465fe07270d12d54c3cece22ac6b73585a137d7ac5780f22f5a9c4fb0f667a40a07
7
+ data.tar.gz: b9bfb1dc0d5be32ea85898cfae3fbe3ce3338578f2e57b1e7b9effd2e00b2847c50bedcb5f9d259292de8141fe3579e11b0bb925a9840534047f26577f5dff26
data/CHANGELOG.md CHANGED
@@ -1,5 +1,75 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.10.0] - 2026-08-30
4
+
5
+ - `Elegant/NoRedundantVariable`, `Elegant/PairedBrackets`, and
6
+ `Elegant/ClassInModule` now ship here, fixed, as `Kata/*` cops derived from
7
+ rubocop-elegant under MIT (`LICENSE.txt`); the originals are
8
+ off. The git-source Gemfile line is no longer needed: the correctors run
9
+ out of the box, and `ClassInModule` clears.
10
+
11
+ ## [0.9.0] - 2026-08-27
12
+
13
+ - The shared rule behind the naming cops is now explicit: compound syntax is
14
+ not the smell — multiple semantic concepts are. A name should name one thing,
15
+ not describe where it came from, what it manipulates, or which layer it
16
+ lives in.
17
+ - New `Kata/GoodClassName` replaces `Kata/AgentNoun` and the class half of
18
+ `Kata/NoUtilName`: a class names one object that exists in the model. It
19
+ keeps the doer check and its derived suggestions, adds junk-drawer names
20
+ matched whole or as a trailing segment (`Service` catches `InvoiceService`),
21
+ and flags names packing more than `MaxWords` concepts
22
+ (`CustomerOrderPayment`) unless `Terms` blesses them as one concept
23
+ (`CreditCard`). The default `Terms` ships the established technical
24
+ compounds: `AbstractSyntaxTree`, `RedBlackTree`, `UnitOfWork`,
25
+ `TimeWithZone`, `HashWithIndifferentAccess` and kin.
26
+ - New `Kata/GoodModuleName` replaces the module half of `Kata/NoUtilName`: a
27
+ module names a domain vocabulary, not an implementation category. Layer
28
+ buckets (`Services`, `Helpers`, `Logic` — so `BusinessLogic` too), vague
29
+ shared namespaces (`Common`, `Shared`, `Core`), doer modules, and crowded
30
+ names are flagged; `AccessControl` and `Billing` pass.
31
+ - `Kata/GoodMethodName` flags names chaining actions with a conjunction
32
+ (`validate_and_save`, `find_or_create`): each action wants its own method.
33
+ Traversal names (`customer_address`) were already priced by the word rule;
34
+ the message stays advisory — the cop cannot know your object model.
35
+ - `Kata/GoodMethodName` and `Kata/GoodVariableName` bless grammatical
36
+ suffixes `id` and `ms` (`user_id`, `timeout_ms`) alongside `at`, the role
37
+ prefixes `max`/`min`/`start`/`end` (`max_retries`, `start_time`), and ship
38
+ established lexical compounds and protocol vocabulary as default `Terms`:
39
+ `first_name`, `postal_code`, `time_zone`, `ip_address`, `user_agent`,
40
+ `mime_type`, `status_code`, `access_token` and kin — names that read as one
41
+ concept. Where names must mirror an external schema, `Exclude` the file:
42
+ the file is the boundary.
43
+ - The defaults were then pressure-tested against corpora of real stdlib, gem,
44
+ Rails, and business-domain names, and grew to absorb what any codebase hits:
45
+ role suffixes (`number`, `code`, `price`, `rate`, `date`, `path`, `url`,
46
+ `count`, `size`, `key`, `token`, `params`, `secret`, `level`, `file`, `dir`,
47
+ `period`, `seconds`, `cents`), role prefixes (`current`, `default`, `total`,
48
+ `new`, `other`, `raw`, `set`, `sort`, `expected`, `actual`, `assert`),
49
+ domain terms (`line_item`, `credit_card`, `payment_method`,
50
+ `billing_address`, `date_of_birth`, `dry_run`, `stack_trace` and kin), and
51
+ the contract names of Ruby, Rails, Sidekiq, Devise, Pundit and RSpec
52
+ (`perform_async`, `deconstruct_keys`, `authenticate_user!`, `policy_scope`,
53
+ `failure_message` and kin). Name suffixes that would bless owner+property
54
+ (`name`, `message`, `amount`) stayed out on purpose: `user_name` and
55
+ `error_message` are still priced.
56
+ - `Kata/GoodClassName` `AllowedNames` also covers the class families a
57
+ framework resolves or subclasses by name (`Validator`, `Decorator`,
58
+ `Presenter`, `Helper`, `Job`, `Logger`, `Delegator`, `Enumerator`,
59
+ `Driver`) and more thing-words (`Center`, `Transfer`);
60
+ `Kata/GoodModuleName` mirrors the class cop's allowed list, and its
61
+ `BannedNames` grows the layer plurals (`Jobs`, `Workers`, `Queries`,
62
+ `Policies`, `Forms`, `Decorators`, `Presenters`, `Serializers`,
63
+ `Validators`, `Mixins`, `Extensions`).
64
+ - The doer check no longer flags thing-words that merely end in `-er`/`-or`:
65
+ `User`, `Order`, `Customer`, `Monitor`, `Buffer` and kin ship in
66
+ `Kata/GoodClassName` `AllowedNames`. `Kata/GoodModuleName` ships the
67
+ framework suffixes (`Controller`, `Mailer`, `Serializer`) so reopening
68
+ `ActionController` is not an offense. `Kata/GoodMethodName` exempts the
69
+ names Ruby and Rails resolve by contract: `method_missing`,
70
+ `respond_to_missing?`, `marshal_dump`, `deep_dup`, `table_name`,
71
+ `primary_key` and kin.
72
+
3
73
  ## [0.8.0] - 2026-08-20
4
74
 
5
75
  - New `rubocop-kata plan` command: buckets the backlog into `structure`,
data/LICENSE.txt CHANGED
@@ -19,3 +19,29 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
22
+
23
+ ---
24
+
25
+ Portions of this software are derived from rubocop-elegant
26
+ (https://github.com/yegor256/rubocop-elegant), used under the same MIT
27
+ License, whose notice is reproduced here as it requires:
28
+
29
+ Copyright (c) 2019-2026 Yegor Bugayenko
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining a copy
32
+ of this software and associated documentation files (the "Software"), to deal
33
+ in the Software without restriction, including without limitation the rights
34
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35
+ copies of the Software, and to permit persons to whom the Software is
36
+ furnished to do so, subject to the following conditions:
37
+
38
+ The above copyright notice and this permission notice shall be included in all
39
+ copies or substantial portions of the Software.
40
+
41
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
47
+ SOFTWARE.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # rubocop-kata
2
2
 
3
- A RuboCop plugin that replaces a pile of linter gems and config with one dependency. Install it and your `.rubocop.yml` shrinks to project-specific overrides. Everything else comes from the gem: a curated stack of RuboCop extensions, opinionated style defaults, and fifteen house cops.
3
+ A RuboCop plugin that replaces a pile of linter gems and config with one dependency. Install it and your `.rubocop.yml` shrinks to project-specific overrides. Everything else comes from the gem: a curated stack of RuboCop extensions, opinionated style defaults, and eighteen house cops.
4
4
 
5
5
  `Kata/GoodMethodName` asks for one word per method name. A second word is
6
6
  allowed only when it is not hiding a missing object: a role prefix
@@ -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/AgentNoun` to `Kata/ClockDiscipline`.
17
+ - **Eighteen 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/AgentNoun: `PaymentProcessor` names a doer; name the class
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
@@ -65,50 +65,31 @@ reports a class nested in a class as global
65
65
  test-file exclusions never match a Rails or RSpec suite
66
66
  ([#77](https://github.com/yegor256/rubocop-elegant/issues/77)).
67
67
 
68
- The defaults here neutralise all four. `Elegant/ClassInModule` is off, because
69
- its offences cannot be cleared: the cop it ships beside forbids the module it
70
- asks for. The two broken correctors are set to report only, because their
71
- offences can be cleared, by hand. The exclusions are widened. Nothing corrupts
72
- your code out of the box, and nothing reports a defect you cannot fix.
68
+ Until upstream releases the fixes, the three cops ship here, fixed, as
69
+ `Kata/NoRedundantVariable`, `Kata/PairedBrackets`, and `Kata/ClassInModule`;
70
+ the `Elegant/*` originals are off so each offence is reported once. They are
71
+ derived from rubocop-elegant under its MIT licence, and the notice travels
72
+ with the gem as `LICENSE.txt`. The exclusions are widened.
73
+ Once upstream ships, the copies go and the originals come back on.
73
74
 
74
- A gemspec cannot name a git source, so to take the fixes themselves rather than
75
- the workarounds, add this to your own `Gemfile`:
76
-
77
- ```ruby
78
- gem "rubocop-elegant", github: "giacope/rubocop-elegant", branch: "fixes"
79
- ```
80
-
81
- That branch is the released gem plus the five pull requests, with the version
82
- pinned so Bundler resolves it. With it in place you can turn the two correctors
83
- back on:
84
-
85
- ```yaml
86
- Elegant/NoRedundantVariable:
87
- AutoCorrect: true
88
-
89
- Elegant/PairedBrackets:
90
- AutoCorrect: true
91
-
92
- Elegant/ClassInModule:
93
- Enabled: true
94
- ```
95
-
96
- Drop all three once upstream releases the fixes. On a Rails codebase, consider
97
- leaving `Elegant/ClassInModule` off for good: it wants every class inside a
98
- module, and Zeitwerk resolves `class Account` from `app/models/account.rb` as a
99
- top-level constant by design.
75
+ On a Rails codebase, consider turning `Kata/ClassInModule` off: it wants
76
+ every class inside a module, and Zeitwerk resolves `class Account` from
77
+ `app/models/account.rb` as a top-level constant by design.
100
78
 
101
79
  ## The cops
102
80
 
103
81
  | Cop | Default | What it enforces |
104
82
  | --- | --- | --- |
105
- | `Kata/AgentNoun` | on | Classes named for what they are, not `-er`/`-or` doers. Suggests the better name when it can derive one. `AllowedNames` matches a whole name or a trailing segment, so `Error` covers `UsageError`. |
83
+ | `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`. |
84
+ | `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`. |
85
+ | `Kata/NoRedundantVariable` | on | A local assigned once and read once is inlined at its read, unless the move would cross a loop, a branch, or a side effect. Autocorrects, and keeps Ruby 3.1 shorthand intact. Fixed copy of `Elegant/NoRedundantVariable`. |
86
+ | `Kata/PairedBrackets` | on | Every bracket pairs on its line, or opens at line end and closes at line start. Autocorrects without drifting the indent. Fixed copy of `Elegant/PairedBrackets`. |
87
+ | `Kata/ClassInModule` | on | A class lives in a module, a class, or a compact namespace, never at the top level. Fixed copy of `Elegant/ClassInModule`. |
106
88
  | `Kata/NoComments` | on | No prose comments; say it in the code. Magic comments, linter directives, and licence headers survive. Autocorrects. |
107
89
  | `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
90
  | `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
91
  | `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`. |
92
+ | `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
93
  | `Kata/GoodVariableName` | on | The same rule for locals, parameters, ivars, class variables, and globals; `_name` and `@_name` stay exempt. |
113
94
  | `Kata/BuilderNoun` | on | Builders named for what they return: `total`, not `calculate_total`. Tune via `BannedPrefixes`/`AllowedNames`. |
114
95
  | `Kata/NoBooleanFlag` | on | No positional boolean arguments; split the method or use a keyword. |
@@ -150,7 +131,7 @@ bundle exec rubocop-kata plan # or: plan path/to/project
150
131
 
151
132
  ```
152
133
  structure 184 Kata/ConstructorDiscipline 92, Kata/NoHashAsObject 48, Kata/EnvDiscipline 44
153
- naming 263 Kata/RealWords 141, Kata/GoodVariableName 88, Kata/AgentNoun 34
134
+ naming 263 Kata/RealWords 141, Kata/GoodVariableName 88, Kata/GoodClassName 34
154
135
  prose 57 Kata/NoComments 57
155
136
  rest 412 Elegant/PairedBrackets 300, Layout/LineLength 112
156
137
  next: structure — 184 offenses in 61 files; these mint the names `naming` then prices, so take them first