mini-max-rb 0.0.1

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 (30) hide show
  1. checksums.yaml +7 -0
  2. data/bootsnap-1.24.6/CHANGELOG.md +473 -0
  3. data/bootsnap-1.24.6/LICENSE.txt +22 -0
  4. data/bootsnap-1.24.6/README.md +391 -0
  5. data/bootsnap-1.24.6/exe/bootsnap +5 -0
  6. data/bootsnap-1.24.6/ext/bootsnap/bootsnap.c +1235 -0
  7. data/bootsnap-1.24.6/ext/bootsnap/extconf.rb +34 -0
  8. data/bootsnap-1.24.6/lib/bootsnap/bundler.rb +16 -0
  9. data/bootsnap-1.24.6/lib/bootsnap/cli/worker_pool.rb +208 -0
  10. data/bootsnap-1.24.6/lib/bootsnap/cli.rb +258 -0
  11. data/bootsnap-1.24.6/lib/bootsnap/compile_cache/iseq.rb +229 -0
  12. data/bootsnap-1.24.6/lib/bootsnap/compile_cache/ruby_bug_22023_canary.rb +1 -0
  13. data/bootsnap-1.24.6/lib/bootsnap/compile_cache/yaml.rb +344 -0
  14. data/bootsnap-1.24.6/lib/bootsnap/compile_cache.rb +47 -0
  15. data/bootsnap-1.24.6/lib/bootsnap/explicit_require.rb +56 -0
  16. data/bootsnap-1.24.6/lib/bootsnap/load_path_cache/cache.rb +241 -0
  17. data/bootsnap-1.24.6/lib/bootsnap/load_path_cache/change_observer.rb +84 -0
  18. data/bootsnap-1.24.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb +42 -0
  19. data/bootsnap-1.24.6/lib/bootsnap/load_path_cache/core_ext/loaded_features.rb +19 -0
  20. data/bootsnap-1.24.6/lib/bootsnap/load_path_cache/loaded_features_index.rb +159 -0
  21. data/bootsnap-1.24.6/lib/bootsnap/load_path_cache/path.rb +143 -0
  22. data/bootsnap-1.24.6/lib/bootsnap/load_path_cache/path_scanner.rb +127 -0
  23. data/bootsnap-1.24.6/lib/bootsnap/load_path_cache/store.rb +132 -0
  24. data/bootsnap-1.24.6/lib/bootsnap/load_path_cache.rb +80 -0
  25. data/bootsnap-1.24.6/lib/bootsnap/rake.rb +14 -0
  26. data/bootsnap-1.24.6/lib/bootsnap/setup.rb +5 -0
  27. data/bootsnap-1.24.6/lib/bootsnap/version.rb +5 -0
  28. data/bootsnap-1.24.6/lib/bootsnap.rb +202 -0
  29. data/mini-max-rb.gemspec +12 -0
  30. metadata +69 -0
@@ -0,0 +1,229 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bootsnap/bootsnap"
4
+ require "zlib"
5
+
6
+ module Bootsnap
7
+ module CompileCache
8
+ module ISeq
9
+ class << self
10
+ attr_reader :cache_dir
11
+ attr_accessor :compiler_selector, :default_compiler
12
+
13
+ def cache_dir=(cache_dir)
14
+ @cache_dir = cache_dir.end_with?("/") ? "#{cache_dir}iseq" : "#{cache_dir}-iseq"
15
+ end
16
+
17
+ def supported?
18
+ CompileCache.supported? && defined?(RubyVM)
19
+ end
20
+ end
21
+
22
+ if supported?
23
+ class Compiler
24
+ attr_reader :namespace
25
+
26
+ def initialize(namespace = nil, compile_options = nil)
27
+ @namespace = namespace
28
+ @options = compile_options.freeze
29
+ update_options
30
+ end
31
+
32
+ def update_options
33
+ @compile_options = if @options.nil? || @options < RubyVM::InstructionSequence.compile_option
34
+ nil
35
+ else
36
+ RubyVM::InstructionSequence.compile_option.merge(@options).freeze
37
+ end
38
+ end
39
+
40
+ has_ruby_bug_18250 = RUBY_VERSION.start_with?("3.0.") && begin # https://bugs.ruby-lang.org/issues/18250
41
+ if defined? RubyVM::InstructionSequence
42
+ RubyVM::InstructionSequence.compile(<<~RUBY).to_binary
43
+ def foo(*); ->{ super }; end; def foo(**); ->{ super }; end
44
+ RUBY
45
+ end
46
+ false
47
+ rescue TypeError
48
+ true
49
+ end
50
+
51
+ has_ruby_bug_22023 = case RUBY_VERSION
52
+ when /^3\.3\./
53
+ true
54
+ when /^3\.4\.(\d+)/
55
+ $1.to_i < 10
56
+ when /^4\.0\.(\d+)/
57
+ $1.to_i < 4
58
+ else
59
+ false
60
+ end
61
+
62
+ if has_ruby_bug_22023 && RUBY_DESCRIPTION.include?("+PRISM")
63
+ module PatchRubyBug22023
64
+ def compile_file(path, options = nil)
65
+ compile_file_prism(path, options)
66
+ end
67
+
68
+ has_ruby_bug_22023_bis = !RubyVM::InstructionSequence.compile_file_prism(
69
+ File.expand_path("../ruby_bug_22023_canary.rb", __FILE__),
70
+ {frozen_string_literal: true},
71
+ ).eval.frozen?
72
+
73
+ if has_ruby_bug_22023_bis
74
+ def compile_file_prism(path, options = nil)
75
+ compile_prism(::File.read(path, encoding: Encoding::UTF_8), path, path, nil, options)
76
+ end
77
+ end
78
+ end
79
+ RubyVM::InstructionSequence.singleton_class.prepend(PatchRubyBug22023)
80
+ end
81
+
82
+ if has_ruby_bug_18250
83
+ def input_to_storage(_, path)
84
+ iseq = RubyVM::InstructionSequence.compile_file(path, @compile_options)
85
+ iseq.to_binary
86
+ rescue TypeError, SyntaxError # Ruby [Bug #18250] & [Bug #22023]
87
+ UNCOMPILABLE
88
+ end
89
+ else
90
+ def input_to_storage(_, path)
91
+ RubyVM::InstructionSequence.compile_file(path, @compile_options).to_binary
92
+ rescue SyntaxError # Ruby [Bug #22023]
93
+ UNCOMPILABLE
94
+ end
95
+ end
96
+
97
+ def storage_to_output(binary, _args)
98
+ iseq = RubyVM::InstructionSequence.load_from_binary(binary)
99
+ binary.clear
100
+ iseq
101
+ rescue RuntimeError => error
102
+ if error.message == "broken binary format"
103
+ $stderr.puts("[Bootsnap::CompileCache] warning: rejecting broken binary")
104
+ nil
105
+ else
106
+ raise
107
+ end
108
+ end
109
+
110
+ def input_to_output(source, path, _kwargs)
111
+ if @compile_options
112
+ if source
113
+ RubyVM::InstructionSequence.compile(
114
+ source.force_encoding(Encoding.default_external),
115
+ path,
116
+ path,
117
+ nil,
118
+ @compile_options,
119
+ )
120
+ else
121
+ RubyVM::InstructionSequence.compile_file(path, @compile_options)
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ DEFAULT = Compiler.new
128
+ FROZEN_STRING_LITERAL = Compiler.new("-fstr", {frozen_string_literal: true}.freeze)
129
+ COVERAGE_SUPPORTED = RUBY_VERSION >= "4.0.4"
130
+
131
+ @default_compiler = DEFAULT
132
+ @coverage_support_warning_emitted = false
133
+
134
+ def self.fetch(path, cache_dir: ISeq.cache_dir)
135
+ compiler = compiler_selector&.call(path) || default_compiler
136
+
137
+ # Having coverage enabled prevents iseq dumping/loading.
138
+ if coverage_on?
139
+ return nil if compiler.equal?(DEFAULT)
140
+
141
+ if COVERAGE_SUPPORTED
142
+ return compiler.input_to_output(nil, path.to_s, nil)
143
+ elsif !@coverage_support_warning_emitted
144
+ @coverage_support_warning_emitted = true
145
+ warn(<<~MSG)
146
+ Using `Bootsnap.enable_frozen_string_literal` with code coverage enabled is only supported on Ruby 4.0.4+.
147
+ Files loaded while coverage is on, will have mutable string literals.
148
+ MSG
149
+ end
150
+
151
+ return nil
152
+ end
153
+
154
+ Bootsnap::CompileCache::Native.fetch(
155
+ cache_dir,
156
+ compiler.namespace,
157
+ path.to_s,
158
+ compiler,
159
+ nil,
160
+ )
161
+ end
162
+
163
+ def self.precompile(path)
164
+ compiler = compiler_selector&.call(path) || default_compiler
165
+ Bootsnap::CompileCache::Native.precompile(
166
+ cache_dir,
167
+ compiler.namespace,
168
+ path.to_s,
169
+ compiler,
170
+ )
171
+ end
172
+
173
+ if RUBY_VERSION < "3.1."
174
+ def self.coverage_on?
175
+ defined?(Coverage) && Coverage.running?
176
+ end
177
+ else
178
+ def self.coverage_on?
179
+ defined?(Coverage) && Coverage.state != :idle
180
+ end
181
+ end
182
+
183
+ module InstructionSequenceMixin
184
+ def load_iseq(path)
185
+ Bootsnap::CompileCache::ISeq.fetch(path.to_s)
186
+ rescue RuntimeError => error
187
+ if error.message.include?("unmatched platform")
188
+ puts("unmatched platform for file #{path}")
189
+ end
190
+ raise
191
+ end
192
+
193
+ def compile_option=(hash)
194
+ super
195
+ Bootsnap::CompileCache::ISeq.compile_option_updated
196
+ end
197
+ end
198
+
199
+ def self.compile_option_updated
200
+ option = RubyVM::InstructionSequence.compile_option
201
+ crc = Zlib.crc32(option.inspect)
202
+ Bootsnap::CompileCache::Native.compile_option_crc32 = crc
203
+ FROZEN_STRING_LITERAL.update_options
204
+ end
205
+ compile_option_updated if supported?
206
+
207
+ def self.install!(cache_dir)
208
+ Bootsnap::CompileCache::ISeq.cache_dir = cache_dir
209
+
210
+ return unless supported?
211
+
212
+ Bootsnap::CompileCache::ISeq.compile_option_updated
213
+
214
+ class << RubyVM::InstructionSequence
215
+ prepend(InstructionSequenceMixin)
216
+ end
217
+ end
218
+ else
219
+ def self.install!(...)
220
+ # noop
221
+ end
222
+
223
+ def self.precompile(...)
224
+ # noop
225
+ end
226
+ end
227
+ end
228
+ end
229
+ end
@@ -0,0 +1,344 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bootsnap/bootsnap"
4
+
5
+ module Bootsnap
6
+ module CompileCache
7
+ module YAML
8
+ Uncompilable = Class.new(StandardError)
9
+ UnsupportedTags = Class.new(Uncompilable)
10
+
11
+ SUPPORTED_INTERNAL_ENCODINGS = [
12
+ nil, # UTF-8
13
+ Encoding::UTF_8,
14
+ Encoding::ASCII,
15
+ Encoding::BINARY,
16
+ ].freeze
17
+
18
+ class << self
19
+ attr_accessor(:msgpack_factory, :supported_options)
20
+ attr_reader(:implementation, :cache_dir)
21
+
22
+ def cache_dir=(cache_dir)
23
+ @cache_dir = cache_dir.end_with?("/") ? "#{cache_dir}yaml" : "#{cache_dir}-yaml"
24
+ end
25
+
26
+ def precompile(path)
27
+ return false unless CompileCache::YAML.supported_internal_encoding?
28
+
29
+ CompileCache::Native.precompile(
30
+ cache_dir,
31
+ nil,
32
+ path.to_s,
33
+ @implementation,
34
+ )
35
+ end
36
+
37
+ def install!(cache_dir)
38
+ self.cache_dir = cache_dir
39
+ init!
40
+ ::YAML.singleton_class.prepend(@implementation::Patch)
41
+ end
42
+
43
+ # Psych coerce strings to `Encoding.default_internal` but Message Pack only support
44
+ # UTF-8, US-ASCII and BINARY. So if Encoding.default_internal is set to anything else
45
+ # we can't safely use the cache
46
+ def supported_internal_encoding?
47
+ SUPPORTED_INTERNAL_ENCODINGS.include?(Encoding.default_internal)
48
+ end
49
+
50
+ module EncodingAwareSymbols
51
+ extend self
52
+
53
+ def unpack(payload)
54
+ (+payload).force_encoding(Encoding::UTF_8).to_sym
55
+ end
56
+ end
57
+
58
+ def init!
59
+ require "yaml"
60
+ require "msgpack"
61
+ require "date"
62
+
63
+ @implementation = ::YAML::VERSION >= "4" ? Psych4 : Psych3
64
+ if @implementation::Patch.method_defined?(:unsafe_load_file) && !::YAML.respond_to?(:unsafe_load_file)
65
+ @implementation::Patch.send(:remove_method, :unsafe_load_file)
66
+ end
67
+
68
+ unless const_defined?(:NoTagsVisitor)
69
+ visitor = Class.new(Psych::Visitors::NoAliasRuby) do
70
+ def visit(target)
71
+ if target.tag
72
+ raise UnsupportedTags, "YAML tags are not supported: #{target.tag}"
73
+ end
74
+
75
+ super
76
+ end
77
+ end
78
+ const_set(:NoTagsVisitor, visitor)
79
+ end
80
+
81
+ # MessagePack serializes symbols as strings by default.
82
+ # We want them to roundtrip cleanly, so we use a custom factory.
83
+ # see: https://github.com/msgpack/msgpack-ruby/pull/122
84
+ factory = MessagePack::Factory.new
85
+ factory.register_type(
86
+ 0x00,
87
+ Symbol,
88
+ packer: :to_msgpack_ext,
89
+ unpacker: EncodingAwareSymbols.method(:unpack).to_proc,
90
+ )
91
+
92
+ if defined? MessagePack::Timestamp
93
+ factory.register_type(
94
+ MessagePack::Timestamp::TYPE, # or just -1
95
+ Time,
96
+ packer: MessagePack::Time::Packer,
97
+ unpacker: MessagePack::Time::Unpacker,
98
+ )
99
+
100
+ marshal_fallback = {
101
+ packer: ->(value) { Marshal.dump(value) },
102
+ unpacker: ->(payload) { Marshal.load(payload) },
103
+ }
104
+ {
105
+ Date => 0x01,
106
+ Regexp => 0x02,
107
+ }.each do |type, code|
108
+ factory.register_type(code, type, marshal_fallback)
109
+ end
110
+ end
111
+
112
+ self.msgpack_factory = factory
113
+
114
+ self.supported_options = []
115
+ params = ::YAML.method(:load).parameters
116
+ if params.include?([:key, :symbolize_names])
117
+ supported_options << :symbolize_names
118
+ end
119
+ if params.include?([:key, :freeze]) && factory.load(factory.dump("yaml"), freeze: true).frozen?
120
+ supported_options << :freeze
121
+ end
122
+ supported_options.freeze
123
+ end
124
+
125
+ def patch
126
+ @implementation::Patch
127
+ end
128
+
129
+ def strict_load(payload)
130
+ ast = ::YAML.parse(payload)
131
+ return ast unless ast
132
+
133
+ loader = ::Psych::ClassLoader::Restricted.new(["Symbol"], [])
134
+ scanner = ::Psych::ScalarScanner.new(loader)
135
+
136
+ NoTagsVisitor.new(scanner, loader).visit(ast)
137
+ end
138
+ end
139
+
140
+ module Psych4
141
+ extend self
142
+
143
+ def input_to_storage(contents, _)
144
+ obj = SafeLoad.input_to_storage(contents, nil)
145
+ if UNCOMPILABLE.equal?(obj)
146
+ obj = UnsafeLoad.input_to_storage(contents, nil)
147
+ end
148
+ obj
149
+ end
150
+
151
+ module UnsafeLoad
152
+ extend self
153
+
154
+ def input_to_storage(contents, _)
155
+ obj = ::YAML.unsafe_load(contents)
156
+ packer = CompileCache::YAML.msgpack_factory.packer
157
+ packer.pack(false) # not safe loaded
158
+ begin
159
+ packer.pack(obj)
160
+ rescue NoMethodError, RangeError
161
+ return UNCOMPILABLE # The object included things that we can't serialize
162
+ end
163
+ packer.to_s
164
+ end
165
+
166
+ def storage_to_output(data, kwargs)
167
+ if kwargs&.key?(:symbolize_names)
168
+ kwargs[:symbolize_keys] = kwargs.delete(:symbolize_names)
169
+ end
170
+
171
+ unpacker = CompileCache::YAML.msgpack_factory.unpacker(kwargs)
172
+ unpacker.feed(data)
173
+ _safe_loaded = unpacker.unpack
174
+ result = unpacker.unpack
175
+ data.clear
176
+ result
177
+ end
178
+
179
+ def input_to_output(data, _path, kwargs)
180
+ ::YAML.unsafe_load(data, **(kwargs || {}))
181
+ end
182
+ end
183
+
184
+ module SafeLoad
185
+ extend self
186
+
187
+ def input_to_storage(contents, _)
188
+ obj = begin
189
+ CompileCache::YAML.strict_load(contents)
190
+ rescue Psych::DisallowedClass, Psych::BadAlias, Uncompilable
191
+ return UNCOMPILABLE
192
+ end
193
+
194
+ packer = CompileCache::YAML.msgpack_factory.packer
195
+ packer.pack(true) # safe loaded
196
+ begin
197
+ packer.pack(obj)
198
+ rescue NoMethodError, RangeError
199
+ return UNCOMPILABLE
200
+ end
201
+ packer.to_s
202
+ end
203
+
204
+ def storage_to_output(data, kwargs)
205
+ if kwargs&.key?(:symbolize_names)
206
+ kwargs[:symbolize_keys] = kwargs.delete(:symbolize_names)
207
+ end
208
+
209
+ unpacker = CompileCache::YAML.msgpack_factory.unpacker(kwargs)
210
+ unpacker.feed(data)
211
+ safe_loaded = unpacker.unpack
212
+ if safe_loaded
213
+ unpacker.unpack
214
+ else
215
+ UNCOMPILABLE
216
+ end
217
+ end
218
+
219
+ def input_to_output(data, _path, kwargs)
220
+ ::YAML.load(data, **(kwargs || {}))
221
+ end
222
+ end
223
+
224
+ module Patch
225
+ def load_file(path, *args)
226
+ return super unless CompileCache::YAML.supported_internal_encoding?
227
+
228
+ return super if args.size > 1
229
+
230
+ if (kwargs = args.first)
231
+ return super unless kwargs.is_a?(Hash)
232
+ return super unless (kwargs.keys - CompileCache::YAML.supported_options).empty?
233
+ end
234
+
235
+ CompileCache::Native.fetch(
236
+ CompileCache::YAML.cache_dir,
237
+ nil,
238
+ File.realpath(path),
239
+ CompileCache::YAML::Psych4::SafeLoad,
240
+ kwargs,
241
+ )
242
+ end
243
+
244
+ ruby2_keywords :load_file if respond_to?(:ruby2_keywords, true)
245
+
246
+ def unsafe_load_file(path, *args)
247
+ return super unless CompileCache::YAML.supported_internal_encoding?
248
+
249
+ return super if args.size > 1
250
+
251
+ if (kwargs = args.first)
252
+ return super unless kwargs.is_a?(Hash)
253
+ return super unless (kwargs.keys - CompileCache::YAML.supported_options).empty?
254
+ end
255
+
256
+ CompileCache::Native.fetch(
257
+ CompileCache::YAML.cache_dir,
258
+ nil,
259
+ File.realpath(path),
260
+ CompileCache::YAML::Psych4::UnsafeLoad,
261
+ kwargs,
262
+ )
263
+ end
264
+
265
+ ruby2_keywords :unsafe_load_file if respond_to?(:ruby2_keywords, true)
266
+ end
267
+ end
268
+
269
+ module Psych3
270
+ extend self
271
+
272
+ def input_to_storage(contents, _)
273
+ obj = ::YAML.load(contents)
274
+ packer = CompileCache::YAML.msgpack_factory.packer
275
+ packer.pack(false) # not safe loaded
276
+ begin
277
+ packer.pack(obj)
278
+ rescue NoMethodError, RangeError
279
+ return UNCOMPILABLE # The object included things that we can't serialize
280
+ end
281
+ packer.to_s
282
+ end
283
+
284
+ def storage_to_output(data, kwargs)
285
+ if kwargs&.key?(:symbolize_names)
286
+ kwargs[:symbolize_keys] = kwargs.delete(:symbolize_names)
287
+ end
288
+ unpacker = CompileCache::YAML.msgpack_factory.unpacker(kwargs)
289
+ unpacker.feed(data)
290
+ _safe_loaded = unpacker.unpack
291
+ unpacker.unpack
292
+ end
293
+
294
+ def input_to_output(data, _path, kwargs)
295
+ ::YAML.load(data, **(kwargs || {}))
296
+ end
297
+
298
+ module Patch
299
+ def load_file(path, *args)
300
+ return super unless CompileCache::YAML.supported_internal_encoding?
301
+
302
+ return super if args.size > 1
303
+
304
+ if (kwargs = args.first)
305
+ return super unless kwargs.is_a?(Hash)
306
+ return super unless (kwargs.keys - CompileCache::YAML.supported_options).empty?
307
+ end
308
+
309
+ CompileCache::Native.fetch(
310
+ CompileCache::YAML.cache_dir,
311
+ nil,
312
+ File.realpath(path),
313
+ CompileCache::YAML::Psych3,
314
+ kwargs,
315
+ )
316
+ end
317
+
318
+ ruby2_keywords :load_file if respond_to?(:ruby2_keywords, true)
319
+
320
+ def unsafe_load_file(path, *args)
321
+ return super unless CompileCache::YAML.supported_internal_encoding?
322
+
323
+ return super if args.size > 1
324
+
325
+ if (kwargs = args.first)
326
+ return super unless kwargs.is_a?(Hash)
327
+ return super unless (kwargs.keys - CompileCache::YAML.supported_options).empty?
328
+ end
329
+
330
+ CompileCache::Native.fetch(
331
+ CompileCache::YAML.cache_dir,
332
+ nil,
333
+ File.realpath(path),
334
+ CompileCache::YAML::Psych3,
335
+ kwargs,
336
+ )
337
+ end
338
+
339
+ ruby2_keywords :unsafe_load_file if respond_to?(:ruby2_keywords, true)
340
+ end
341
+ end
342
+ end
343
+ end
344
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bootsnap
4
+ module CompileCache
5
+ UNCOMPILABLE = BasicObject.new
6
+ def UNCOMPILABLE.inspect
7
+ "<Bootsnap::UNCOMPILABLE>"
8
+ end
9
+
10
+ Error = Class.new(StandardError)
11
+
12
+ def self.setup(cache_dir:, iseq:, yaml:, json: (json_unset = true), readonly: false, revalidation: false)
13
+ unless json_unset
14
+ warn("Bootsnap::CompileCache.setup `json` argument is deprecated and has no effect")
15
+ end
16
+
17
+ if iseq
18
+ if supported?
19
+ require_relative "compile_cache/iseq"
20
+ Bootsnap::CompileCache::ISeq.install!(cache_dir)
21
+ elsif $VERBOSE
22
+ warn("[bootsnap/setup] bytecode caching is not supported on this implementation of Ruby")
23
+ end
24
+ end
25
+
26
+ if yaml
27
+ if supported?
28
+ require_relative "compile_cache/yaml"
29
+ Bootsnap::CompileCache::YAML.install!(cache_dir)
30
+ elsif $VERBOSE
31
+ warn("[bootsnap/setup] YAML parsing caching is not supported on this implementation of Ruby")
32
+ end
33
+ end
34
+
35
+ if supported? && defined?(Bootsnap::CompileCache::Native)
36
+ Bootsnap::CompileCache::Native.readonly = readonly
37
+ Bootsnap::CompileCache::Native.revalidation = revalidation
38
+ end
39
+ end
40
+
41
+ def self.supported?
42
+ # only enable on 'ruby' (MRI) and TruffleRuby for POSIX (darwin, linux, *bsd), Windows (RubyInstaller2)
43
+ %w[ruby truffleruby].include?(RUBY_ENGINE) &&
44
+ RUBY_PLATFORM.match?(/darwin|linux|bsd|mswin|mingw|cygwin/)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bootsnap
4
+ module ExplicitRequire
5
+ ARCHDIR = RbConfig::CONFIG["archdir"]
6
+ RUBYLIBDIR = RbConfig::CONFIG["rubylibdir"]
7
+ DLEXT = RbConfig::CONFIG["DLEXT"]
8
+
9
+ def self.from_self(feature)
10
+ require_relative("../#{feature}")
11
+ end
12
+
13
+ def self.from_rubylibdir(feature)
14
+ require(File.join(RUBYLIBDIR, "#{feature}.rb"))
15
+ end
16
+
17
+ def self.from_archdir(feature)
18
+ require(File.join(ARCHDIR, "#{feature}.#{DLEXT}"))
19
+ end
20
+
21
+ # Given a set of gems, run a block with the LOAD_PATH narrowed to include
22
+ # only core ruby source paths and these gems -- that is, roughly,
23
+ # temporarily remove all gems not listed in this call from the LOAD_PATH.
24
+ #
25
+ # This is useful before bootsnap is fully-initialized to load gems that it
26
+ # depends on, without forcing full LOAD_PATH traversals.
27
+ def self.with_gems(*gems)
28
+ # Ensure the gems are activated (their paths are in $LOAD_PATH)
29
+ gems.each do |gem_name|
30
+ gem gem_name
31
+ end
32
+
33
+ orig = $LOAD_PATH.dup
34
+ $LOAD_PATH.clear
35
+ gems.each do |gem|
36
+ pat = %r{
37
+ /
38
+ (gems|extensions/[^/]+/[^/]+) # "gems" or "extensions/x64_64-darwin16/2.3.0"
39
+ /
40
+ #{Regexp.escape(gem)}-(\h{12}|(\d+\.)) # msgpack-1.2.3 or msgpack-1234567890ab
41
+ }x
42
+ $LOAD_PATH.concat(orig.grep(pat))
43
+ end
44
+ $LOAD_PATH << ARCHDIR
45
+ $LOAD_PATH << RUBYLIBDIR
46
+ begin
47
+ yield
48
+ rescue LoadError
49
+ $LOAD_PATH.replace(orig)
50
+ yield
51
+ end
52
+ ensure
53
+ $LOAD_PATH.replace(orig)
54
+ end
55
+ end
56
+ end