bootsnap 1.7.3 → 1.9.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b27cdcd835cd67efea9340d2e09899a3fa553ded267992672183d3bce9cd7de
4
- data.tar.gz: 73d228cbe15a69fb1a26d76f6375fe564f4de4db6e7f111e6a4d0ec31e09b0a1
3
+ metadata.gz: 8741381213652a6e3fc633bb87c69446d65ded8ccc5dcf72e64a8fa4a796955b
4
+ data.tar.gz: e72c311d1417b7c4d174c5b95cc6d95b1b0078dfd5dfb71c213f6704cd011665
5
5
  SHA512:
6
- metadata.gz: e967771cc3387e0297d1654a824f7406e2db1395766dc6df5d2069b78129a71737a497e4681c8988f62ce308e646f967137929266004dbc0e3fbf212da53d3f0
7
- data.tar.gz: ba6e782a7c4da7d8762cea5501359077b66b68f6b0cbb00e8533557cfd5194ef71bc5016c2273a8ba6ad0aa8e5f434f449c3d0cc8252fde215032807cfd75a9f
6
+ metadata.gz: 804f427e8dd71b5aab1fe772f0f44f9fd8598cd2cd9bfc2348a13bff85fb1d65f59711188ca52b8dabc26e688655b4565e2aca2b2b8bf2a85e2635a299fe2f3a
7
+ data.tar.gz: a679ccfd21df451edf3e77c750f92388ab746afbb5e5d84e3265e8e2fbd52f6c17d6a303efc179e24fa994de95762d30e2b31683517d500236fe0c2ba5f23d25
data/CHANGELOG.md CHANGED
@@ -1,5 +1,52 @@
1
1
  # Unreleased
2
2
 
3
+ # 1.9.3
4
+
5
+ * Only disable the compile cache for source files impacted by [Ruby 3.0.3 [Bug 18250]](https://bugs.ruby-lang.org/issues/18250).
6
+ This should keep the performance loss to a minimum.
7
+
8
+ # 1.9.2
9
+
10
+ * Disable compile cache if [Ruby 3.0.3's ISeq cache bug](https://bugs.ruby-lang.org/issues/18250) is detected.
11
+ AKA `iseq.rb:13 to_binary: wrong argument type false (expected Symbol)`
12
+ * Fix `Kernel.load` behavior: before `load 'a'` would load `a.rb` (and other tried extensions) and wouldn't load `a` unless `development_mode: true`, now only `a` would be loaded and files with extensions wouldn't be.
13
+
14
+ # 1.9.1
15
+
16
+ * Removed a forgotten debug statement in JSON precompilation.
17
+
18
+ # 1.9.0
19
+
20
+ * Added a compilation cache for `JSON.load_file`. (#370)
21
+
22
+ # 1.8.1
23
+
24
+ * Fixed support for older Psych. (#369)
25
+
26
+ # 1.8.0
27
+
28
+ * Improve support for Pysch 4. (#368)
29
+
30
+ # 1.7.7
31
+
32
+ * Fix `require_relative` in evaled code on latest ruby 3.1.0-dev. (#366)
33
+
34
+ # 1.7.6
35
+
36
+ * Fix reliance on `set` to be required.
37
+ * Fix `Encoding::UndefinedConversionError` error for Rails applications when precompiling cache. (#364)
38
+
39
+ # 1.7.5
40
+
41
+ * Handle a regression of Ruby 2.7.3 causing Bootsnap to call the deprecated `untaint` method. (#360)
42
+ * Gracefully handle read-only file system as well as other errors preventing to persist the load path cache. (#358)
43
+
44
+ # 1.7.4
45
+
46
+ * Stop raising errors when encoutering various file system errors. The cache is now best effort,
47
+ if somehow it can't be saved, bootsnapp will gracefully fallback to the original operation (e.g. `Kernel.require`).
48
+ (#353, #177, #262)
49
+
3
50
  # 1.7.3
4
51
 
5
52
  * Disable YAML precompilation when encountering YAML tags. (#351)
@@ -464,8 +464,7 @@ open_cache_file(const char * path, struct bs_cache_key * key, const char ** errn
464
464
  fd = open(path, O_RDONLY);
465
465
  if (fd < 0) {
466
466
  *errno_provenance = "bs_fetch:open_cache_file:open";
467
- if (errno == ENOENT) return CACHE_MISS;
468
- return ERROR_WITH_ERRNO;
467
+ return CACHE_MISS;
469
468
  }
470
469
  #ifdef _WIN32
471
470
  setmode(fd, O_BINARY);
@@ -763,9 +762,11 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
763
762
  /* If storage_data isn't a string, we can't cache it */
764
763
  if (!RB_TYPE_P(storage_data, T_STRING)) goto invalid_type_storage_data;
765
764
 
766
- /* Write the cache key and storage_data to the cache directory */
767
- res = atomic_write_cache_file(cache_path, &current_key, storage_data, &errno_provenance);
768
- if (res < 0) goto fail_errno;
765
+ /* Attempt to write the cache key and storage_data to the cache directory.
766
+ * We do however ignore any failures to persist the cache, as it's better
767
+ * to move along, than to interrupt the process.
768
+ */
769
+ atomic_write_cache_file(cache_path, &current_key, storage_data, &errno_provenance);
769
770
 
770
771
  /* Having written the cache, now convert storage_data to output_data */
771
772
  exception_tag = bs_storage_to_output(handler, args, storage_data, &output_data);
@@ -37,7 +37,11 @@ module Bootsnap
37
37
 
38
38
  def initialize(jobs)
39
39
  @jobs = jobs
40
- @pipe_out, @to_io = IO.pipe
40
+ @pipe_out, @to_io = IO.pipe(binmode: true)
41
+ # Set the writer encoding to binary since IO.pipe only sets it for the reader.
42
+ # https://github.com/rails/rails/issues/16514#issuecomment-52313290
43
+ @to_io.set_encoding(Encoding::BINARY)
44
+
41
45
  @pid = nil
42
46
  end
43
47
 
data/lib/bootsnap/cli.rb CHANGED
@@ -21,7 +21,7 @@ module Bootsnap
21
21
 
22
22
  attr_reader :cache_dir, :argv
23
23
 
24
- attr_accessor :compile_gemfile, :exclude, :verbose, :iseq, :yaml, :jobs
24
+ attr_accessor :compile_gemfile, :exclude, :verbose, :iseq, :yaml, :json, :jobs
25
25
 
26
26
  def initialize(argv)
27
27
  @argv = argv
@@ -32,37 +32,44 @@ module Bootsnap
32
32
  self.jobs = Etc.nprocessors
33
33
  self.iseq = true
34
34
  self.yaml = true
35
+ self.json = true
35
36
  end
36
37
 
37
38
  def precompile_command(*sources)
38
39
  require 'bootsnap/compile_cache/iseq'
39
40
  require 'bootsnap/compile_cache/yaml'
41
+ require 'bootsnap/compile_cache/json'
40
42
 
41
43
  fix_default_encoding do
42
44
  Bootsnap::CompileCache::ISeq.cache_dir = self.cache_dir
43
45
  Bootsnap::CompileCache::YAML.init!
44
46
  Bootsnap::CompileCache::YAML.cache_dir = self.cache_dir
47
+ Bootsnap::CompileCache::JSON.init!
48
+ Bootsnap::CompileCache::JSON.cache_dir = self.cache_dir
45
49
 
46
50
  @work_pool = WorkerPool.create(size: jobs, jobs: {
47
51
  ruby: method(:precompile_ruby),
48
52
  yaml: method(:precompile_yaml),
53
+ json: method(:precompile_json),
49
54
  })
50
55
  @work_pool.spawn
51
56
 
52
57
  main_sources = sources.map { |d| File.expand_path(d) }
53
58
  precompile_ruby_files(main_sources)
54
59
  precompile_yaml_files(main_sources)
60
+ precompile_json_files(main_sources)
55
61
 
56
62
  if compile_gemfile
57
63
  # Some gems embed their tests, they're very unlikely to be loaded, so not worth precompiling.
58
64
  gem_exclude = Regexp.union([exclude, '/spec/', '/test/'].compact)
59
65
  precompile_ruby_files($LOAD_PATH.map { |d| File.expand_path(d) }, exclude: gem_exclude)
60
66
 
61
- # Gems that include YAML files usually don't put them in `lib/`.
67
+ # Gems that include JSON or YAML files usually don't put them in `lib/`.
62
68
  # So we look at the gem root.
63
69
  gem_pattern = %r{^#{Regexp.escape(Bundler.bundle_path.to_s)}/?(?:bundler/)?gems\/[^/]+}
64
70
  gem_paths = $LOAD_PATH.map { |p| p[gem_pattern] }.compact.uniq
65
71
  precompile_yaml_files(gem_paths, exclude: gem_exclude)
72
+ precompile_json_files(gem_paths, exclude: gem_exclude)
66
73
  end
67
74
 
68
75
  if exitstatus = @work_pool.shutdown
@@ -137,6 +144,29 @@ module Bootsnap
137
144
  end
138
145
  end
139
146
 
147
+ def precompile_json_files(load_paths, exclude: self.exclude)
148
+ return unless json
149
+
150
+ load_paths.each do |path|
151
+ if !exclude || !exclude.match?(path)
152
+ list_files(path, '**/*.json').each do |json_file|
153
+ # We ignore hidden files to not match the various .config.json files
154
+ if !File.basename(json_file).start_with?('.') && (!exclude || !exclude.match?(json_file))
155
+ @work_pool.push(:json, json_file)
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
161
+
162
+ def precompile_json(*json_files)
163
+ Array(json_files).each do |json_file|
164
+ if CompileCache::JSON.precompile(json_file, cache_dir: cache_dir)
165
+ STDERR.puts(json_file) if verbose
166
+ end
167
+ end
168
+ end
169
+
140
170
  def precompile_ruby_files(load_paths, exclude: self.exclude)
141
171
  return unless iseq
142
172
 
@@ -240,6 +270,11 @@ module Bootsnap
240
270
  Disable YAML precompilation.
241
271
  EOS
242
272
  opts.on('--no-yaml', help) { self.yaml = false }
273
+
274
+ help = <<~EOS
275
+ Disable JSON precompilation.
276
+ EOS
277
+ opts.on('--no-json', help) { self.json = false }
243
278
  end
244
279
  end
245
280
  end
@@ -9,10 +9,35 @@ module Bootsnap
9
9
  attr_accessor(:cache_dir)
10
10
  end
11
11
 
12
- def self.input_to_storage(_, path)
13
- RubyVM::InstructionSequence.compile_file(path).to_binary
14
- rescue SyntaxError
15
- raise(Uncompilable, 'syntax error')
12
+ has_ruby_bug_18250 = begin # https://bugs.ruby-lang.org/issues/18250
13
+ if defined? RubyVM::InstructionSequence
14
+ RubyVM::InstructionSequence.compile("def foo(*); ->{ super }; end; def foo(**); ->{ super }; end").to_binary
15
+ end
16
+ false
17
+ rescue TypeError
18
+ true
19
+ end
20
+
21
+ if has_ruby_bug_18250
22
+ def self.input_to_storage(_, path)
23
+ iseq = begin
24
+ RubyVM::InstructionSequence.compile_file(path)
25
+ rescue SyntaxError
26
+ raise(Uncompilable, 'syntax error')
27
+ end
28
+
29
+ begin
30
+ iseq.to_binary
31
+ rescue TypeError
32
+ raise(Uncompilable, 'ruby bug #18250')
33
+ end
34
+ end
35
+ else
36
+ def self.input_to_storage(_, path)
37
+ RubyVM::InstructionSequence.compile_file(path).to_binary
38
+ rescue SyntaxError
39
+ raise(Uncompilable, 'syntax error')
40
+ end
16
41
  end
17
42
 
18
43
  def self.storage_to_output(binary, _args)
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+ require('bootsnap/bootsnap')
3
+
4
+ module Bootsnap
5
+ module CompileCache
6
+ module JSON
7
+ class << self
8
+ attr_accessor(:msgpack_factory, :cache_dir, :supported_options)
9
+
10
+ def input_to_storage(payload, _)
11
+ obj = ::JSON.parse(payload)
12
+ msgpack_factory.dump(obj)
13
+ end
14
+
15
+ def storage_to_output(data, kwargs)
16
+ if kwargs && kwargs.key?(:symbolize_names)
17
+ kwargs[:symbolize_keys] = kwargs.delete(:symbolize_names)
18
+ end
19
+ msgpack_factory.load(data, kwargs)
20
+ end
21
+
22
+ def input_to_output(data, kwargs)
23
+ ::JSON.parse(data, **(kwargs || {}))
24
+ end
25
+
26
+ def precompile(path, cache_dir: self.cache_dir)
27
+ Bootsnap::CompileCache::Native.precompile(
28
+ cache_dir,
29
+ path.to_s,
30
+ self,
31
+ )
32
+ end
33
+
34
+ def install!(cache_dir)
35
+ self.cache_dir = cache_dir
36
+ init!
37
+ if ::JSON.respond_to?(:load_file)
38
+ ::JSON.singleton_class.prepend(Patch)
39
+ end
40
+ end
41
+
42
+ def init!
43
+ require('json')
44
+ require('msgpack')
45
+
46
+ self.msgpack_factory = MessagePack::Factory.new
47
+ self.supported_options = [:symbolize_names]
48
+ if ::JSON.parse('["foo"]', freeze: true).first.frozen?
49
+ self.supported_options = [:freeze]
50
+ end
51
+ self.supported_options.freeze
52
+ end
53
+ end
54
+
55
+ module Patch
56
+ def load_file(path, *args)
57
+ return super if args.size > 1
58
+ if kwargs = args.first
59
+ return super unless kwargs.is_a?(Hash)
60
+ return super unless (kwargs.keys - ::Bootsnap::CompileCache::JSON.supported_options).empty?
61
+ end
62
+
63
+ begin
64
+ ::Bootsnap::CompileCache::Native.fetch(
65
+ Bootsnap::CompileCache::JSON.cache_dir,
66
+ File.realpath(path),
67
+ ::Bootsnap::CompileCache::JSON,
68
+ kwargs,
69
+ )
70
+ rescue Errno::EACCES
71
+ ::Bootsnap::CompileCache.permission_error(path)
72
+ end
73
+ end
74
+
75
+ ruby2_keywords :load_file if respond_to?(:ruby2_keywords, true)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -23,7 +23,11 @@ module Bootsnap
23
23
  end
24
24
 
25
25
  def input_to_output(data, kwargs)
26
- ::YAML.load(data, **(kwargs || {}))
26
+ if ::YAML.respond_to?(:unsafe_load)
27
+ ::YAML.unsafe_load(data, **(kwargs || {}))
28
+ else
29
+ ::YAML.load(data, **(kwargs || {}))
30
+ end
27
31
  end
28
32
 
29
33
  def strict_load(payload, *args)
@@ -52,6 +56,13 @@ module Bootsnap
52
56
  require('msgpack')
53
57
  require('date')
54
58
 
59
+ if Patch.method_defined?(:unsafe_load_file) && !::YAML.respond_to?(:unsafe_load_file)
60
+ Patch.send(:remove_method, :unsafe_load_file)
61
+ end
62
+ if Patch.method_defined?(:load_file) && ::YAML::VERSION >= '4'
63
+ Patch.send(:remove_method, :load_file)
64
+ end
65
+
55
66
  # MessagePack serializes symbols as strings by default.
56
67
  # We want them to roundtrip cleanly, so we use a custom factory.
57
68
  # see: https://github.com/msgpack/msgpack-ruby/pull/122
@@ -126,6 +137,27 @@ module Bootsnap
126
137
  end
127
138
 
128
139
  ruby2_keywords :load_file if respond_to?(:ruby2_keywords, true)
140
+
141
+ def unsafe_load_file(path, *args)
142
+ return super if args.size > 1
143
+ if kwargs = args.first
144
+ return super unless kwargs.is_a?(Hash)
145
+ return super unless (kwargs.keys - ::Bootsnap::CompileCache::YAML.supported_options).empty?
146
+ end
147
+
148
+ begin
149
+ ::Bootsnap::CompileCache::Native.fetch(
150
+ Bootsnap::CompileCache::YAML.cache_dir,
151
+ File.realpath(path),
152
+ ::Bootsnap::CompileCache::YAML,
153
+ kwargs,
154
+ )
155
+ rescue Errno::EACCES
156
+ ::Bootsnap::CompileCache.permission_error(path)
157
+ end
158
+ end
159
+
160
+ ruby2_keywords :unsafe_load_file if respond_to?(:ruby2_keywords, true)
129
161
  end
130
162
  end
131
163
  end
@@ -4,7 +4,7 @@ module Bootsnap
4
4
  Error = Class.new(StandardError)
5
5
  PermissionError = Class.new(Error)
6
6
 
7
- def self.setup(cache_dir:, iseq:, yaml:)
7
+ def self.setup(cache_dir:, iseq:, yaml:, json:)
8
8
  if iseq
9
9
  if supported?
10
10
  require_relative('compile_cache/iseq')
@@ -22,6 +22,15 @@ module Bootsnap
22
22
  warn("[bootsnap/setup] YAML parsing caching is not supported on this implementation of Ruby")
23
23
  end
24
24
  end
25
+
26
+ if json
27
+ if supported?
28
+ require_relative('compile_cache/json')
29
+ Bootsnap::CompileCache::JSON.install!(cache_dir)
30
+ elsif $VERBOSE
31
+ warn("[bootsnap/setup] JSON parsing caching is not supported on this implementation of Ruby")
32
+ end
33
+ end
25
34
  end
26
35
 
27
36
  def self.permission_error(path)
@@ -44,14 +44,20 @@ module Bootsnap
44
44
 
45
45
  # Try to resolve this feature to an absolute path without traversing the
46
46
  # loadpath.
47
- def find(feature)
47
+ def find(feature, try_extensions: true)
48
48
  reinitialize if (@has_relative_paths && dir_changed?) || stale?
49
49
  feature = feature.to_s.freeze
50
+
50
51
  return feature if absolute_path?(feature)
51
- return expand_path(feature) if feature.start_with?('./')
52
+
53
+ if feature.start_with?('./', '../')
54
+ return try_extensions ? expand_path(feature) : File.expand_path(feature).freeze
55
+ end
56
+
52
57
  @mutex.synchronize do
53
- x = search_index(feature)
58
+ x = search_index(feature, try_extensions: try_extensions)
54
59
  return x if x
60
+ return unless try_extensions
55
61
 
56
62
  # Ruby has some built-in features that require lies about.
57
63
  # For example, 'enumerator' is built in. If you require it, ruby
@@ -177,16 +183,24 @@ module Bootsnap
177
183
  end
178
184
 
179
185
  if DLEXT2
180
- def search_index(f)
181
- try_index(f + DOT_RB) || try_index(f + DLEXT) || try_index(f + DLEXT2) || try_index(f)
186
+ def search_index(f, try_extensions: true)
187
+ if try_extensions
188
+ try_index(f + DOT_RB) || try_index(f + DLEXT) || try_index(f + DLEXT2) || try_index(f)
189
+ else
190
+ try_index(f)
191
+ end
182
192
  end
183
193
 
184
194
  def maybe_append_extension(f)
185
195
  try_ext(f + DOT_RB) || try_ext(f + DLEXT) || try_ext(f + DLEXT2) || f
186
196
  end
187
197
  else
188
- def search_index(f)
189
- try_index(f + DOT_RB) || try_index(f + DLEXT) || try_index(f)
198
+ def search_index(f, try_extensions: true)
199
+ if try_extensions
200
+ try_index(f + DOT_RB) || try_index(f + DLEXT) || try_index(f)
201
+ else
202
+ try_index(f)
203
+ end
190
204
  end
191
205
 
192
206
  def maybe_append_extension(f)
@@ -196,7 +210,7 @@ module Bootsnap
196
210
 
197
211
  s = rand.to_s.force_encoding(Encoding::US_ASCII).freeze
198
212
  if s.respond_to?(:-@)
199
- if (-s).equal?(s) && (-s.dup).equal?(s)
213
+ if (-s).equal?(s) && (-s.dup).equal?(s) || RUBY_VERSION >= '2.7'
200
214
  def try_index(f)
201
215
  if (p = @index[f])
202
216
  -(File.join(p, f).freeze)
@@ -15,11 +15,13 @@ module Bootsnap
15
15
  @lpc_observer.push_paths(self, *entries.map(&:to_s))
16
16
  super
17
17
  end
18
+ alias_method :append, :push
18
19
 
19
20
  def unshift(*entries)
20
21
  @lpc_observer.unshift_paths(self, *entries.map(&:to_s))
21
22
  super
22
23
  end
24
+ alias_method :prepend, :unshift
23
25
 
24
26
  def concat(entries)
25
27
  @lpc_observer.push_paths(self, *entries.map(&:to_s))
@@ -47,33 +47,18 @@ module Kernel
47
47
 
48
48
  alias_method(:require_relative_without_bootsnap, :require_relative)
49
49
  def require_relative(path)
50
+ location = caller_locations(1..1).first
50
51
  realpath = Bootsnap::LoadPathCache.realpath_cache.call(
51
- caller_locations(1..1).first.absolute_path, path
52
+ location.absolute_path || location.path, path
52
53
  )
53
54
  require(realpath)
54
55
  end
55
56
 
56
57
  alias_method(:load_without_bootsnap, :load)
57
58
  def load(path, wrap = false)
58
- if (resolved = Bootsnap::LoadPathCache.load_path_cache.find(path))
59
- return load_without_bootsnap(resolved, wrap)
60
- end
61
-
62
- # load also allows relative paths from pwd even when not in $:
63
- if File.exist?(relative = File.expand_path(path).freeze)
64
- return load_without_bootsnap(relative, wrap)
65
- end
66
-
67
- raise(Bootsnap::LoadPathCache::CoreExt.make_load_error(path))
68
- rescue LoadError => e
69
- e.instance_variable_set(Bootsnap::LoadPathCache::ERROR_TAG_IVAR, true)
70
- raise(e)
71
- rescue Bootsnap::LoadPathCache::ReturnFalse
72
- false
73
- rescue Bootsnap::LoadPathCache::FallbackScan
74
- fallback = true
75
- ensure
76
- if fallback
59
+ if (resolved = Bootsnap::LoadPathCache.load_path_cache.find(path, try_extensions: false))
60
+ load_without_bootsnap(resolved, wrap)
61
+ else
77
62
  load_without_bootsnap(path, wrap)
78
63
  end
79
64
  end
@@ -58,9 +58,9 @@ module Bootsnap
58
58
  end
59
59
 
60
60
  def purge_multi(features)
61
- rejected_hashes = features.map(&:hash).to_set
61
+ rejected_hashes = features.each_with_object({}) { |f, h| h[f.hash] = true }
62
62
  @mutex.synchronize do
63
- @lfi.reject! { |_, hash| rejected_hashes.include?(hash) }
63
+ @lfi.reject! { |_, hash| rejected_hashes.key?(hash) }
64
64
  end
65
65
  end
66
66
 
@@ -84,10 +84,18 @@ module Bootsnap
84
84
  # entry.
85
85
  def register(short, long = nil)
86
86
  if long.nil?
87
- pat = %r{/#{Regexp.escape(short)}(\.[^/]+)?$}
88
87
  len = $LOADED_FEATURES.size
89
88
  ret = yield
90
- long = $LOADED_FEATURES[len..-1].detect { |feat| feat =~ pat }
89
+ long = $LOADED_FEATURES[len..-1].detect do |feat|
90
+ offset = 0
91
+ while offset = feat.index(short, offset)
92
+ if feat.index(".", offset + 1) && !feat.index("/", offset + 2)
93
+ break true
94
+ else
95
+ offset += 1
96
+ end
97
+ end
98
+ end
91
99
  else
92
100
  ret = yield
93
101
  end
@@ -91,6 +91,7 @@ module Bootsnap
91
91
  FileUtils.mv(tmp, @store_path)
92
92
  rescue Errno::EEXIST
93
93
  retry
94
+ rescue SystemCallError
94
95
  end
95
96
  end
96
97
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Bootsnap
3
- VERSION = "1.7.3"
3
+ VERSION = "1.9.3"
4
4
  end
data/lib/bootsnap.rb CHANGED
@@ -27,7 +27,9 @@ module Bootsnap
27
27
 
28
28
  def self.instrumentation=(callback)
29
29
  @instrumentation = callback
30
- self.instrumentation_enabled = !!callback
30
+ if respond_to?(:instrumentation_enabled=, true)
31
+ self.instrumentation_enabled = !!callback
32
+ end
31
33
  end
32
34
 
33
35
  def self._instrument(event, path)
@@ -41,7 +43,8 @@ module Bootsnap
41
43
  autoload_paths_cache: nil,
42
44
  disable_trace: nil,
43
45
  compile_cache_iseq: true,
44
- compile_cache_yaml: true
46
+ compile_cache_yaml: true,
47
+ compile_cache_json: true
45
48
  )
46
49
  unless autoload_paths_cache.nil?
47
50
  warn "[DEPRECATED] Bootsnap's `autoload_paths_cache:` option is deprecated and will be removed. " \
@@ -67,7 +70,8 @@ module Bootsnap
67
70
  Bootsnap::CompileCache.setup(
68
71
  cache_dir: cache_dir + '/bootsnap/compile-cache',
69
72
  iseq: compile_cache_iseq,
70
- yaml: compile_cache_yaml
73
+ yaml: compile_cache_yaml,
74
+ json: compile_cache_json,
71
75
  )
72
76
  end
73
77
 
@@ -111,6 +115,7 @@ module Bootsnap
111
115
  load_path_cache: !ENV['DISABLE_BOOTSNAP_LOAD_PATH_CACHE'],
112
116
  compile_cache_iseq: !ENV['DISABLE_BOOTSNAP_COMPILE_CACHE'] && iseq_cache_supported?,
113
117
  compile_cache_yaml: !ENV['DISABLE_BOOTSNAP_COMPILE_CACHE'],
118
+ compile_cache_json: !ENV['DISABLE_BOOTSNAP_COMPILE_CACHE'],
114
119
  )
115
120
 
116
121
  if ENV['BOOTSNAP_LOG']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootsnap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.3
4
+ version: 1.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Burke Libbey
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-22 00:00:00.000000000 Z
11
+ date: 2021-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -42,14 +42,14 @@ dependencies:
42
42
  name: rake-compiler
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
@@ -116,6 +116,7 @@ files:
116
116
  - lib/bootsnap/cli/worker_pool.rb
117
117
  - lib/bootsnap/compile_cache.rb
118
118
  - lib/bootsnap/compile_cache/iseq.rb
119
+ - lib/bootsnap/compile_cache/json.rb
119
120
  - lib/bootsnap/compile_cache/yaml.rb
120
121
  - lib/bootsnap/explicit_require.rb
121
122
  - lib/bootsnap/load_path_cache.rb
@@ -153,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
154
  - !ruby/object:Gem::Version
154
155
  version: '0'
155
156
  requirements: []
156
- rubygems_version: 3.0.3
157
+ rubygems_version: 3.2.20
157
158
  signing_key:
158
159
  specification_version: 4
159
160
  summary: Boot large ruby/rails apps faster