rubocop-legion 0.1.2 → 0.1.3
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 +6 -0
- data/CLAUDE.md +96 -0
- data/README.md +73 -11
- data/config/base.yml +60 -0
- data/config/core.yml +17 -0
- data/config/lex.yml +16 -0
- data/lib/rubocop/legion/version.rb +1 -1
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b8cc626a680f38939c6212bd03e40249c354e24e8d4d8415aee6aa00c449e67e
|
|
4
|
+
data.tar.gz: 3eaed689593c5ec2ec4e24c89104c856ff0bff298302c278f1ca296d7278161f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8ac7d705d82418617f8d9ff3e67524911ff1c947a381c1ab61fcbdc35a1fa5c7537e9dc017f7118ca0037eebe27ab52d352e08a7433fde06cf641b48e8e13006
|
|
7
|
+
data.tar.gz: ea1138ce50b98a013ea6b4de431eebb336a087ef3204b6be1c20061786d3e8c43f589958bc03050f1ed4d3f5bb9e9808b8da50eafbeeff323455a494be76e7bd
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.3] - 2026-03-29
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Shared config profiles: `config/lex.yml` for lex-* gems, `config/core.yml` for legion-* gems
|
|
7
|
+
- Use `inherit_gem: { rubocop-legion: config/lex.yml }` to replace 60-line .rubocop.yml with 2 lines
|
|
8
|
+
|
|
3
9
|
## [0.1.2] - 2026-03-29
|
|
4
10
|
|
|
5
11
|
### Added
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# rubocop-legion
|
|
2
|
+
|
|
3
|
+
**Parent**: `/Users/miverso2/rubymine/legion/CLAUDE.md`
|
|
4
|
+
|
|
5
|
+
## What is This?
|
|
6
|
+
|
|
7
|
+
Custom RuboCop plugin gem for the LegionIO ecosystem. Provides 32 AST-based cops across 6 departments. Uses the new RuboCop Plugin API (1.72+, lint_roller-based) with auto-discovery via gemspec metadata.
|
|
8
|
+
|
|
9
|
+
**GitHub**: https://github.com/LegionIO/rubocop-legion
|
|
10
|
+
**RubyGems**: https://rubygems.org/gems/rubocop-legion
|
|
11
|
+
**License**: MIT
|
|
12
|
+
|
|
13
|
+
## Cop Scoping
|
|
14
|
+
|
|
15
|
+
Cops are scoped by gem type — no per-repo configuration needed:
|
|
16
|
+
|
|
17
|
+
- **Universal** (9 cops): Fire on all LegionIO gems
|
|
18
|
+
- **Library-specific** (6 cops): Fire on all gems but only trigger when using Sequel, Sinatra, Thor, Faraday, or cache
|
|
19
|
+
- **LEX-only** (17 cops): Scoped to `lib/legion/extensions/**/*.rb` via Include directive — never fire on core `legion-*` libraries
|
|
20
|
+
|
|
21
|
+
## Departments and Cops
|
|
22
|
+
|
|
23
|
+
### Universal — 9 cops
|
|
24
|
+
|
|
25
|
+
- **ConstantSafety** (4): `BareDataDefine`, `BareProcess`, `BareJson` (all error, auto-fix) — prefix with `::` inside `module Legion`. `InheritParam` (convention, auto-fix) — pass `false` to `const_defined?`/`const_get`.
|
|
26
|
+
- **RescueLogging** (3): `BareRescue` (warning, auto-fix) — capture with `=> e`. `NoCapture` (convention, no auto-fix) — exception class without capture. `SilentCapture` (warning, no auto-fix) — captured but never logged/re-raised. Skips `_`-prefixed vars. All skip inline rescue modifiers.
|
|
27
|
+
- **Singleton** (1): `UseInstance` (error, auto-fix) — `.instance` not `.new` for configurable singleton classes.
|
|
28
|
+
- **Framework/ModuleFunctionPrivate** (1): `private` after `module_function` resets visibility.
|
|
29
|
+
|
|
30
|
+
### Library-Specific — 6 cops
|
|
31
|
+
|
|
32
|
+
- `EagerSequelModel` — `Sequel::Model(:table)` at require time
|
|
33
|
+
- `SinatraHostAuth` — Sinatra 4.0+ `set :host_authorization`
|
|
34
|
+
- `ThorReservedRun` — Thor 1.5+ reserves `run`
|
|
35
|
+
- `FaradayXmlMiddleware` — Faraday 2.0+ removed `:xml`
|
|
36
|
+
- `CacheTimeCoercion` — Time→String after cache round-trip
|
|
37
|
+
- `ApiStringKeys` — `Legion::JSON.load` returns symbol keys (scoped to `lib/legion/extensions/**/*.rb`)
|
|
38
|
+
|
|
39
|
+
### LEX-Only — 17 cops
|
|
40
|
+
|
|
41
|
+
- **HelperMigration** (7): `DirectLogging`, `OldLoggingMethods`, `DirectJson`, `DirectCache`, `DirectLocalCache`, `DirectCrypt` (all auto-fix) — use per-extension helpers, not global singletons. `LoggingGuard` (no auto-fix) — remove unnecessary `respond_to?(:log_warn)` / `defined?(Legion::Logging)` guards.
|
|
42
|
+
- **Extension** (10): `ActorSingularModule` (auto-fix), `CoreExtendGuard` (auto-fix), `RunnerMustBeModule`, `RunnerIncludeHelpers`, `SelfContainedActorRunnerClass`, `RunnerReturnHash`, `SettingsKeyMethod` (auto-fix), `SettingsBracketMultiArg` (auto-fix), `LlmAskKwargs`, `DataRequiredWithoutMigrations`.
|
|
43
|
+
|
|
44
|
+
## Architecture
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
rubocop-legion/
|
|
48
|
+
├── lib/
|
|
49
|
+
│ ├── rubocop-legion.rb # Entry point, requires all cops
|
|
50
|
+
│ └── rubocop/
|
|
51
|
+
│ ├── legion.rb # Namespace declarations
|
|
52
|
+
│ ├── legion/
|
|
53
|
+
│ │ ├── version.rb
|
|
54
|
+
│ │ └── plugin.rb # LintRoller::Plugin (auto-discovery)
|
|
55
|
+
│ └── cop/legion/
|
|
56
|
+
│ ├── helper_migration/ # 7 cops (lex-only)
|
|
57
|
+
│ ├── constant_safety/ # 4 cops (universal)
|
|
58
|
+
│ ├── singleton/ # 1 cop (universal)
|
|
59
|
+
│ ├── rescue_logging/ # 3 cops (universal)
|
|
60
|
+
│ ├── framework/ # 7 cops (universal + library-specific)
|
|
61
|
+
│ └── extension/ # 10 cops (lex-only)
|
|
62
|
+
├── config/
|
|
63
|
+
│ └── default.yml # All cop defaults, Include/Exclude scoping
|
|
64
|
+
└── spec/ # 233 specs, mirrors lib/ structure
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Key Implementation Details
|
|
68
|
+
|
|
69
|
+
- Plugin entry point: `RuboCop::Legion::Plugin` (LintRoller-based, registered via gemspec metadata `default_lint_roller_plugin`)
|
|
70
|
+
- All cops inherit from `RuboCop::Cop::Base`
|
|
71
|
+
- Auto-correctable cops use `extend AutoCorrector`
|
|
72
|
+
- AST matching via `def_node_matcher` and `def_node_search`
|
|
73
|
+
- Specs use `RuboCop::RSpec::Support` with `:config` shared context and `expect_offense`/`expect_correction`
|
|
74
|
+
- `BareRescue` and `NoCapture` skip rescue modifiers (inline `rescue`) to avoid syntax corruption
|
|
75
|
+
- `NoCapture` has no auto-correct to prevent correction loop with `Lint/UselessAssignment`
|
|
76
|
+
- `SilentCapture` skips `_`-prefixed variables (Ruby unused convention)
|
|
77
|
+
|
|
78
|
+
## Development
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
bundle install
|
|
82
|
+
bundle exec rspec # 233 specs
|
|
83
|
+
bundle exec rubocop # Self-linting
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Common Per-Repo Overrides
|
|
87
|
+
|
|
88
|
+
```yaml
|
|
89
|
+
# Repos using Faraday JSON middleware (string keys, not Legion::JSON symbol keys)
|
|
90
|
+
Legion/Framework/ApiStringKeys:
|
|
91
|
+
Enabled: false
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
**Maintained By**: Matthew Iverson (@Esity)
|
data/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
LegionIO code quality cops for [RuboCop](https://rubocop.org/).
|
|
4
4
|
|
|
5
|
-
Custom cops for the LegionIO async job engine ecosystem. Enforces helper usage, constant safety, rescue logging, framework conventions, and LEX extension structure.
|
|
5
|
+
Custom cops for the LegionIO async job engine ecosystem. Enforces helper usage, constant safety, rescue logging, framework conventions, and LEX extension structure. Replaces the regex-based `lint-patterns.yml` CI workflow with precise AST-based analysis and auto-correction.
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
9
9
|
Add to your Gemfile:
|
|
10
10
|
|
|
11
11
|
```ruby
|
|
12
|
-
gem 'rubocop-legion', require: false, group: :development
|
|
12
|
+
gem 'rubocop-legion', '~> 0.1', require: false, group: :development
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Usage
|
|
@@ -21,16 +21,78 @@ plugins:
|
|
|
21
21
|
- rubocop-legion
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Requires RuboCop 1.72+ (Plugin API with lint_roller).
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
## Cop Scoping
|
|
27
|
+
|
|
28
|
+
Cops are automatically scoped based on where they should apply:
|
|
29
|
+
|
|
30
|
+
- **Universal cops** fire on all LegionIO gems (any code inside `module Legion`)
|
|
31
|
+
- **Library-specific cops** fire on all gems but only trigger when using a specific library (Sequel, Sinatra, Thor, Faraday, etc.)
|
|
32
|
+
- **LEX-only cops** fire only on `lib/legion/extensions/**/*.rb` — they don't apply to core `legion-*` libraries
|
|
33
|
+
|
|
34
|
+
No per-repo configuration needed for scoping. If a cop doesn't apply to your gem type, it won't fire.
|
|
35
|
+
|
|
36
|
+
## Cops
|
|
37
|
+
|
|
38
|
+
### Universal (all LegionIO gems) — 9 cops
|
|
39
|
+
|
|
40
|
+
| Department | Cop | Severity | Auto-fix | Description |
|
|
41
|
+
|---|---|---|---|---|
|
|
42
|
+
| ConstantSafety | `BareDataDefine` | error | yes | Use `::Data.define` inside `module Legion` to avoid `Legion::Data` |
|
|
43
|
+
| ConstantSafety | `BareProcess` | error | yes | Use `::Process` inside `module Legion` to avoid `Legion::Process` |
|
|
44
|
+
| ConstantSafety | `BareJson` | error | yes | Use `::JSON` inside `module Legion` to avoid `Legion::JSON` |
|
|
45
|
+
| ConstantSafety | `InheritParam` | convention | yes | Pass `false` to `const_defined?`/`const_get` on dynamic modules |
|
|
46
|
+
| RescueLogging | `BareRescue` | warning | yes | Bare `rescue` swallows exceptions — capture with `rescue => e` |
|
|
47
|
+
| RescueLogging | `NoCapture` | convention | no | Exception class specified but not captured (`rescue Error` without `=> e`) |
|
|
48
|
+
| RescueLogging | `SilentCapture` | warning | no | Captured exception never logged or re-raised |
|
|
49
|
+
| Singleton | `UseInstance` | error | yes | Use `.instance` instead of `.new` for singleton classes |
|
|
50
|
+
| Framework | `ModuleFunctionPrivate` | convention | no | `private` after `module_function` resets visibility |
|
|
51
|
+
|
|
52
|
+
### Library-Specific (all gems, triggers on library usage) — 6 cops
|
|
53
|
+
|
|
54
|
+
| Department | Cop | Triggers on | Severity | Auto-fix | Description |
|
|
55
|
+
|---|---|---|---|---|---|
|
|
56
|
+
| Framework | `EagerSequelModel` | Sequel | warning | no | `Sequel::Model(:table)` introspects schema at require time |
|
|
57
|
+
| Framework | `SinatraHostAuth` | Sinatra | convention | no | Sinatra 4.0+ requires `set :host_authorization` |
|
|
58
|
+
| Framework | `ThorReservedRun` | Thor | warning | no | Thor 1.5+ reserves `run` — rename or use `map` |
|
|
59
|
+
| Framework | `FaradayXmlMiddleware` | Faraday | error | no | Faraday 2.0+ removed built-in `:xml` middleware |
|
|
60
|
+
| Framework | `CacheTimeCoercion` | cache_get | convention | no | Time objects become Strings after cache round-trip |
|
|
61
|
+
| Framework | `ApiStringKeys` | Legion::JSON.load | warning | yes | `Legion::JSON.load` returns symbol keys — use `body[:key]` |
|
|
62
|
+
|
|
63
|
+
### LEX Extensions Only (`lib/legion/extensions/**/*.rb`) — 17 cops
|
|
64
|
+
|
|
65
|
+
| Department | Cop | Severity | Auto-fix | Description |
|
|
66
|
+
|---|---|---|---|---|
|
|
67
|
+
| HelperMigration | `DirectLogging` | warning | yes | Use `log.method` instead of `Legion::Logging.method` |
|
|
68
|
+
| HelperMigration | `OldLoggingMethods` | warning | yes | Use `log.method` instead of deprecated `log_method` helpers |
|
|
69
|
+
| HelperMigration | `DirectJson` | convention | yes | Use `json_load`/`json_dump` instead of `Legion::JSON` |
|
|
70
|
+
| HelperMigration | `DirectCache` | warning | yes | Use `cache_get`/`cache_set` instead of `Legion::Cache` |
|
|
71
|
+
| HelperMigration | `DirectLocalCache` | warning | yes | Use `local_cache_get`/`local_cache_set` instead of `Legion::Cache::Local` |
|
|
72
|
+
| HelperMigration | `DirectCrypt` | warning | yes | Use `vault_get`/`vault_exist?` instead of `Legion::Crypt` |
|
|
73
|
+
| HelperMigration | `LoggingGuard` | convention | no | Remove unnecessary `respond_to?(:log_warn)` / `defined?(Legion::Logging)` guards |
|
|
74
|
+
| Extension | `ActorSingularModule` | error | yes | Use `module Actor` (singular) — framework discovers `Actor`, not `Actors` |
|
|
75
|
+
| Extension | `CoreExtendGuard` | error | yes | Guard `extend Core` with `const_defined?` for standalone compatibility |
|
|
76
|
+
| Extension | `RunnerMustBeModule` | warning | no | Runners must be modules, not classes |
|
|
77
|
+
| Extension | `RunnerIncludeHelpers` | convention | no | Runner modules need `include Helpers::Lex` or `extend self` |
|
|
78
|
+
| Extension | `SelfContainedActorRunnerClass` | warning | no | Self-contained actors must override `runner_class` |
|
|
79
|
+
| Extension | `RunnerReturnHash` | convention | no | Runner methods must return a Hash |
|
|
80
|
+
| Extension | `SettingsKeyMethod` | error | yes | `Legion::Settings` has no `key?` — use `!Settings[:key].nil?` |
|
|
81
|
+
| Extension | `SettingsBracketMultiArg` | error | yes | `Settings#[]` takes 1 arg — use `Settings.dig(...)` for nested access |
|
|
82
|
+
| Extension | `LlmAskKwargs` | error | no | `Legion::LLM.ask` only accepts `message:` — no extra kwargs |
|
|
83
|
+
| Extension | `DataRequiredWithoutMigrations` | warning | no | `data_required?` returns true but migrations may be missing |
|
|
84
|
+
|
|
85
|
+
**Total: 32 cops** across 6 departments, 15 auto-correctable.
|
|
86
|
+
|
|
87
|
+
## Per-Repo Overrides
|
|
88
|
+
|
|
89
|
+
Most repos need no overrides. Common exceptions:
|
|
90
|
+
|
|
91
|
+
```yaml
|
|
92
|
+
# Repos using Faraday JSON middleware (string keys, not Legion::JSON symbol keys)
|
|
93
|
+
Legion/Framework/ApiStringKeys:
|
|
94
|
+
Enabled: false
|
|
95
|
+
```
|
|
34
96
|
|
|
35
97
|
## License
|
|
36
98
|
|
data/config/base.yml
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Shared RuboCop configuration for all LegionIO gems.
|
|
2
|
+
# Do not use directly — inherit via config/lex.yml or config/core.yml.
|
|
3
|
+
|
|
4
|
+
AllCops:
|
|
5
|
+
TargetRubyVersion: 3.4
|
|
6
|
+
NewCops: enable
|
|
7
|
+
SuggestExtensions: false
|
|
8
|
+
|
|
9
|
+
Layout/LineLength:
|
|
10
|
+
Max: 160
|
|
11
|
+
|
|
12
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
|
13
|
+
EnforcedStyle: space
|
|
14
|
+
|
|
15
|
+
Layout/HashAlignment:
|
|
16
|
+
EnforcedHashRocketStyle: table
|
|
17
|
+
EnforcedColonStyle: table
|
|
18
|
+
|
|
19
|
+
Metrics/MethodLength:
|
|
20
|
+
Max: 50
|
|
21
|
+
|
|
22
|
+
Metrics/ClassLength:
|
|
23
|
+
Max: 1500
|
|
24
|
+
|
|
25
|
+
Metrics/ModuleLength:
|
|
26
|
+
Max: 1500
|
|
27
|
+
|
|
28
|
+
Metrics/BlockLength:
|
|
29
|
+
Max: 40
|
|
30
|
+
Exclude:
|
|
31
|
+
- 'spec/**/*'
|
|
32
|
+
- '*.gemspec'
|
|
33
|
+
|
|
34
|
+
Metrics/AbcSize:
|
|
35
|
+
Max: 60
|
|
36
|
+
|
|
37
|
+
Metrics/CyclomaticComplexity:
|
|
38
|
+
Max: 15
|
|
39
|
+
|
|
40
|
+
Metrics/PerceivedComplexity:
|
|
41
|
+
Max: 17
|
|
42
|
+
|
|
43
|
+
Style/Documentation:
|
|
44
|
+
Enabled: false
|
|
45
|
+
|
|
46
|
+
Style/SymbolArray:
|
|
47
|
+
Enabled: true
|
|
48
|
+
|
|
49
|
+
Style/FrozenStringLiteralComment:
|
|
50
|
+
Enabled: true
|
|
51
|
+
EnforcedStyle: always
|
|
52
|
+
|
|
53
|
+
Naming/FileName:
|
|
54
|
+
Enabled: false
|
|
55
|
+
|
|
56
|
+
Naming/PredicateMethod:
|
|
57
|
+
Enabled: false
|
|
58
|
+
|
|
59
|
+
Gemspec/DevelopmentDependencies:
|
|
60
|
+
Enabled: false
|
data/config/core.yml
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Shared RuboCop configuration for legion-* core library gems.
|
|
2
|
+
#
|
|
3
|
+
# Usage in your .rubocop.yml:
|
|
4
|
+
#
|
|
5
|
+
# inherit_gem:
|
|
6
|
+
# rubocop-legion: config/core.yml
|
|
7
|
+
#
|
|
8
|
+
# # Repo-specific overrides below (if any)
|
|
9
|
+
|
|
10
|
+
inherit_from: base.yml
|
|
11
|
+
|
|
12
|
+
plugins:
|
|
13
|
+
- rubocop-legion
|
|
14
|
+
|
|
15
|
+
Metrics/ParameterLists:
|
|
16
|
+
Max: 10
|
|
17
|
+
CountKeywordArgs: false
|
data/config/lex.yml
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Shared RuboCop configuration for lex-* extension gems.
|
|
2
|
+
#
|
|
3
|
+
# Usage in your .rubocop.yml:
|
|
4
|
+
#
|
|
5
|
+
# inherit_gem:
|
|
6
|
+
# rubocop-legion: config/lex.yml
|
|
7
|
+
#
|
|
8
|
+
# # Repo-specific overrides below (if any)
|
|
9
|
+
|
|
10
|
+
inherit_from: base.yml
|
|
11
|
+
|
|
12
|
+
plugins:
|
|
13
|
+
- rubocop-legion
|
|
14
|
+
|
|
15
|
+
Metrics/ParameterLists:
|
|
16
|
+
Max: 8
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubocop-legion
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -78,11 +78,15 @@ files:
|
|
|
78
78
|
- ".rspec"
|
|
79
79
|
- ".rubocop.yml"
|
|
80
80
|
- CHANGELOG.md
|
|
81
|
+
- CLAUDE.md
|
|
81
82
|
- Gemfile
|
|
82
83
|
- LICENSE
|
|
83
84
|
- README.md
|
|
84
85
|
- Rakefile
|
|
86
|
+
- config/base.yml
|
|
87
|
+
- config/core.yml
|
|
85
88
|
- config/default.yml
|
|
89
|
+
- config/lex.yml
|
|
86
90
|
- lib/rubocop-legion.rb
|
|
87
91
|
- lib/rubocop/cop/legion/constant_safety/bare_data_define.rb
|
|
88
92
|
- lib/rubocop/cop/legion/constant_safety/bare_json.rb
|