tapioca 0.11.8 → 0.11.9

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +116 -49
  3. data/lib/tapioca/cli.rb +76 -67
  4. data/lib/tapioca/commands/{dsl.rb → abstract_dsl.rb} +32 -78
  5. data/lib/tapioca/commands/{gem.rb → abstract_gem.rb} +26 -93
  6. data/lib/tapioca/commands/annotations.rb +9 -7
  7. data/lib/tapioca/commands/check_shims.rb +2 -0
  8. data/lib/tapioca/commands/command.rb +9 -2
  9. data/lib/tapioca/commands/configure.rb +2 -2
  10. data/lib/tapioca/commands/dsl_compiler_list.rb +31 -0
  11. data/lib/tapioca/commands/dsl_generate.rb +40 -0
  12. data/lib/tapioca/commands/dsl_verify.rb +25 -0
  13. data/lib/tapioca/commands/gem_generate.rb +51 -0
  14. data/lib/tapioca/commands/gem_sync.rb +37 -0
  15. data/lib/tapioca/commands/gem_verify.rb +36 -0
  16. data/lib/tapioca/commands/require.rb +2 -0
  17. data/lib/tapioca/commands/todo.rb +21 -2
  18. data/lib/tapioca/commands.rb +8 -2
  19. data/lib/tapioca/dsl/compiler.rb +8 -4
  20. data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +3 -1
  21. data/lib/tapioca/dsl/compilers/active_model_validations_confirmation.rb +94 -0
  22. data/lib/tapioca/dsl/compilers/active_record_columns.rb +19 -9
  23. data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +3 -2
  24. data/lib/tapioca/dsl/compilers/active_support_concern.rb +1 -1
  25. data/lib/tapioca/dsl/compilers/graphql_input_object.rb +1 -1
  26. data/lib/tapioca/dsl/compilers/graphql_mutation.rb +9 -2
  27. data/lib/tapioca/dsl/compilers/json_api_client_resource.rb +208 -0
  28. data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +20 -4
  29. data/lib/tapioca/dsl/helpers/graphql_type_helper.rb +20 -3
  30. data/lib/tapioca/dsl/pipeline.rb +6 -4
  31. data/lib/tapioca/gem/pipeline.rb +103 -36
  32. data/lib/tapioca/gemfile.rb +13 -7
  33. data/lib/tapioca/helpers/git_attributes.rb +34 -0
  34. data/lib/tapioca/helpers/test/template.rb +4 -4
  35. data/lib/tapioca/internal.rb +1 -0
  36. data/lib/tapioca/loaders/dsl.rb +11 -1
  37. data/lib/tapioca/sorbet_ext/generic_name_patch.rb +0 -27
  38. data/lib/tapioca/static/symbol_loader.rb +9 -8
  39. data/lib/tapioca/version.rb +1 -1
  40. metadata +19 -10
@@ -50,6 +50,8 @@ module Tapioca
50
50
  @root
51
51
  end
52
52
 
53
+ # Events handling
54
+
53
55
  sig { params(symbol: String).void }
54
56
  def push_symbol(symbol)
55
57
  @events << Gem::SymbolFound.new(symbol)
@@ -98,6 +100,8 @@ module Tapioca
98
100
  @events << Gem::MethodNodeAdded.new(symbol, constant, method, node, signature, parameters)
99
101
  end
100
102
 
103
+ # Constants and properties filtering
104
+
101
105
  sig { params(symbol_name: String).returns(T::Boolean) }
102
106
  def symbol_in_payload?(symbol_name)
103
107
  symbol_name = symbol_name[2..-1] if symbol_name.start_with?("::")
@@ -106,16 +110,27 @@ module Tapioca
106
110
  @payload_symbols.include?(symbol_name)
107
111
  end
108
112
 
113
+ # this looks something like:
114
+ # "(eval at /path/to/file.rb:123)"
115
+ # and we are just interested in the "/path/to/file.rb" part
116
+ EVAL_SOURCE_FILE_PATTERN = T.let(/\(eval at (.+):\d+\)/, Regexp)
117
+
109
118
  sig { params(name: T.any(String, Symbol)).returns(T::Boolean) }
110
119
  def constant_in_gem?(name)
111
120
  return true unless Object.respond_to?(:const_source_location)
112
121
 
113
- source_location, _ = Object.const_source_location(name)
114
- return true unless source_location
122
+ source_file, _ = Object.const_source_location(name)
123
+ return true unless source_file
115
124
  # If the source location of the constant is "(eval)", all bets are off.
116
- return true if source_location == "(eval)"
125
+ return true if source_file == "(eval)"
117
126
 
118
- gem.contains_path?(source_location)
127
+ # Ruby 3.3 adds automatic definition of source location for evals if
128
+ # `file` and `line` arguments are not provided. This results in the source
129
+ # file being something like `(eval at /path/to/file.rb:123)`. We try to parse
130
+ # this string to get the actual source file.
131
+ source_file = source_file.sub(EVAL_SOURCE_FILE_PATTERN, "\\1")
132
+
133
+ gem.contains_path?(source_file)
119
134
  end
120
135
 
121
136
  sig { params(method: UnboundMethod).returns(T::Boolean) }
@@ -126,6 +141,8 @@ module Tapioca
126
141
  @gem.contains_path?(source_location)
127
142
  end
128
143
 
144
+ # Helpers
145
+
129
146
  sig { params(constant: Module).returns(T.nilable(String)) }
130
147
  def name_of(constant)
131
148
  name = name_of_proxy_target(constant, super(class_of(constant)))
@@ -149,6 +166,8 @@ module Tapioca
149
166
  gem_symbols.union(engine_symbols)
150
167
  end
151
168
 
169
+ # Events handling
170
+
152
171
  sig { returns(Gem::Event) }
153
172
  def next_event
154
173
  T.must(@events.shift)
@@ -171,7 +190,7 @@ module Tapioca
171
190
  sig { params(event: Gem::SymbolFound).void }
172
191
  def on_symbol(event)
173
192
  symbol = event.symbol.delete_prefix("::")
174
- return if symbol_in_payload?(symbol) && !@bootstrap_symbols.include?(symbol)
193
+ return if skip_symbol?(symbol)
175
194
 
176
195
  constant = constantize(symbol)
177
196
  push_constant(symbol, constant) if Runtime::Reflection.constant_defined?(constant)
@@ -180,13 +199,7 @@ module Tapioca
180
199
  sig { params(event: Gem::ConstantFound).void.checked(:never) }
181
200
  def on_constant(event)
182
201
  name = event.symbol
183
-
184
- return if name.strip.empty?
185
- return if name.start_with?("#<")
186
- return if name.downcase == name
187
- return if alias_namespaced?(name)
188
-
189
- return if T::Enum === event.constant # T::Enum instances are defined via `compile_enums`
202
+ return if skip_constant?(name, event.constant)
190
203
 
191
204
  if event.is_a?(Gem::ForeignConstantFound)
192
205
  compile_foreign_constant(name, event.constant)
@@ -200,11 +213,17 @@ module Tapioca
200
213
  @node_listeners.each { |listener| listener.dispatch(event) }
201
214
  end
202
215
 
203
- # Compile
216
+ # Compiling
204
217
 
205
218
  sig { params(symbol: String, constant: Module).void }
206
219
  def compile_foreign_constant(symbol, constant)
207
- compile_module(symbol, constant, foreign_constant: true)
220
+ return if skip_foreign_constant?(symbol, constant)
221
+ return if seen?(symbol)
222
+
223
+ seen!(symbol)
224
+
225
+ scope = compile_scope(symbol, constant)
226
+ push_foreign_scope(symbol, constant, scope)
208
227
  end
209
228
 
210
229
  sig { params(symbol: String, constant: BasicObject).void.checked(:never) }
@@ -225,10 +244,9 @@ module Tapioca
225
244
  def compile_alias(name, constant)
226
245
  return if seen?(name)
227
246
 
228
- mark_seen(name)
247
+ seen!(name)
229
248
 
230
- return if symbol_in_payload?(name)
231
- return unless constant_in_gem?(name)
249
+ return if skip_alias?(name, constant)
232
250
 
233
251
  target = name_of(constant)
234
252
  # If target has no name, let's make it an anonymous class or module with `Class.new` or `Module.new`
@@ -247,10 +265,9 @@ module Tapioca
247
265
  def compile_object(name, value)
248
266
  return if seen?(name)
249
267
 
250
- mark_seen(name)
268
+ seen!(name)
251
269
 
252
- return if symbol_in_payload?(name)
253
- return unless constant_in_gem?(name)
270
+ return if skip_object?(name, value)
254
271
 
255
272
  klass = class_of(value)
256
273
 
@@ -279,29 +296,29 @@ module Tapioca
279
296
  @root << node
280
297
  end
281
298
 
282
- sig { params(name: String, constant: Module, foreign_constant: T::Boolean).void }
283
- def compile_module(name, constant, foreign_constant: false)
284
- return unless defined_in_gem?(constant, strict: false) || foreign_constant
285
- return if Tapioca::TypeVariableModule === constant
299
+ sig { params(name: String, constant: Module).void }
300
+ def compile_module(name, constant)
301
+ return if skip_module?(name, constant)
286
302
  return if seen?(name)
287
303
 
288
- mark_seen(name)
304
+ seen!(name)
289
305
 
290
- scope =
291
- if constant.is_a?(Class)
292
- superclass = compile_superclass(constant)
293
- RBI::Class.new(name, superclass_name: superclass)
294
- else
295
- RBI::Module.new(name)
296
- end
306
+ scope = compile_scope(name, constant)
307
+ push_scope(name, constant, scope)
308
+ end
297
309
 
298
- if foreign_constant
299
- push_foreign_scope(name, constant, scope)
310
+ sig { params(name: String, constant: Module).returns(RBI::Scope) }
311
+ def compile_scope(name, constant)
312
+ scope = if constant.is_a?(Class)
313
+ superclass = compile_superclass(constant)
314
+ RBI::Class.new(name, superclass_name: superclass)
300
315
  else
301
- push_scope(name, constant, scope)
316
+ RBI::Module.new(name)
302
317
  end
303
318
 
304
319
  @root << scope
320
+
321
+ scope
305
322
  end
306
323
 
307
324
  sig { params(constant: T::Class[T.anything]).returns(T.nilable(String)) }
@@ -353,6 +370,54 @@ module Tapioca
353
370
  "::#{name}"
354
371
  end
355
372
 
373
+ # Constants and properties filtering
374
+
375
+ sig { params(name: String).returns(T::Boolean) }
376
+ def skip_symbol?(name)
377
+ symbol_in_payload?(name) && !@bootstrap_symbols.include?(name)
378
+ end
379
+
380
+ sig { params(name: String, constant: T.anything).returns(T::Boolean).checked(:never) }
381
+ def skip_constant?(name, constant)
382
+ return true if name.strip.empty?
383
+ return true if name.start_with?("#<")
384
+ return true if name.downcase == name
385
+ return true if alias_namespaced?(name)
386
+
387
+ return true if T::Enum === constant # T::Enum instances are defined via `compile_enums`
388
+
389
+ false
390
+ end
391
+
392
+ sig { params(name: String, constant: Module).returns(T::Boolean) }
393
+ def skip_alias?(name, constant)
394
+ return true if symbol_in_payload?(name)
395
+ return true unless constant_in_gem?(name)
396
+
397
+ false
398
+ end
399
+
400
+ sig { params(name: String, constant: BasicObject).returns(T::Boolean).checked(:never) }
401
+ def skip_object?(name, constant)
402
+ return true if symbol_in_payload?(name)
403
+ return true unless constant_in_gem?(name)
404
+
405
+ false
406
+ end
407
+
408
+ sig { params(name: String, constant: Module).returns(T::Boolean) }
409
+ def skip_foreign_constant?(name, constant)
410
+ Tapioca::TypeVariableModule === constant
411
+ end
412
+
413
+ sig { params(name: String, constant: Module).returns(T::Boolean) }
414
+ def skip_module?(name, constant)
415
+ return true unless defined_in_gem?(constant, strict: false)
416
+ return true if Tapioca::TypeVariableModule === constant
417
+
418
+ false
419
+ end
420
+
356
421
  sig { params(constant: Module, strict: T::Boolean).returns(T::Boolean) }
357
422
  def defined_in_gem?(constant, strict: true)
358
423
  files = get_file_candidates(constant)
@@ -385,7 +450,7 @@ module Tapioca
385
450
  end
386
451
 
387
452
  sig { params(name: String).void }
388
- def mark_seen(name)
453
+ def seen!(name)
389
454
  @seen.add(name)
390
455
  end
391
456
 
@@ -394,6 +459,8 @@ module Tapioca
394
459
  @seen.include?(name)
395
460
  end
396
461
 
462
+ # Helpers
463
+
397
464
  sig { params(constant: T.all(Module, T::Generic)).returns(String) }
398
465
  def generic_name_of(constant)
399
466
  type_name = T.must(constant.name)
@@ -156,6 +156,11 @@ module Tapioca
156
156
  @spec.name
157
157
  end
158
158
 
159
+ sig { returns(T::Array[::Gem::Dependency]) }
160
+ def dependencies
161
+ @spec.dependencies
162
+ end
163
+
159
164
  sig { returns(String) }
160
165
  def rbi_file_name
161
166
  "#{name}@#{version}.rbi"
@@ -230,13 +235,14 @@ module Tapioca
230
235
 
231
236
  sig { returns(Regexp) }
232
237
  def require_paths_prefix_matcher
233
- @require_paths_prefix_matcher = T.let(@require_paths_prefix_matcher, T.nilable(Regexp))
234
-
235
- @require_paths_prefix_matcher ||= begin
236
- require_paths = T.unsafe(@spec).require_paths
237
- prefix_matchers = require_paths.map { |rp| Regexp.new("^#{rp}/") }
238
- Regexp.union(prefix_matchers)
239
- end
238
+ @require_paths_prefix_matcher ||= T.let(
239
+ begin
240
+ require_paths = T.unsafe(@spec).require_paths
241
+ prefix_matchers = require_paths.map { |rp| Regexp.new("^#{rp}/") }
242
+ Regexp.union(prefix_matchers)
243
+ end,
244
+ T.nilable(Regexp),
245
+ )
240
246
  end
241
247
 
242
248
  sig { params(file: String).returns(Pathname) }
@@ -0,0 +1,34 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ class GitAttributes
5
+ class << self
6
+ extend T::Sig
7
+
8
+ sig { params(path: Pathname).void }
9
+ def create_generated_attribute_file(path)
10
+ create_gitattributes_file(path, <<~CONTENT)
11
+ **/*.rbi linguist-generated=true
12
+ CONTENT
13
+ end
14
+
15
+ sig { params(path: Pathname).void }
16
+ def create_vendored_attribute_file(path)
17
+ create_gitattributes_file(path, <<~CONTENT)
18
+ **/*.rbi linguist-vendored=true
19
+ CONTENT
20
+ end
21
+
22
+ private
23
+
24
+ sig { params(path: Pathname, content: String).void }
25
+ def create_gitattributes_file(path, content)
26
+ # We don't want to start creating folders, just to write
27
+ # the `.gitattributes` file. So, if the folder doesn't
28
+ # exist, we just return.
29
+ return unless path.exist?
30
+
31
+ File.write(path.join(".gitattributes"), content)
32
+ end
33
+ end
34
+ end
@@ -24,12 +24,12 @@ module Tapioca
24
24
  ::Gem::Requirement.new(selector).satisfied_by?(ActiveSupport.gem_version)
25
25
  end
26
26
 
27
- sig { params(src: String).returns(String) }
28
- def template(src)
27
+ sig { params(src: String, trim_mode: String).returns(String) }
28
+ def template(src, trim_mode: ">")
29
29
  erb = if ERB_SUPPORTS_KVARGS
30
- ::ERB.new(src, trim_mode: ">")
30
+ ::ERB.new(src, trim_mode: trim_mode)
31
31
  else
32
- ::ERB.new(src, nil, ">")
32
+ ::ERB.new(src, nil, trim_mode)
33
33
  end
34
34
 
35
35
  erb.result(binding)
@@ -28,6 +28,7 @@ require "yard-sorbet"
28
28
  require "tapioca/runtime/dynamic_mixin_compiler"
29
29
  require "tapioca/helpers/gem_helper"
30
30
 
31
+ require "tapioca/helpers/git_attributes"
31
32
  require "tapioca/helpers/sorbet_helper"
32
33
  require "tapioca/helpers/rbi_helper"
33
34
  require "tapioca/sorbet_ext/backcompat_patches"
@@ -46,7 +46,17 @@ module Tapioca
46
46
 
47
47
  sig { void }
48
48
  def load_dsl_extensions
49
- Dir["#{__dir__}/../dsl/extensions/*.rb"].sort.each { |f| require(f) }
49
+ say("Loading DSL extension classes... ")
50
+
51
+ Dir.glob(["#{@tapioca_path}/extensions/**/*.rb"]).each do |extension|
52
+ require File.expand_path(extension)
53
+ end
54
+
55
+ ::Gem.find_files("tapioca/dsl/extensions/*.rb").each do |extension|
56
+ require File.expand_path(extension)
57
+ end
58
+
59
+ say("Done", :green)
50
60
  end
51
61
 
52
62
  sig { void }
@@ -191,19 +191,6 @@ module Tapioca
191
191
  sig { returns(T.nilable(String)) }
192
192
  def name
193
193
  constant_name = super
194
-
195
- # This is a hack to work around modules under anonymous modules not having
196
- # names in 2.7: https://bugs.ruby-lang.org/issues/14895
197
- #
198
- # This happens when a type variable is declared under `class << self`, for
199
- # example.
200
- #
201
- # The workaround is to give the parent context a name, at which point, our
202
- # module gets bound to a name under that name, as well.
203
- unless constant_name
204
- constant_name = with_bound_name_pre_3_0 { super }
205
- end
206
-
207
194
  constant_name&.split("::")&.last
208
195
  end
209
196
 
@@ -247,20 +234,6 @@ module Tapioca
247
234
  -> { bounds }
248
235
  end
249
236
 
250
- sig do
251
- type_parameters(:Result)
252
- .params(block: T.proc.returns(T.type_parameter(:Result)))
253
- .returns(T.type_parameter(:Result))
254
- end
255
- def with_bound_name_pre_3_0(&block)
256
- require "securerandom"
257
- temp_name = "TYPE_VARIABLE_TRACKING_#{SecureRandom.hex}"
258
- self.class.const_set(temp_name, @context)
259
- block.call
260
- ensure
261
- self.class.send(:remove_const, temp_name) if temp_name
262
- end
263
-
264
237
  sig { returns(T::Hash[Symbol, T.untyped]) }
265
238
  def bounds
266
239
  @bounds ||= @bounds_proc.call
@@ -59,14 +59,15 @@ module Tapioca
59
59
 
60
60
  sig { returns(T::Array[T.class_of(Rails::Engine)]) }
61
61
  def engines
62
- @engines = T.let(@engines, T.nilable(T::Array[T.class_of(Rails::Engine)]))
63
-
64
- @engines ||= if Object.const_defined?("Rails::Engine")
65
- descendants_of(Object.const_get("Rails::Engine"))
66
- .reject(&:abstract_railtie?)
67
- else
68
- []
69
- end
62
+ @engines ||= T.let(
63
+ if Object.const_defined?("Rails::Engine")
64
+ descendants_of(Object.const_get("Rails::Engine"))
65
+ .reject(&:abstract_railtie?)
66
+ else
67
+ []
68
+ end,
69
+ T.nilable(T::Array[T.class_of(Rails::Engine)]),
70
+ )
70
71
  end
71
72
 
72
73
  sig { params(input: String, table_type: String).returns(String) }
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Tapioca
5
- VERSION = "0.11.8"
5
+ VERSION = "0.11.9"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tapioca
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.8
4
+ version: 0.11.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ufuk Kayserilioglu
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2023-07-12 00:00:00.000000000 Z
14
+ date: 2023-09-13 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -61,20 +61,20 @@ dependencies:
61
61
  requirements:
62
62
  - - "~>"
63
63
  - !ruby/object:Gem::Version
64
- version: 0.0.0
64
+ version: 0.1.0
65
65
  - - ">="
66
66
  - !ruby/object:Gem::Version
67
- version: 0.0.16
67
+ version: 0.1.0
68
68
  type: :runtime
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: 0.0.0
74
+ version: 0.1.0
75
75
  - - ">="
76
76
  - !ruby/object:Gem::Version
77
- version: 0.0.16
77
+ version: 0.1.0
78
78
  - !ruby/object:Gem::Dependency
79
79
  name: sorbet-static-and-runtime
80
80
  requirement: !ruby/object:Gem::Requirement
@@ -152,13 +152,19 @@ files:
152
152
  - lib/tapioca/bundler_ext/auto_require_hook.rb
153
153
  - lib/tapioca/cli.rb
154
154
  - lib/tapioca/commands.rb
155
+ - lib/tapioca/commands/abstract_dsl.rb
156
+ - lib/tapioca/commands/abstract_gem.rb
155
157
  - lib/tapioca/commands/annotations.rb
156
158
  - lib/tapioca/commands/check_shims.rb
157
159
  - lib/tapioca/commands/command.rb
158
160
  - lib/tapioca/commands/command_without_tracker.rb
159
161
  - lib/tapioca/commands/configure.rb
160
- - lib/tapioca/commands/dsl.rb
161
- - lib/tapioca/commands/gem.rb
162
+ - lib/tapioca/commands/dsl_compiler_list.rb
163
+ - lib/tapioca/commands/dsl_generate.rb
164
+ - lib/tapioca/commands/dsl_verify.rb
165
+ - lib/tapioca/commands/gem_generate.rb
166
+ - lib/tapioca/commands/gem_sync.rb
167
+ - lib/tapioca/commands/gem_verify.rb
162
168
  - lib/tapioca/commands/require.rb
163
169
  - lib/tapioca/commands/todo.rb
164
170
  - lib/tapioca/dsl.rb
@@ -170,6 +176,7 @@ files:
170
176
  - lib/tapioca/dsl/compilers/active_job.rb
171
177
  - lib/tapioca/dsl/compilers/active_model_attributes.rb
172
178
  - lib/tapioca/dsl/compilers/active_model_secure_password.rb
179
+ - lib/tapioca/dsl/compilers/active_model_validations_confirmation.rb
173
180
  - lib/tapioca/dsl/compilers/active_record_associations.rb
174
181
  - lib/tapioca/dsl/compilers/active_record_columns.rb
175
182
  - lib/tapioca/dsl/compilers/active_record_delegated_types.rb
@@ -188,6 +195,7 @@ files:
188
195
  - lib/tapioca/dsl/compilers/graphql_input_object.rb
189
196
  - lib/tapioca/dsl/compilers/graphql_mutation.rb
190
197
  - lib/tapioca/dsl/compilers/identity_cache.rb
198
+ - lib/tapioca/dsl/compilers/json_api_client_resource.rb
191
199
  - lib/tapioca/dsl/compilers/kredis.rb
192
200
  - lib/tapioca/dsl/compilers/mixed_in_class_attributes.rb
193
201
  - lib/tapioca/dsl/compilers/protobuf.rb
@@ -228,6 +236,7 @@ files:
228
236
  - lib/tapioca/helpers/config_helper.rb
229
237
  - lib/tapioca/helpers/env_helper.rb
230
238
  - lib/tapioca/helpers/gem_helper.rb
239
+ - lib/tapioca/helpers/git_attributes.rb
231
240
  - lib/tapioca/helpers/rbi_files_helper.rb
232
241
  - lib/tapioca/helpers/rbi_helper.rb
233
242
  - lib/tapioca/helpers/sorbet_helper.rb
@@ -276,14 +285,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
276
285
  requirements:
277
286
  - - ">="
278
287
  - !ruby/object:Gem::Version
279
- version: '2.7'
288
+ version: '3.0'
280
289
  required_rubygems_version: !ruby/object:Gem::Requirement
281
290
  requirements:
282
291
  - - ">="
283
292
  - !ruby/object:Gem::Version
284
293
  version: '0'
285
294
  requirements: []
286
- rubygems_version: 3.4.16
295
+ rubygems_version: 3.4.19
287
296
  signing_key:
288
297
  specification_version: 4
289
298
  summary: A Ruby Interface file generator for gems, core types and the Ruby standard