rigortype 0.1.10 → 0.1.11
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/lib/rigor/analysis/baseline.rb +51 -15
- data/lib/rigor/cli/baseline_command.rb +4 -3
- data/lib/rigor/cli.rb +16 -3
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/analyzer.rb +190 -0
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +189 -0
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +81 -0
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +142 -0
- data/plugins/rigor-actioncable/lib/rigor-actioncable.rb +3 -0
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/analyzer.rb +178 -0
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +310 -0
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +76 -0
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +177 -0
- data/plugins/rigor-actionmailer/lib/rigor-actionmailer.rb +3 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +589 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_discoverer.rb +150 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb +123 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +247 -0
- data/plugins/rigor-actionpack/lib/rigor-actionpack.rb +3 -0
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb +114 -0
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +177 -0
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +65 -0
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +117 -0
- data/plugins/rigor-activejob/lib/rigor-activejob.rb +3 -0
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +273 -0
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/inflector.rb +114 -0
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +561 -0
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +194 -0
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +240 -0
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_table.rb +94 -0
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +514 -0
- data/plugins/rigor-activerecord/lib/rigor-activerecord.rb +8 -0
- data/plugins/rigor-activerecord/sig/active_record/relation.rbs +182 -0
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/analyzer.rb +78 -0
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_discoverer.rb +162 -0
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_index.rb +43 -0
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +170 -0
- data/plugins/rigor-activestorage/lib/rigor-activestorage.rb +8 -0
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +34 -0
- data/plugins/rigor-activesupport-core-ext/lib/rigor-activesupport-core-ext.rb +20 -0
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +463 -0
- data/plugins/rigor-devise/lib/rigor/plugin/devise.rb +108 -0
- data/plugins/rigor-devise/lib/rigor-devise.rb +8 -0
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb +285 -0
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema.rb +124 -0
- data/plugins/rigor-dry-schema/lib/rigor-dry-schema.rb +8 -0
- data/plugins/rigor-dry-struct/lib/rigor/plugin/dry_struct.rb +116 -0
- data/plugins/rigor-dry-struct/lib/rigor-dry-struct.rb +8 -0
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types/alias_scanner.rb +341 -0
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +120 -0
- data/plugins/rigor-dry-types/lib/rigor-dry-types.rb +8 -0
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/contract_scanner.rb +120 -0
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +85 -0
- data/plugins/rigor-dry-validation/lib/rigor-dry-validation.rb +7 -0
- data/plugins/rigor-dry-validation/sig/dry_validation.rbs +25 -0
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/analyzer.rb +177 -0
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +242 -0
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_index.rb +56 -0
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +174 -0
- data/plugins/rigor-factorybot/lib/rigor-factorybot.rb +3 -0
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +409 -0
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql.rb +114 -0
- data/plugins/rigor-graphql/lib/rigor-graphql.rb +8 -0
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami/action_checker.rb +124 -0
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami.rb +111 -0
- data/plugins/rigor-hanami/lib/rigor-hanami.rb +3 -0
- data/plugins/rigor-hanami/sig/hanami_action.rbs +78 -0
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +302 -0
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest.rb +72 -0
- data/plugins/rigor-minitest/lib/rigor-minitest.rb +3 -0
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/analyzer.rb +194 -0
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +140 -0
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_index.rb +65 -0
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit.rb +130 -0
- data/plugins/rigor-pundit/lib/rigor-pundit.rb +3 -0
- data/plugins/rigor-rails/lib/rigor-rails.rb +31 -0
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +277 -0
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb +108 -0
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +138 -0
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +167 -0
- data/plugins/rigor-rails-i18n/lib/rigor-rails-i18n.rb +3 -0
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +161 -0
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_table.rb +103 -0
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +490 -0
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +158 -0
- data/plugins/rigor-rails-routes/lib/rigor-rails-routes.rb +3 -0
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +163 -0
- data/plugins/rigor-rbs-inline/lib/rigor-rbs-inline.rb +24 -0
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/analyzer.rb +110 -0
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_scope_index.rb +200 -0
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_type_resolver.rb +170 -0
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +233 -0
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/scope_walker.rb +190 -0
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +188 -0
- data/plugins/rigor-rspec/lib/rigor-rspec.rb +3 -0
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/have_http_status_analyzer.rb +128 -0
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/http_status_codes.rb +60 -0
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails.rb +75 -0
- data/plugins/rigor-rspec-rails/lib/rigor-rspec-rails.rb +3 -0
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +266 -0
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers.rb +113 -0
- data/plugins/rigor-shoulda-matchers/lib/rigor-shoulda-matchers.rb +3 -0
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/analyzer.rb +152 -0
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_discoverer.rb +190 -0
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_index.rb +61 -0
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +124 -0
- data/plugins/rigor-sidekiq/lib/rigor-sidekiq.rb +3 -0
- data/plugins/rigor-sinatra/lib/rigor/plugin/sinatra.rb +85 -0
- data/plugins/rigor-sinatra/lib/rigor-sinatra.rb +8 -0
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb +108 -0
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/assertion_recognizer.rb +250 -0
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +95 -0
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +226 -0
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/method_signature.rb +28 -0
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +154 -0
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sigil_detector.rb +100 -0
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/type_translator.rb +323 -0
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +660 -0
- data/plugins/rigor-sorbet/lib/rigor-sorbet.rb +3 -0
- data/plugins/rigor-statesman/lib/rigor/plugin/statesman.rb +209 -0
- data/plugins/rigor-statesman/lib/rigor-statesman.rb +8 -0
- data/plugins/rigor-typescript-utility-types/lib/rigor/plugin/typescript_utility_types.rb +163 -0
- data/plugins/rigor-typescript-utility-types/lib/rigor-typescript-utility-types.rb +9 -0
- metadata +149 -1
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "prism"
|
|
4
|
+
require "rigor/plugin"
|
|
5
|
+
|
|
6
|
+
module Rigor
|
|
7
|
+
module Plugin
|
|
8
|
+
# Example plugin: validates state-machine references.
|
|
9
|
+
# Demonstrates the **two-pass DSL analysis** pattern many
|
|
10
|
+
# plugins reuse:
|
|
11
|
+
#
|
|
12
|
+
# 1. **Collect pass.** Walk the file once to gather every
|
|
13
|
+
# state name declared inside a `state_machine do ... end`
|
|
14
|
+
# block (`state :draft`, `state :submitted`, ...).
|
|
15
|
+
# 2. **Validate pass.** Walk the file again, validating each
|
|
16
|
+
# `transition_to(:sym)` and `event :sym` reference against
|
|
17
|
+
# the collected state set. Levenshtein distance ≤ 3 drives
|
|
18
|
+
# the did-you-mean suggestions.
|
|
19
|
+
#
|
|
20
|
+
# Useful for `aasm` / `statesman` / hand-rolled DSLs and any
|
|
21
|
+
# framework where declarations and uses live in the same
|
|
22
|
+
# file. The same skeleton lifts to GraphQL types,
|
|
23
|
+
# ActiveModel validations, route declarations — anywhere a
|
|
24
|
+
# declarative DSL produces a closed namespace and the rest
|
|
25
|
+
# of the file references that namespace by literal symbol.
|
|
26
|
+
#
|
|
27
|
+
# ## Configuration
|
|
28
|
+
#
|
|
29
|
+
# Defaults match the `Statesman::Machine` API; override via
|
|
30
|
+
# `.rigor.yml` if your DSL uses different names:
|
|
31
|
+
#
|
|
32
|
+
# plugins:
|
|
33
|
+
# - gem: rigor-statesman
|
|
34
|
+
# config:
|
|
35
|
+
# dsl_method: state_machine # the do-block opener
|
|
36
|
+
# state_method: state # state declaration inside the block
|
|
37
|
+
# transition_method: transition_to # call-site under check
|
|
38
|
+
#
|
|
39
|
+
# ## Diagnostics
|
|
40
|
+
#
|
|
41
|
+
# | Event | Severity | Rule |
|
|
42
|
+
# | --- | --- | --- |
|
|
43
|
+
# | `transition_to(:known_state)` | `:info` | `known-state` |
|
|
44
|
+
# | `transition_to(:typo)` (close match) | `:error` | `unknown-state` (with did-you-mean) |
|
|
45
|
+
# | `transition_to(:typo)` (no close match) | `:error` | `unknown-state` |
|
|
46
|
+
# | file declares no state machine | silent | — |
|
|
47
|
+
class Statesman < Rigor::Plugin::Base
|
|
48
|
+
manifest(
|
|
49
|
+
id: "statesman",
|
|
50
|
+
version: "0.1.0",
|
|
51
|
+
description: "Validates state-machine transition references against declared states.",
|
|
52
|
+
config_schema: {
|
|
53
|
+
"dsl_method" => :string,
|
|
54
|
+
"state_method" => :string,
|
|
55
|
+
"transition_method" => :string
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
DEFAULT_DSL_METHOD = "state_machine"
|
|
60
|
+
DEFAULT_STATE_METHOD = "state"
|
|
61
|
+
DEFAULT_TRANSITION_METHOD = "transition_to"
|
|
62
|
+
DID_YOU_MEAN_DISTANCE = 3
|
|
63
|
+
|
|
64
|
+
def init(_services)
|
|
65
|
+
@dsl_method = config.fetch("dsl_method", DEFAULT_DSL_METHOD).to_sym
|
|
66
|
+
@state_method = config.fetch("state_method", DEFAULT_STATE_METHOD).to_sym
|
|
67
|
+
@transition_method = config.fetch("transition_method", DEFAULT_TRANSITION_METHOD).to_sym
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def diagnostics_for_file(path:, scope:, root:) # rubocop:disable Lint/UnusedMethodArgument
|
|
71
|
+
states = collect_states(root)
|
|
72
|
+
return [] if states.empty?
|
|
73
|
+
|
|
74
|
+
validate_transitions(path, root, states)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
private
|
|
78
|
+
|
|
79
|
+
# Pass 1 — every `state :foo` declaration inside a
|
|
80
|
+
# `<dsl_method> do ... end` block on the file. Returns a
|
|
81
|
+
# frozen Set of state name Symbols.
|
|
82
|
+
def collect_states(root)
|
|
83
|
+
states = Set.new
|
|
84
|
+
walk(root) do |node|
|
|
85
|
+
next unless dsl_call?(node)
|
|
86
|
+
|
|
87
|
+
walk(node.block) do |inner|
|
|
88
|
+
next unless state_declaration?(inner)
|
|
89
|
+
|
|
90
|
+
sym = literal_symbol_arg(inner, 0)
|
|
91
|
+
states << sym if sym
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
states.freeze
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Pass 2 — every `<transition_method>(:sym)` call.
|
|
98
|
+
def validate_transitions(path, root, states)
|
|
99
|
+
diagnostics = []
|
|
100
|
+
walk(root) do |node|
|
|
101
|
+
next unless transition_call?(node)
|
|
102
|
+
|
|
103
|
+
sym = literal_symbol_arg(node, 0)
|
|
104
|
+
next if sym.nil? # not a literal — defer to runtime
|
|
105
|
+
|
|
106
|
+
diagnostics << build_diagnostic(path, node, sym, states)
|
|
107
|
+
end
|
|
108
|
+
diagnostics
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def build_diagnostic(path, node, sym, states)
|
|
112
|
+
if states.include?(sym)
|
|
113
|
+
diagnostic(
|
|
114
|
+
path, node,
|
|
115
|
+
severity: :info,
|
|
116
|
+
rule: "known-state",
|
|
117
|
+
message: "#{@transition_method}(:#{sym}) — declared state"
|
|
118
|
+
)
|
|
119
|
+
else
|
|
120
|
+
hint = did_you_mean(sym, states)
|
|
121
|
+
message = "unknown state :#{sym}"
|
|
122
|
+
message += " (did you mean :#{hint}?)" if hint
|
|
123
|
+
diagnostic(path, node, severity: :error, rule: "unknown-state", message: message)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def dsl_call?(node)
|
|
128
|
+
node.is_a?(Prism::CallNode) &&
|
|
129
|
+
node.name == @dsl_method &&
|
|
130
|
+
node.block
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def state_declaration?(node)
|
|
134
|
+
node.is_a?(Prism::CallNode) &&
|
|
135
|
+
node.name == @state_method &&
|
|
136
|
+
!node.arguments.nil?
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def transition_call?(node)
|
|
140
|
+
node.is_a?(Prism::CallNode) &&
|
|
141
|
+
node.name == @transition_method &&
|
|
142
|
+
!node.arguments.nil?
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def literal_symbol_arg(call, index)
|
|
146
|
+
node = call.arguments.arguments[index]
|
|
147
|
+
return nil unless node.is_a?(Prism::SymbolNode)
|
|
148
|
+
|
|
149
|
+
node.unescaped.to_sym
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def walk(node, &)
|
|
153
|
+
return if node.nil?
|
|
154
|
+
|
|
155
|
+
yield node
|
|
156
|
+
node.compact_child_nodes.each { |child| walk(child, &) }
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def did_you_mean(name, states)
|
|
160
|
+
target = name.to_s
|
|
161
|
+
best = nil
|
|
162
|
+
best_distance = DID_YOU_MEAN_DISTANCE + 1
|
|
163
|
+
states.each do |state|
|
|
164
|
+
distance = levenshtein(target, state.to_s)
|
|
165
|
+
if distance < best_distance
|
|
166
|
+
best = state
|
|
167
|
+
best_distance = distance
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
best
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def levenshtein(a, b) # rubocop:disable Naming/MethodParameterName
|
|
174
|
+
return b.length if a.empty?
|
|
175
|
+
return a.length if b.empty?
|
|
176
|
+
|
|
177
|
+
rows = Array.new(a.length + 1) { |_i| Array.new(b.length + 1, 0) }
|
|
178
|
+
(0..a.length).each { |i| rows[i][0] = i }
|
|
179
|
+
(0..b.length).each { |j| rows[0][j] = j }
|
|
180
|
+
|
|
181
|
+
(1..a.length).each do |i|
|
|
182
|
+
(1..b.length).each do |j|
|
|
183
|
+
cost = a[i - 1] == b[j - 1] ? 0 : 1
|
|
184
|
+
rows[i][j] = [
|
|
185
|
+
rows[i - 1][j] + 1,
|
|
186
|
+
rows[i][j - 1] + 1,
|
|
187
|
+
rows[i - 1][j - 1] + cost
|
|
188
|
+
].min
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
rows[a.length][b.length]
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def diagnostic(path, node, severity:, rule:, message:)
|
|
195
|
+
location = node.location
|
|
196
|
+
Rigor::Analysis::Diagnostic.new(
|
|
197
|
+
path: path,
|
|
198
|
+
line: location.start_line,
|
|
199
|
+
column: location.start_column + 1,
|
|
200
|
+
message: message,
|
|
201
|
+
severity: severity,
|
|
202
|
+
rule: rule
|
|
203
|
+
)
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
Rigor::Plugin.register(Statesman)
|
|
208
|
+
end
|
|
209
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Gem entry point. Required by Rigor's plugin loader when
|
|
4
|
+
# `.rigor.yml` lists `rigor-statesman` under `plugins:`. The
|
|
5
|
+
# loader expects this `require` to side-effect a call to
|
|
6
|
+
# `Rigor::Plugin.register`, which the body of
|
|
7
|
+
# `lib/rigor/plugin/statesman.rb` performs at load time.
|
|
8
|
+
require_relative "rigor/plugin/statesman"
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rigor/plugin"
|
|
4
|
+
|
|
5
|
+
module Rigor
|
|
6
|
+
module Plugin
|
|
7
|
+
# Example plugin: ships the TypeScript-canonical utility-type
|
|
8
|
+
# aliases (`Pick<T, K>`, `Omit<T, K>`, `Partial<T>`,
|
|
9
|
+
# `Required<T>`, `Readonly<T>`) as opt-in vocabulary that
|
|
10
|
+
# resolves to the Rigor-canonical shape-projection type
|
|
11
|
+
# functions introduced in ADR-13.
|
|
12
|
+
#
|
|
13
|
+
# Background. `docs/type-specification/imported-built-in-types.md`
|
|
14
|
+
# § "Deferred or rejected imports" deliberately rejects
|
|
15
|
+
# TypeScript-canonical names from the Rigor core surface: the
|
|
16
|
+
# core stays RBS-canonical per ADR-0 / ADR-1, and the shape
|
|
17
|
+
# semantics live in core under `pick_of[T, K]` /
|
|
18
|
+
# `omit_of[T, K]` / `partial_of[T]` / `required_of[T]` /
|
|
19
|
+
# `readonly_of[T]` (added in ADR-13 slice 4). This plugin
|
|
20
|
+
# ships the TS spellings as an opt-in translation layer for
|
|
21
|
+
# users migrating from TypeScript / Sorbet / Flow-style RBI.
|
|
22
|
+
#
|
|
23
|
+
# Off by default — users add the gem to their `.rigor.yml`
|
|
24
|
+
# plugins list to enable.
|
|
25
|
+
#
|
|
26
|
+
# @example .rigor.yml
|
|
27
|
+
# plugins:
|
|
28
|
+
# - gem: rigor-typescript-utility-types
|
|
29
|
+
#
|
|
30
|
+
# Once loaded, an RBS::Extended payload such as
|
|
31
|
+
# `%a{rigor:v1:return: Pick[Foo, :a | :b]}` resolves through
|
|
32
|
+
# the chain: the parser builds a `Generic("Pick", …)` AST,
|
|
33
|
+
# the registry / built-in parametric builders decline, the
|
|
34
|
+
# chain consults `Resolvers::Pick`, which recursively
|
|
35
|
+
# resolves the two arguments to Rigor types and calls
|
|
36
|
+
# `Type::Combinator.pick_of` on them.
|
|
37
|
+
#
|
|
38
|
+
# ## Translation table
|
|
39
|
+
#
|
|
40
|
+
# | TypeScript spelling | Rigor core call |
|
|
41
|
+
# | --- | --- |
|
|
42
|
+
# | `Pick<T, K>` | `Type::Combinator.pick_of(T, K)` |
|
|
43
|
+
# | `Omit<T, K>` | `Type::Combinator.omit_of(T, K)` |
|
|
44
|
+
# | `Partial<T>` | `Type::Combinator.partial_of(T)` |
|
|
45
|
+
# | `Required<T>` | `Type::Combinator.required_of(T)` |
|
|
46
|
+
# | `Readonly<T>` | `Type::Combinator.readonly_of(T)` |
|
|
47
|
+
#
|
|
48
|
+
# ## Deferred TypeScript utility names
|
|
49
|
+
#
|
|
50
|
+
# `Parameters<F>` / `ReturnType<F>` / `InstanceType<C>` /
|
|
51
|
+
# `Awaited<P>` / `Uppercase<S>` / `Lowercase<S>` /
|
|
52
|
+
# `Capitalize<S>` / `Uncapitalize<S>` / `ThisParameterType<F>`
|
|
53
|
+
# / `OmitThisParameter<F>` / `ConstructorParameters<C>` /
|
|
54
|
+
# `NoInfer<T>` are NOT mapped today. The plugin returns `nil`
|
|
55
|
+
# from `#resolve` for those heads, leaving the parser's
|
|
56
|
+
# default Nominal-fallback to produce `Nominal[ReturnType, …]`
|
|
57
|
+
# etc. Function-type projection operators (`params_of[F]` /
|
|
58
|
+
# `return_of[F]`) and class projections (`instance_type[C]`)
|
|
59
|
+
# would unlock these — they remain deferred in core.
|
|
60
|
+
class TypescriptUtilityTypes < Rigor::Plugin::Base
|
|
61
|
+
module Resolvers
|
|
62
|
+
# Common helper: extract a single-arg utility-type Generic
|
|
63
|
+
# whose head matches `name`. Returns the resolved
|
|
64
|
+
# argument's `Rigor::Type` or `nil` (so the chain falls
|
|
65
|
+
# through).
|
|
66
|
+
module SingleArg
|
|
67
|
+
def self.resolve(node, scope, name)
|
|
68
|
+
return nil unless node.is_a?(Rigor::TypeNode::Generic)
|
|
69
|
+
return nil unless node.head == name
|
|
70
|
+
return nil unless node.args.size == 1
|
|
71
|
+
|
|
72
|
+
scope.resolver.resolve(node.args[0], scope)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Common helper for two-arg utility types.
|
|
77
|
+
module TwoArg
|
|
78
|
+
def self.resolve(node, scope, name)
|
|
79
|
+
return nil unless node.is_a?(Rigor::TypeNode::Generic)
|
|
80
|
+
return nil unless node.head == name
|
|
81
|
+
return nil unless node.args.size == 2
|
|
82
|
+
|
|
83
|
+
[scope.resolver.resolve(node.args[0], scope),
|
|
84
|
+
scope.resolver.resolve(node.args[1], scope)]
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# `Pick<T, K>` → `pick_of[T, K]`.
|
|
89
|
+
class Pick < Rigor::Plugin::TypeNodeResolver
|
|
90
|
+
def resolve(node, scope)
|
|
91
|
+
resolved = TwoArg.resolve(node, scope, "Pick")
|
|
92
|
+
return nil if resolved.nil?
|
|
93
|
+
|
|
94
|
+
t_type, k_type = resolved
|
|
95
|
+
return nil if t_type.nil? || k_type.nil?
|
|
96
|
+
|
|
97
|
+
Rigor::Type::Combinator.pick_of(t_type, k_type)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# `Omit<T, K>` → `omit_of[T, K]`.
|
|
102
|
+
class Omit < Rigor::Plugin::TypeNodeResolver
|
|
103
|
+
def resolve(node, scope)
|
|
104
|
+
resolved = TwoArg.resolve(node, scope, "Omit")
|
|
105
|
+
return nil if resolved.nil?
|
|
106
|
+
|
|
107
|
+
t_type, k_type = resolved
|
|
108
|
+
return nil if t_type.nil? || k_type.nil?
|
|
109
|
+
|
|
110
|
+
Rigor::Type::Combinator.omit_of(t_type, k_type)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# `Partial<T>` → `partial_of[T]`.
|
|
115
|
+
class Partial < Rigor::Plugin::TypeNodeResolver
|
|
116
|
+
def resolve(node, scope)
|
|
117
|
+
t_type = SingleArg.resolve(node, scope, "Partial")
|
|
118
|
+
return nil if t_type.nil?
|
|
119
|
+
|
|
120
|
+
Rigor::Type::Combinator.partial_of(t_type)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# `Required<T>` → `required_of[T]`.
|
|
125
|
+
class Required < Rigor::Plugin::TypeNodeResolver
|
|
126
|
+
def resolve(node, scope)
|
|
127
|
+
t_type = SingleArg.resolve(node, scope, "Required")
|
|
128
|
+
return nil if t_type.nil?
|
|
129
|
+
|
|
130
|
+
Rigor::Type::Combinator.required_of(t_type)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# `Readonly<T>` → `readonly_of[T]`.
|
|
135
|
+
class Readonly < Rigor::Plugin::TypeNodeResolver
|
|
136
|
+
def resolve(node, scope)
|
|
137
|
+
t_type = SingleArg.resolve(node, scope, "Readonly")
|
|
138
|
+
return nil if t_type.nil?
|
|
139
|
+
|
|
140
|
+
Rigor::Type::Combinator.readonly_of(t_type)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
manifest(
|
|
146
|
+
id: "typescript-utility-types",
|
|
147
|
+
version: "0.1.0",
|
|
148
|
+
description: "Maps TypeScript-canonical utility-type aliases " \
|
|
149
|
+
"(Pick, Omit, Partial, Required, Readonly) onto the " \
|
|
150
|
+
"Rigor-canonical shape-projection type functions.",
|
|
151
|
+
type_node_resolvers: [
|
|
152
|
+
Resolvers::Pick.new,
|
|
153
|
+
Resolvers::Omit.new,
|
|
154
|
+
Resolvers::Partial.new,
|
|
155
|
+
Resolvers::Required.new,
|
|
156
|
+
Resolvers::Readonly.new
|
|
157
|
+
]
|
|
158
|
+
)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
register(TypescriptUtilityTypes)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Gem entry point. Required by Rigor's plugin loader when
|
|
4
|
+
# `.rigor.yml` lists `rigor-typescript-utility-types` under
|
|
5
|
+
# `plugins:`. The loader expects this `require` to side-effect
|
|
6
|
+
# a call to `Rigor::Plugin.register`, which the body of
|
|
7
|
+
# `lib/rigor/plugin/typescript_utility_types.rb` performs at
|
|
8
|
+
# load time.
|
|
9
|
+
require_relative "rigor/plugin/typescript_utility_types"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rigortype
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.11
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rigor contributors
|
|
@@ -476,6 +476,125 @@ files:
|
|
|
476
476
|
- lib/rigor/type_node/symbol_literal.rb
|
|
477
477
|
- lib/rigor/type_node/union.rb
|
|
478
478
|
- lib/rigor/version.rb
|
|
479
|
+
- plugins/rigor-actioncable/lib/rigor-actioncable.rb
|
|
480
|
+
- plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb
|
|
481
|
+
- plugins/rigor-actioncable/lib/rigor/plugin/actioncable/analyzer.rb
|
|
482
|
+
- plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb
|
|
483
|
+
- plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb
|
|
484
|
+
- plugins/rigor-actionmailer/lib/rigor-actionmailer.rb
|
|
485
|
+
- plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb
|
|
486
|
+
- plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/analyzer.rb
|
|
487
|
+
- plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb
|
|
488
|
+
- plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb
|
|
489
|
+
- plugins/rigor-actionpack/lib/rigor-actionpack.rb
|
|
490
|
+
- plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb
|
|
491
|
+
- plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb
|
|
492
|
+
- plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_discoverer.rb
|
|
493
|
+
- plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb
|
|
494
|
+
- plugins/rigor-activejob/lib/rigor-activejob.rb
|
|
495
|
+
- plugins/rigor-activejob/lib/rigor/plugin/activejob.rb
|
|
496
|
+
- plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb
|
|
497
|
+
- plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb
|
|
498
|
+
- plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb
|
|
499
|
+
- plugins/rigor-activerecord/lib/rigor-activerecord.rb
|
|
500
|
+
- plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb
|
|
501
|
+
- plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb
|
|
502
|
+
- plugins/rigor-activerecord/lib/rigor/plugin/activerecord/inflector.rb
|
|
503
|
+
- plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb
|
|
504
|
+
- plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb
|
|
505
|
+
- plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb
|
|
506
|
+
- plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_table.rb
|
|
507
|
+
- plugins/rigor-activerecord/sig/active_record/relation.rbs
|
|
508
|
+
- plugins/rigor-activestorage/lib/rigor-activestorage.rb
|
|
509
|
+
- plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb
|
|
510
|
+
- plugins/rigor-activestorage/lib/rigor/plugin/activestorage/analyzer.rb
|
|
511
|
+
- plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_discoverer.rb
|
|
512
|
+
- plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_index.rb
|
|
513
|
+
- plugins/rigor-activesupport-core-ext/lib/rigor-activesupport-core-ext.rb
|
|
514
|
+
- plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb
|
|
515
|
+
- plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs
|
|
516
|
+
- plugins/rigor-devise/lib/rigor-devise.rb
|
|
517
|
+
- plugins/rigor-devise/lib/rigor/plugin/devise.rb
|
|
518
|
+
- plugins/rigor-dry-schema/lib/rigor-dry-schema.rb
|
|
519
|
+
- plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema.rb
|
|
520
|
+
- plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb
|
|
521
|
+
- plugins/rigor-dry-struct/lib/rigor-dry-struct.rb
|
|
522
|
+
- plugins/rigor-dry-struct/lib/rigor/plugin/dry_struct.rb
|
|
523
|
+
- plugins/rigor-dry-types/lib/rigor-dry-types.rb
|
|
524
|
+
- plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb
|
|
525
|
+
- plugins/rigor-dry-types/lib/rigor/plugin/dry_types/alias_scanner.rb
|
|
526
|
+
- plugins/rigor-dry-validation/lib/rigor-dry-validation.rb
|
|
527
|
+
- plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb
|
|
528
|
+
- plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/contract_scanner.rb
|
|
529
|
+
- plugins/rigor-dry-validation/sig/dry_validation.rbs
|
|
530
|
+
- plugins/rigor-factorybot/lib/rigor-factorybot.rb
|
|
531
|
+
- plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb
|
|
532
|
+
- plugins/rigor-factorybot/lib/rigor/plugin/factorybot/analyzer.rb
|
|
533
|
+
- plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb
|
|
534
|
+
- plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_index.rb
|
|
535
|
+
- plugins/rigor-graphql/lib/rigor-graphql.rb
|
|
536
|
+
- plugins/rigor-graphql/lib/rigor/plugin/graphql.rb
|
|
537
|
+
- plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb
|
|
538
|
+
- plugins/rigor-hanami/lib/rigor-hanami.rb
|
|
539
|
+
- plugins/rigor-hanami/lib/rigor/plugin/hanami.rb
|
|
540
|
+
- plugins/rigor-hanami/lib/rigor/plugin/hanami/action_checker.rb
|
|
541
|
+
- plugins/rigor-hanami/sig/hanami_action.rbs
|
|
542
|
+
- plugins/rigor-minitest/lib/rigor-minitest.rb
|
|
543
|
+
- plugins/rigor-minitest/lib/rigor/plugin/minitest.rb
|
|
544
|
+
- plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb
|
|
545
|
+
- plugins/rigor-pundit/lib/rigor-pundit.rb
|
|
546
|
+
- plugins/rigor-pundit/lib/rigor/plugin/pundit.rb
|
|
547
|
+
- plugins/rigor-pundit/lib/rigor/plugin/pundit/analyzer.rb
|
|
548
|
+
- plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb
|
|
549
|
+
- plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_index.rb
|
|
550
|
+
- plugins/rigor-rails-i18n/lib/rigor-rails-i18n.rb
|
|
551
|
+
- plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb
|
|
552
|
+
- plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb
|
|
553
|
+
- plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb
|
|
554
|
+
- plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb
|
|
555
|
+
- plugins/rigor-rails-routes/lib/rigor-rails-routes.rb
|
|
556
|
+
- plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb
|
|
557
|
+
- plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb
|
|
558
|
+
- plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_table.rb
|
|
559
|
+
- plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb
|
|
560
|
+
- plugins/rigor-rails/lib/rigor-rails.rb
|
|
561
|
+
- plugins/rigor-rbs-inline/lib/rigor-rbs-inline.rb
|
|
562
|
+
- plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb
|
|
563
|
+
- plugins/rigor-rspec-rails/lib/rigor-rspec-rails.rb
|
|
564
|
+
- plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails.rb
|
|
565
|
+
- plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/have_http_status_analyzer.rb
|
|
566
|
+
- plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/http_status_codes.rb
|
|
567
|
+
- plugins/rigor-rspec/lib/rigor-rspec.rb
|
|
568
|
+
- plugins/rigor-rspec/lib/rigor/plugin/rspec.rb
|
|
569
|
+
- plugins/rigor-rspec/lib/rigor/plugin/rspec/analyzer.rb
|
|
570
|
+
- plugins/rigor-rspec/lib/rigor/plugin/rspec/let_scope_index.rb
|
|
571
|
+
- plugins/rigor-rspec/lib/rigor/plugin/rspec/let_type_resolver.rb
|
|
572
|
+
- plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb
|
|
573
|
+
- plugins/rigor-rspec/lib/rigor/plugin/rspec/scope_walker.rb
|
|
574
|
+
- plugins/rigor-shoulda-matchers/lib/rigor-shoulda-matchers.rb
|
|
575
|
+
- plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers.rb
|
|
576
|
+
- plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb
|
|
577
|
+
- plugins/rigor-sidekiq/lib/rigor-sidekiq.rb
|
|
578
|
+
- plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb
|
|
579
|
+
- plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/analyzer.rb
|
|
580
|
+
- plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_discoverer.rb
|
|
581
|
+
- plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_index.rb
|
|
582
|
+
- plugins/rigor-sinatra/lib/rigor-sinatra.rb
|
|
583
|
+
- plugins/rigor-sinatra/lib/rigor/plugin/sinatra.rb
|
|
584
|
+
- plugins/rigor-sorbet/lib/rigor-sorbet.rb
|
|
585
|
+
- plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb
|
|
586
|
+
- plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb
|
|
587
|
+
- plugins/rigor-sorbet/lib/rigor/plugin/sorbet/assertion_recognizer.rb
|
|
588
|
+
- plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb
|
|
589
|
+
- plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb
|
|
590
|
+
- plugins/rigor-sorbet/lib/rigor/plugin/sorbet/method_signature.rb
|
|
591
|
+
- plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb
|
|
592
|
+
- plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sigil_detector.rb
|
|
593
|
+
- plugins/rigor-sorbet/lib/rigor/plugin/sorbet/type_translator.rb
|
|
594
|
+
- plugins/rigor-statesman/lib/rigor-statesman.rb
|
|
595
|
+
- plugins/rigor-statesman/lib/rigor/plugin/statesman.rb
|
|
596
|
+
- plugins/rigor-typescript-utility-types/lib/rigor-typescript-utility-types.rb
|
|
597
|
+
- plugins/rigor-typescript-utility-types/lib/rigor/plugin/typescript_utility_types.rb
|
|
479
598
|
- sig/rigor.rbs
|
|
480
599
|
- sig/rigor/analysis/baseline.rbs
|
|
481
600
|
- sig/rigor/analysis/check_rules/always_truthy_condition_collector.rbs
|
|
@@ -524,6 +643,35 @@ metadata:
|
|
|
524
643
|
rdoc_options: []
|
|
525
644
|
require_paths:
|
|
526
645
|
- lib
|
|
646
|
+
- plugins/rigor-actioncable/lib
|
|
647
|
+
- plugins/rigor-actionmailer/lib
|
|
648
|
+
- plugins/rigor-actionpack/lib
|
|
649
|
+
- plugins/rigor-activejob/lib
|
|
650
|
+
- plugins/rigor-activerecord/lib
|
|
651
|
+
- plugins/rigor-activestorage/lib
|
|
652
|
+
- plugins/rigor-activesupport-core-ext/lib
|
|
653
|
+
- plugins/rigor-devise/lib
|
|
654
|
+
- plugins/rigor-dry-schema/lib
|
|
655
|
+
- plugins/rigor-dry-struct/lib
|
|
656
|
+
- plugins/rigor-dry-types/lib
|
|
657
|
+
- plugins/rigor-dry-validation/lib
|
|
658
|
+
- plugins/rigor-factorybot/lib
|
|
659
|
+
- plugins/rigor-graphql/lib
|
|
660
|
+
- plugins/rigor-hanami/lib
|
|
661
|
+
- plugins/rigor-minitest/lib
|
|
662
|
+
- plugins/rigor-pundit/lib
|
|
663
|
+
- plugins/rigor-rails/lib
|
|
664
|
+
- plugins/rigor-rails-i18n/lib
|
|
665
|
+
- plugins/rigor-rails-routes/lib
|
|
666
|
+
- plugins/rigor-rbs-inline/lib
|
|
667
|
+
- plugins/rigor-rspec/lib
|
|
668
|
+
- plugins/rigor-rspec-rails/lib
|
|
669
|
+
- plugins/rigor-shoulda-matchers/lib
|
|
670
|
+
- plugins/rigor-sidekiq/lib
|
|
671
|
+
- plugins/rigor-sinatra/lib
|
|
672
|
+
- plugins/rigor-sorbet/lib
|
|
673
|
+
- plugins/rigor-statesman/lib
|
|
674
|
+
- plugins/rigor-typescript-utility-types/lib
|
|
527
675
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
528
676
|
requirements:
|
|
529
677
|
- - ">="
|