tapioca 0.4.13 → 0.4.18
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/Gemfile +0 -1
- data/README.md +4 -2
- data/exe/tapioca +17 -2
- data/lib/tapioca.rb +1 -27
- data/lib/tapioca/cli.rb +1 -108
- data/lib/tapioca/cli/main.rb +136 -0
- data/lib/tapioca/compilers/dsl/active_record_associations.rb +38 -7
- data/lib/tapioca/compilers/dsl/active_record_columns.rb +4 -4
- data/lib/tapioca/compilers/dsl/active_record_scope.rb +1 -1
- data/lib/tapioca/compilers/dsl/base.rb +1 -1
- data/lib/tapioca/compilers/dsl/url_helpers.rb +3 -3
- data/lib/tapioca/compilers/sorbet.rb +4 -1
- data/lib/tapioca/compilers/symbol_table/symbol_generator.rb +152 -49
- data/lib/tapioca/config.rb +1 -1
- data/lib/tapioca/config_builder.rb +7 -12
- data/lib/tapioca/gemfile.rb +30 -22
- data/lib/tapioca/generator.rb +127 -24
- data/lib/tapioca/generic_type_registry.rb +170 -0
- data/lib/tapioca/internal.rb +21 -0
- data/lib/tapioca/loader.rb +13 -2
- data/lib/tapioca/sorbet_ext/generic_name_patch.rb +66 -0
- data/lib/tapioca/sorbet_ext/name_patch.rb +16 -0
- data/lib/tapioca/version.rb +1 -1
- metadata +21 -2
@@ -123,7 +123,7 @@ module Tapioca
|
|
123
123
|
# Compile a Ruby method return type into a Parlour type
|
124
124
|
sig do
|
125
125
|
params(method_def: T.any(Method, UnboundMethod))
|
126
|
-
.returns(String)
|
126
|
+
.returns(T.nilable(String))
|
127
127
|
end
|
128
128
|
def compile_method_return_type_to_parlour(method_def)
|
129
129
|
signature = T::Private::Methods.signature_for_method(method_def)
|
@@ -89,7 +89,7 @@ module Tapioca
|
|
89
89
|
class UrlHelpers < Base
|
90
90
|
extend T::Sig
|
91
91
|
|
92
|
-
sig { override.params(root: Parlour::RbiGenerator::Namespace, constant:
|
92
|
+
sig { override.params(root: Parlour::RbiGenerator::Namespace, constant: Module).void }
|
93
93
|
def decorate(root, constant)
|
94
94
|
case constant
|
95
95
|
when GeneratedPathHelpersModule.singleton_class, GeneratedUrlHelpersModule.singleton_class
|
@@ -127,7 +127,7 @@ module Tapioca
|
|
127
127
|
|
128
128
|
private
|
129
129
|
|
130
|
-
sig { params(root: Parlour::RbiGenerator::Namespace, constant:
|
130
|
+
sig { params(root: Parlour::RbiGenerator::Namespace, constant: Module).void }
|
131
131
|
def generate_module_for(root, constant)
|
132
132
|
root.create_module(T.must(constant.name)) do |mod|
|
133
133
|
mod.create_include("::ActionDispatch::Routing::UrlFor")
|
@@ -143,7 +143,7 @@ module Tapioca
|
|
143
143
|
end
|
144
144
|
end
|
145
145
|
|
146
|
-
sig { params(mod: Parlour::RbiGenerator::Namespace, constant:
|
146
|
+
sig { params(mod: Parlour::RbiGenerator::Namespace, constant: Module, helper_module: Module).void }
|
147
147
|
def create_mixins_for(mod, constant, helper_module)
|
148
148
|
include_helper = constant.ancestors.include?(helper_module) || NON_DISCOVERABLE_INCLUDERS.include?(constant)
|
149
149
|
extend_helper = constant.singleton_class.ancestors.include?(helper_module)
|
@@ -8,6 +8,7 @@ module Tapioca
|
|
8
8
|
module Compilers
|
9
9
|
module Sorbet
|
10
10
|
SORBET = Pathname.new(Gem::Specification.find_by_name("sorbet-static").full_gem_path) / "libexec" / "sorbet"
|
11
|
+
EXE_PATH_ENV_VAR = "TAPIOCA_SORBET_EXE"
|
11
12
|
|
12
13
|
class << self
|
13
14
|
extend(T::Sig)
|
@@ -26,7 +27,9 @@ module Tapioca
|
|
26
27
|
|
27
28
|
sig { returns(String) }
|
28
29
|
def sorbet_path
|
29
|
-
SORBET
|
30
|
+
sorbet_path = ENV.fetch(EXE_PATH_ENV_VAR, SORBET)
|
31
|
+
sorbet_path = SORBET if sorbet_path.empty?
|
32
|
+
sorbet_path.to_s.shellescape
|
30
33
|
end
|
31
34
|
end
|
32
35
|
end
|
@@ -74,9 +74,15 @@ module Tapioca
|
|
74
74
|
compile(symbol, constant)
|
75
75
|
end
|
76
76
|
|
77
|
-
sig
|
78
|
-
|
79
|
-
|
77
|
+
sig do
|
78
|
+
params(
|
79
|
+
symbol: String,
|
80
|
+
inherit: T::Boolean,
|
81
|
+
namespace: Module
|
82
|
+
).returns(BasicObject).checked(:never)
|
83
|
+
end
|
84
|
+
def resolve_constant(symbol, inherit: false, namespace: Object)
|
85
|
+
namespace.const_get(symbol, inherit)
|
80
86
|
rescue NameError, LoadError, RuntimeError, ArgumentError, TypeError
|
81
87
|
nil
|
82
88
|
end
|
@@ -95,6 +101,7 @@ module Tapioca
|
|
95
101
|
return if alias_namespaced?(name)
|
96
102
|
return if seen?(name)
|
97
103
|
return unless parent_declares_constant?(name)
|
104
|
+
return if T::Enum === constant # T::Enum instances are defined via `compile_enums`
|
98
105
|
|
99
106
|
mark_seen(name)
|
100
107
|
compile_constant(name, constant)
|
@@ -141,9 +148,11 @@ module Tapioca
|
|
141
148
|
def compile_object(name, value)
|
142
149
|
return if symbol_ignored?(name)
|
143
150
|
klass = class_of(value)
|
144
|
-
|
151
|
+
klass_name = name_of(klass)
|
152
|
+
|
153
|
+
return if klass_name&.start_with?("T::Types::", "T::Private::")
|
145
154
|
|
146
|
-
type_name = public_module?(klass) &&
|
155
|
+
type_name = public_module?(klass) && klass_name || "T.untyped"
|
147
156
|
indented("#{name} = T.let(T.unsafe(nil), #{type_name})")
|
148
157
|
end
|
149
158
|
|
@@ -180,37 +189,38 @@ module Tapioca
|
|
180
189
|
|
181
190
|
[
|
182
191
|
compile_module_helpers(constant),
|
192
|
+
compile_type_variables(constant),
|
183
193
|
compile_mixins(constant),
|
184
194
|
compile_mixes_in_class_methods(constant),
|
185
195
|
compile_props(constant),
|
196
|
+
compile_enums(constant),
|
186
197
|
methods,
|
187
|
-
].select { |b| b
|
198
|
+
].select { |b| b && !b.empty? }.join("\n\n")
|
188
199
|
end
|
189
200
|
end
|
190
201
|
|
191
|
-
sig { params(constant: Module).returns(String) }
|
202
|
+
sig { params(constant: Module).returns(T.nilable(String)) }
|
192
203
|
def compile_module_helpers(constant)
|
193
204
|
abstract_type = T::Private::Abstract::Data.get(constant, :abstract_type)
|
194
205
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
end
|
206
|
+
helpers = []
|
207
|
+
helpers << indented("#{abstract_type}!") if abstract_type
|
208
|
+
helpers << indented("final!") if T::Private::Final.final_module?(constant)
|
209
|
+
helpers << indented("sealed!") if T::Private::Sealed.sealed_module?(constant)
|
210
|
+
|
211
|
+
return if helpers.empty?
|
212
|
+
|
213
|
+
helpers.join("\n")
|
204
214
|
end
|
205
215
|
|
206
|
-
sig { params(constant: Module).returns(String) }
|
216
|
+
sig { params(constant: Module).returns(T.nilable(String)) }
|
207
217
|
def compile_props(constant)
|
208
|
-
return
|
218
|
+
return unless T::Props::ClassMethods === constant
|
209
219
|
|
210
220
|
constant.props.map do |name, prop|
|
211
221
|
method = "prop"
|
212
222
|
method = "const" if prop.fetch(:immutable, false)
|
213
|
-
type = prop.fetch(:type_object, "T.untyped")
|
223
|
+
type = prop.fetch(:type_object, "T.untyped").to_s.gsub(".returns(<VOID>)", ".void")
|
214
224
|
|
215
225
|
if prop.key?(:default)
|
216
226
|
indented("#{method} :#{name}, #{type}, default: T.unsafe(nil)")
|
@@ -220,6 +230,23 @@ module Tapioca
|
|
220
230
|
end.join("\n")
|
221
231
|
end
|
222
232
|
|
233
|
+
sig { params(constant: Module).returns(T.nilable(String)) }
|
234
|
+
def compile_enums(constant)
|
235
|
+
return unless T::Enum > constant
|
236
|
+
|
237
|
+
enums = T.unsafe(constant).values.map do |enum_type|
|
238
|
+
enum_type.instance_variable_get(:@const_name).to_s
|
239
|
+
end
|
240
|
+
|
241
|
+
content = [
|
242
|
+
indented('enums do'),
|
243
|
+
*enums.map { |e| indented(" #{e} = new") }.join("\n"),
|
244
|
+
indented('end'),
|
245
|
+
]
|
246
|
+
|
247
|
+
content.join("\n")
|
248
|
+
end
|
249
|
+
|
223
250
|
sig { params(name: String, constant: Module).returns(T.nilable(String)) }
|
224
251
|
def compile_subconstants(name, constant)
|
225
252
|
output = constants_of(constant).sort.uniq.map do |constant_name|
|
@@ -234,11 +261,71 @@ module Tapioca
|
|
234
261
|
compile(symbol, subconstant)
|
235
262
|
end.compact
|
236
263
|
|
237
|
-
return
|
264
|
+
return if output.empty?
|
238
265
|
|
239
266
|
"\n" + output.join("\n\n")
|
240
267
|
end
|
241
268
|
|
269
|
+
sig { params(constant: Module).returns(T.nilable(String)) }
|
270
|
+
def compile_type_variables(constant)
|
271
|
+
type_variables = compile_type_variable_declarations(constant)
|
272
|
+
singleton_class_type_variables = compile_type_variable_declarations(singleton_class_of(constant))
|
273
|
+
|
274
|
+
return if !type_variables && !singleton_class_type_variables
|
275
|
+
|
276
|
+
type_variables += "\n" if type_variables
|
277
|
+
singleton_class_type_variables += "\n" if singleton_class_type_variables
|
278
|
+
|
279
|
+
[
|
280
|
+
type_variables,
|
281
|
+
singleton_class_type_variables,
|
282
|
+
].compact.join("\n").rstrip
|
283
|
+
end
|
284
|
+
|
285
|
+
sig { params(constant: Module).returns(T.nilable(String)) }
|
286
|
+
def compile_type_variable_declarations(constant)
|
287
|
+
with_indentation_for_constant(constant) do
|
288
|
+
# Try to find the type variables defined on this constant, bail if we can't
|
289
|
+
type_variables = GenericTypeRegistry.lookup_type_variables(constant)
|
290
|
+
return unless type_variables
|
291
|
+
|
292
|
+
# Create a map of subconstants (via their object ids) to their names.
|
293
|
+
# We need this later when we want to lookup the name of the registered type
|
294
|
+
# variable via the value of the type variable constant.
|
295
|
+
subconstant_to_name_lookup = constants_of(constant).map do |constant_name|
|
296
|
+
[
|
297
|
+
object_id_of(resolve_constant(constant_name.to_s, namespace: constant)),
|
298
|
+
constant_name,
|
299
|
+
]
|
300
|
+
end.to_h
|
301
|
+
|
302
|
+
# Map each type variable to its string representation.
|
303
|
+
#
|
304
|
+
# Each entry of `type_variables` maps an object_id to a String,
|
305
|
+
# and the order they are inserted into the hash is the order they should be
|
306
|
+
# defined in the source code.
|
307
|
+
#
|
308
|
+
# By looping over these entries and then getting the actual constant name
|
309
|
+
# from the `subconstant_to_name_lookup` we defined above, gives us all the
|
310
|
+
# information we need to serialize type variable definitions.
|
311
|
+
type_variable_declarations = type_variables.map do |type_variable_id, serialized_type_variable|
|
312
|
+
constant_name = subconstant_to_name_lookup[type_variable_id]
|
313
|
+
# Here, we know that constant_value will be an instance of
|
314
|
+
# T::Types::CustomTypeVariable, which knows how to serialize
|
315
|
+
# itself to a type_member/type_template
|
316
|
+
indented("#{constant_name} = #{serialized_type_variable}")
|
317
|
+
end.compact
|
318
|
+
|
319
|
+
return if type_variable_declarations.empty?
|
320
|
+
|
321
|
+
[
|
322
|
+
indented("extend T::Generic"),
|
323
|
+
"",
|
324
|
+
*type_variable_declarations,
|
325
|
+
].compact.join("\n")
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
242
329
|
sig { params(constant: Class).returns(String) }
|
243
330
|
def compile_superclass(constant)
|
244
331
|
superclass = T.let(nil, T.nilable(Class)) # rubocop:disable Lint/UselessAssignment
|
@@ -348,9 +435,13 @@ module Tapioca
|
|
348
435
|
end
|
349
436
|
|
350
437
|
define_singleton_method(:include) do |mod|
|
351
|
-
|
352
|
-
|
353
|
-
|
438
|
+
begin
|
439
|
+
before = singleton_class.ancestors
|
440
|
+
super(mod).tap do
|
441
|
+
mixins_from_modules[mod] = singleton_class.ancestors - before
|
442
|
+
end
|
443
|
+
rescue Exception # rubocop:disable Lint/RescueException
|
444
|
+
# this is a best effort, bail if we can't perform this
|
354
445
|
end
|
355
446
|
end
|
356
447
|
|
@@ -411,29 +502,19 @@ module Tapioca
|
|
411
502
|
instance_methods = compile_directly_owned_methods(name, constant)
|
412
503
|
singleton_methods = compile_directly_owned_methods(name, singleton_class_of(constant))
|
413
504
|
|
414
|
-
return if symbol_ignored?(name) && instance_methods
|
505
|
+
return if symbol_ignored?(name) && !instance_methods && !singleton_methods
|
415
506
|
|
416
507
|
[
|
417
|
-
initialize_method
|
508
|
+
initialize_method,
|
418
509
|
instance_methods,
|
419
510
|
singleton_methods,
|
420
|
-
].select { |b| b.strip
|
511
|
+
].select { |b| b && !b.strip.empty? }.join("\n\n")
|
421
512
|
end
|
422
513
|
|
423
|
-
sig { params(module_name: String, mod: Module, for_visibility: T::Array[Symbol]).returns(String) }
|
514
|
+
sig { params(module_name: String, mod: Module, for_visibility: T::Array[Symbol]).returns(T.nilable(String)) }
|
424
515
|
def compile_directly_owned_methods(module_name, mod, for_visibility = [:public, :protected, :private])
|
425
|
-
|
426
|
-
|
427
|
-
postamble = nil
|
428
|
-
|
429
|
-
if mod.singleton_class?
|
430
|
-
indent_step = 1
|
431
|
-
preamble = indented("class << self")
|
432
|
-
postamble = indented("end")
|
433
|
-
end
|
434
|
-
|
435
|
-
methods = with_indentation(indent_step) do
|
436
|
-
method_names_by_visibility(mod)
|
516
|
+
with_indentation_for_constant(mod) do
|
517
|
+
methods = method_names_by_visibility(mod)
|
437
518
|
.delete_if { |visibility, _method_list| !for_visibility.include?(visibility) }
|
438
519
|
.flat_map do |visibility, method_list|
|
439
520
|
compiled = method_list.sort!.map do |name|
|
@@ -450,16 +531,11 @@ module Tapioca
|
|
450
531
|
compiled
|
451
532
|
end
|
452
533
|
.compact
|
453
|
-
.join("\n")
|
454
|
-
end
|
455
534
|
|
456
|
-
|
535
|
+
return if methods.empty?
|
457
536
|
|
458
|
-
|
459
|
-
|
460
|
-
methods,
|
461
|
-
postamble,
|
462
|
-
].compact.join("\n")
|
537
|
+
methods.join("\n")
|
538
|
+
end
|
463
539
|
end
|
464
540
|
|
465
541
|
sig { params(mod: Module).returns(T::Hash[Symbol, T::Array[Symbol]]) }
|
@@ -639,6 +715,33 @@ module Tapioca
|
|
639
715
|
@indent -= 2 * step
|
640
716
|
end
|
641
717
|
|
718
|
+
sig do
|
719
|
+
params(
|
720
|
+
constant: Module,
|
721
|
+
blk: T.proc
|
722
|
+
.returns(T.nilable(String))
|
723
|
+
)
|
724
|
+
.returns(T.nilable(String))
|
725
|
+
end
|
726
|
+
def with_indentation_for_constant(constant, &blk)
|
727
|
+
step = if constant.singleton_class?
|
728
|
+
1
|
729
|
+
else
|
730
|
+
0
|
731
|
+
end
|
732
|
+
|
733
|
+
result = with_indentation(step, &blk)
|
734
|
+
|
735
|
+
return result unless result
|
736
|
+
return result unless constant.singleton_class?
|
737
|
+
|
738
|
+
[
|
739
|
+
indented("class << self"),
|
740
|
+
result,
|
741
|
+
indented("end"),
|
742
|
+
].compact.join("\n")
|
743
|
+
end
|
744
|
+
|
642
745
|
sig { params(str: String).returns(String) }
|
643
746
|
def indented(str)
|
644
747
|
" " * @indent + str
|
@@ -839,12 +942,12 @@ module Tapioca
|
|
839
942
|
nil
|
840
943
|
end
|
841
944
|
|
842
|
-
sig { params(constant:
|
945
|
+
sig { params(constant: T::Types::Base).returns(String) }
|
843
946
|
def type_of(constant)
|
844
947
|
constant.to_s.gsub(/\bAttachedClass\b/, "T.attached_class")
|
845
948
|
end
|
846
949
|
|
847
|
-
sig { params(object:
|
950
|
+
sig { params(object: BasicObject).returns(Integer).checked(:never) }
|
848
951
|
def object_id_of(object)
|
849
952
|
Object.instance_method(:object_id).bind(object).call
|
850
953
|
end
|
data/lib/tapioca/config.rb
CHANGED
@@ -8,7 +8,6 @@ module Tapioca
|
|
8
8
|
const(:outdir, String)
|
9
9
|
const(:prerequire, T.nilable(String))
|
10
10
|
const(:postrequire, String)
|
11
|
-
const(:generate_command, String)
|
12
11
|
const(:exclude, T::Array[String])
|
13
12
|
const(:typed_overrides, T::Hash[String, String])
|
14
13
|
const(:todos_path, String)
|
@@ -27,6 +26,7 @@ module Tapioca
|
|
27
26
|
TAPIOCA_PATH = T.let("#{SORBET_PATH}/tapioca", String)
|
28
27
|
TAPIOCA_CONFIG = T.let("#{TAPIOCA_PATH}/config.yml", String)
|
29
28
|
|
29
|
+
DEFAULT_COMMAND = T.let("bin/tapioca", String)
|
30
30
|
DEFAULT_POSTREQUIRE = T.let("#{TAPIOCA_PATH}/require.rb", String)
|
31
31
|
DEFAULT_RBIDIR = T.let("#{SORBET_PATH}/rbi", String)
|
32
32
|
DEFAULT_DSLDIR = T.let("#{DEFAULT_RBIDIR}/dsl", String)
|
@@ -10,9 +10,13 @@ module Tapioca
|
|
10
10
|
|
11
11
|
sig { params(command: Symbol, options: T::Hash[String, T.untyped]).returns(Config) }
|
12
12
|
def from_options(command, options)
|
13
|
-
|
14
|
-
|
15
|
-
)
|
13
|
+
merged_options = merge_options(default_options(command), config_options, options)
|
14
|
+
|
15
|
+
puts(<<~MSG) if merged_options.include?("generate_command")
|
16
|
+
DEPRECATION: The `-c` and `--cmd` flags will be removed in a future release.
|
17
|
+
MSG
|
18
|
+
|
19
|
+
Config.from_hash(merged_options)
|
16
20
|
end
|
17
21
|
|
18
22
|
private
|
@@ -40,14 +44,6 @@ module Tapioca
|
|
40
44
|
DEFAULT_OPTIONS.merge("outdir" => default_outdir)
|
41
45
|
end
|
42
46
|
|
43
|
-
sig { returns(String) }
|
44
|
-
def default_command
|
45
|
-
command = File.basename($PROGRAM_NAME)
|
46
|
-
args = ARGV.join(" ")
|
47
|
-
|
48
|
-
"#{command} #{args}".strip
|
49
|
-
end
|
50
|
-
|
51
47
|
sig { params(options: T::Hash[String, T.untyped]).returns(T::Hash[String, T.untyped]) }
|
52
48
|
def merge_options(*options)
|
53
49
|
options.each_with_object({}) do |option, result|
|
@@ -65,7 +61,6 @@ module Tapioca
|
|
65
61
|
DEFAULT_OPTIONS = T.let({
|
66
62
|
"postrequire" => Config::DEFAULT_POSTREQUIRE,
|
67
63
|
"outdir" => nil,
|
68
|
-
"generate_command" => default_command,
|
69
64
|
"exclude" => [],
|
70
65
|
"typed_overrides" => Config::DEFAULT_OVERRIDES,
|
71
66
|
"todos_path" => Config::DEFAULT_TODOSPATH,
|
data/lib/tapioca/gemfile.rb
CHANGED
@@ -17,27 +17,23 @@ module Tapioca
|
|
17
17
|
)
|
18
18
|
end
|
19
19
|
|
20
|
+
sig { returns(Bundler::Definition) }
|
21
|
+
attr_reader(:definition)
|
22
|
+
|
23
|
+
sig { returns(T::Array[Gem]) }
|
24
|
+
attr_reader(:dependencies)
|
25
|
+
|
26
|
+
sig { returns(T::Array[String]) }
|
27
|
+
attr_reader(:missing_specs)
|
28
|
+
|
20
29
|
sig { void }
|
21
30
|
def initialize
|
22
31
|
@gemfile = T.let(File.new(Bundler.default_gemfile), File)
|
23
32
|
@lockfile = T.let(File.new(Bundler.default_lockfile), File)
|
24
|
-
@
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
sig { returns(T::Array[Gem]) }
|
29
|
-
def dependencies
|
30
|
-
@dependencies ||= begin
|
31
|
-
specs = definition.locked_gems.specs.to_a
|
32
|
-
|
33
|
-
definition
|
34
|
-
.resolve
|
35
|
-
.materialize(specs)
|
36
|
-
.map { |spec| Gem.new(spec) }
|
37
|
-
.reject { |gem| gem.ignore?(dir) }
|
38
|
-
.uniq(&:rbi_file_name)
|
39
|
-
.sort_by(&:rbi_file_name)
|
40
|
-
end
|
33
|
+
@definition = T.let(Bundler::Dsl.evaluate(gemfile, lockfile, {}), Bundler::Definition)
|
34
|
+
dependencies, missing_specs = load_dependencies
|
35
|
+
@dependencies = T.let(dependencies, T::Array[Gem])
|
36
|
+
@missing_specs = T.let(missing_specs, T::Array[String])
|
41
37
|
end
|
42
38
|
|
43
39
|
sig { params(gem_name: String).returns(T.nilable(Gem)) }
|
@@ -55,6 +51,23 @@ module Tapioca
|
|
55
51
|
sig { returns(File) }
|
56
52
|
attr_reader(:gemfile, :lockfile)
|
57
53
|
|
54
|
+
sig { returns([T::Array[Gem], T::Array[String]]) }
|
55
|
+
def load_dependencies
|
56
|
+
deps = definition.locked_gems.dependencies.values
|
57
|
+
|
58
|
+
missing_specs = T::Array[String].new
|
59
|
+
|
60
|
+
dependencies = definition
|
61
|
+
.resolve
|
62
|
+
.materialize(deps, missing_specs)
|
63
|
+
.map { |spec| Gem.new(spec) }
|
64
|
+
.reject { |gem| gem.ignore?(dir) }
|
65
|
+
.uniq(&:rbi_file_name)
|
66
|
+
.sort_by(&:rbi_file_name)
|
67
|
+
|
68
|
+
[dependencies, missing_specs]
|
69
|
+
end
|
70
|
+
|
58
71
|
sig { returns(Bundler::Runtime) }
|
59
72
|
def runtime
|
60
73
|
Bundler::Runtime.new(File.dirname(gemfile.path), definition)
|
@@ -65,11 +78,6 @@ module Tapioca
|
|
65
78
|
definition.groups
|
66
79
|
end
|
67
80
|
|
68
|
-
sig { returns(Bundler::Definition) }
|
69
|
-
def definition
|
70
|
-
@definition ||= Bundler::Dsl.evaluate(gemfile, lockfile, {})
|
71
|
-
end
|
72
|
-
|
73
81
|
sig { returns(String) }
|
74
82
|
def dir
|
75
83
|
File.expand_path(gemfile.path + "/..")
|