bootsnap 1.9.2 → 1.10.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative('../explicit_require')
3
+ require_relative("../explicit_require")
4
4
 
5
5
  module Bootsnap
6
6
  module LoadPathCache
@@ -28,15 +28,16 @@ module Bootsnap
28
28
  BUILTIN_FEATURES = $LOADED_FEATURES.each_with_object({}) do |feat, features|
29
29
  # Builtin features are of the form 'enumerator.so'.
30
30
  # All others include paths.
31
- next unless feat.size < 20 && !feat.include?('/')
31
+ next unless feat.size < 20 && !feat.include?("/")
32
32
 
33
- base = File.basename(feat, '.*') # enumerator.so -> enumerator
33
+ base = File.basename(feat, ".*") # enumerator.so -> enumerator
34
34
  ext = File.extname(feat) # .so
35
35
 
36
36
  features[feat] = nil # enumerator.so
37
37
  features[base] = nil # enumerator
38
38
 
39
39
  next unless [DOT_SO, *DL_EXTENSIONS].include?(ext)
40
+
40
41
  DL_EXTENSIONS.each do |dl_ext|
41
42
  features["#{base}#{dl_ext}"] = nil # enumerator.bundle
42
43
  end
@@ -48,9 +49,9 @@ module Bootsnap
48
49
  reinitialize if (@has_relative_paths && dir_changed?) || stale?
49
50
  feature = feature.to_s.freeze
50
51
 
51
- return feature if absolute_path?(feature)
52
+ return feature if Bootsnap.absolute_path?(feature)
52
53
 
53
- if feature.start_with?('./', '../')
54
+ if feature.start_with?("./", "../")
54
55
  return try_extensions ? expand_path(feature) : File.expand_path(feature).freeze
55
56
  end
56
57
 
@@ -64,7 +65,7 @@ module Bootsnap
64
65
  # returns false as if it were already loaded; however, there is no
65
66
  # file to find on disk. We've pre-built a list of these, and we
66
67
  # return false if any of them is loaded.
67
- raise(LoadPathCache::ReturnFalse, '', []) if BUILTIN_FEATURES.key?(feature)
68
+ raise(LoadPathCache::ReturnFalse, "", []) if BUILTIN_FEATURES.key?(feature)
68
69
 
69
70
  # The feature wasn't found on our preliminary search through the index.
70
71
  # We resolve this differently depending on what the extension was.
@@ -73,13 +74,14 @@ module Bootsnap
73
74
  # native dynamic extension, e.g. .bundle or .so), we know it was a
74
75
  # failure and there's nothing more we can do to find the file.
75
76
  # no extension, .rb, (.bundle or .so)
76
- when '', *CACHED_EXTENSIONS
77
+ when "", *CACHED_EXTENSIONS
77
78
  nil
78
79
  # Ruby allows specifying native extensions as '.so' even when DLEXT
79
80
  # is '.bundle'. This is where we handle that case.
80
81
  when DOT_SO
81
82
  x = search_index(feature[0..-4] + DLEXT)
82
83
  return x if x
84
+
83
85
  if DLEXT2
84
86
  x = search_index(feature[0..-4] + DLEXT2)
85
87
  return x if x
@@ -87,7 +89,7 @@ module Bootsnap
87
89
  else
88
90
  # other, unknown extension. For example, `.rake`. Since we haven't
89
91
  # cached these, we legitimately need to run the load path search.
90
- raise(LoadPathCache::FallbackScan, '', [])
92
+ raise(LoadPathCache::FallbackScan, "", [])
91
93
  end
92
94
  end
93
95
 
@@ -95,26 +97,18 @@ module Bootsnap
95
97
  # cases where the file doesn't appear to be on the load path. We should
96
98
  # be able to detect newly-created files without rebooting the
97
99
  # application.
98
- raise(LoadPathCache::FallbackScan, '', []) if @development_mode
99
- end
100
-
101
- if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
102
- def absolute_path?(path)
103
- path[1] == ':'
104
- end
105
- else
106
- def absolute_path?(path)
107
- path.start_with?(SLASH)
108
- end
100
+ raise(LoadPathCache::FallbackScan, "", []) if @development_mode
109
101
  end
110
102
 
111
103
  def unshift_paths(sender, *paths)
112
104
  return unless sender == @path_obj
105
+
113
106
  @mutex.synchronize { unshift_paths_locked(*paths) }
114
107
  end
115
108
 
116
109
  def push_paths(sender, *paths)
117
110
  return unless sender == @path_obj
111
+
118
112
  @mutex.synchronize { push_paths_locked(*paths) }
119
113
  end
120
114
 
@@ -147,6 +141,7 @@ module Bootsnap
147
141
  p = Path.new(path)
148
142
  @has_relative_paths = true if p.relative?
149
143
  next if p.non_directory?
144
+
150
145
  expanded_path = p.expanded_path
151
146
  entries, dirs = p.entries_and_dirs(@store)
152
147
  # push -> low precedence -> set only if unset
@@ -161,6 +156,7 @@ module Bootsnap
161
156
  paths.map(&:to_s).reverse_each do |path|
162
157
  p = Path.new(path)
163
158
  next if p.non_directory?
159
+
164
160
  expanded_path = p.expanded_path
165
161
  entries, dirs = p.entries_and_dirs(@store)
166
162
  # unshift -> high precedence -> unconditional set
@@ -183,56 +179,62 @@ module Bootsnap
183
179
  end
184
180
 
185
181
  if DLEXT2
186
- def search_index(f, try_extensions: true)
182
+ def search_index(feature, try_extensions: true)
187
183
  if try_extensions
188
- try_index(f + DOT_RB) || try_index(f + DLEXT) || try_index(f + DLEXT2) || try_index(f)
184
+ try_index(feature + DOT_RB) ||
185
+ try_index(feature + DLEXT) ||
186
+ try_index(feature + DLEXT2) ||
187
+ try_index(feature)
189
188
  else
190
- try_index(f)
189
+ try_index(feature)
191
190
  end
192
191
  end
193
192
 
194
- def maybe_append_extension(f)
195
- try_ext(f + DOT_RB) || try_ext(f + DLEXT) || try_ext(f + DLEXT2) || f
193
+ def maybe_append_extension(feature)
194
+ try_ext(feature + DOT_RB) ||
195
+ try_ext(feature + DLEXT) ||
196
+ try_ext(feature + DLEXT2) ||
197
+ feature
196
198
  end
197
199
  else
198
- def search_index(f, try_extensions: true)
200
+ def search_index(feature, try_extensions: true)
199
201
  if try_extensions
200
- try_index(f + DOT_RB) || try_index(f + DLEXT) || try_index(f)
202
+ try_index(feature + DOT_RB) || try_index(feature + DLEXT) || try_index(feature)
201
203
  else
202
- try_index(f)
204
+ try_index(feature)
203
205
  end
204
206
  end
205
207
 
206
- def maybe_append_extension(f)
207
- try_ext(f + DOT_RB) || try_ext(f + DLEXT) || f
208
+ def maybe_append_extension(feature)
209
+ try_ext(feature + DOT_RB) || try_ext(feature + DLEXT) || feature
208
210
  end
209
211
  end
210
212
 
211
213
  s = rand.to_s.force_encoding(Encoding::US_ASCII).freeze
212
214
  if s.respond_to?(:-@)
213
- if (-s).equal?(s) && (-s.dup).equal?(s) || RUBY_VERSION >= '2.7'
214
- def try_index(f)
215
- if (p = @index[f])
216
- -(File.join(p, f).freeze)
215
+ if (-s).equal?(s) && (-s.dup).equal?(s) || RUBY_VERSION >= "2.7"
216
+ def try_index(feature)
217
+ if (path = @index[feature])
218
+ -File.join(path, feature).freeze
217
219
  end
218
220
  end
219
221
  else
220
- def try_index(f)
221
- if (p = @index[f])
222
- -File.join(p, f).untaint
222
+ def try_index(feature)
223
+ if (path = @index[feature])
224
+ -File.join(path, feature).untaint
223
225
  end
224
226
  end
225
227
  end
226
228
  else
227
- def try_index(f)
228
- if (p = @index[f])
229
- File.join(p, f)
229
+ def try_index(feature)
230
+ if (path = @index[feature])
231
+ File.join(path, feature)
230
232
  end
231
233
  end
232
234
  end
233
235
 
234
- def try_ext(f)
235
- f if File.exist?(f)
236
+ def try_ext(feature)
237
+ feature if File.exist?(feature)
236
238
  end
237
239
  end
238
240
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Bootsnap
3
4
  module LoadPathCache
4
5
  module ChangeObserver
@@ -57,6 +58,7 @@ module Bootsnap
57
58
 
58
59
  def self.register(observer, arr)
59
60
  return if arr.frozen? # can't register observer, but no need to.
61
+
60
62
  arr.instance_variable_set(:@lpc_observer, observer)
61
63
  arr.extend(ArrayMixin)
62
64
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Bootsnap
3
4
  module LoadPathCache
4
5
  module CoreExt
@@ -13,35 +14,42 @@ module Bootsnap
13
14
  end
14
15
 
15
16
  module Kernel
16
- module_function # rubocop:disable Style/ModuleFunction
17
+ module_function
17
18
 
18
19
  alias_method(:require_without_bootsnap, :require)
19
20
 
20
- # Note that require registers to $LOADED_FEATURES while load does not.
21
- def require_with_bootsnap_lfi(path, resolved = nil)
22
- Bootsnap::LoadPathCache.loaded_features_index.register(path, resolved) do
23
- require_without_bootsnap(resolved || path)
24
- end
25
- end
26
-
27
21
  def require(path)
28
- return false if Bootsnap::LoadPathCache.loaded_features_index.key?(path)
22
+ fallback = false
23
+ string_path = path.to_s
24
+ return false if Bootsnap::LoadPathCache.loaded_features_index.key?(string_path)
29
25
 
30
- if (resolved = Bootsnap::LoadPathCache.load_path_cache.find(path))
31
- return require_with_bootsnap_lfi(path, resolved)
26
+ if (resolved = Bootsnap::LoadPathCache.load_path_cache.find(string_path))
27
+ # Note that require registers to $LOADED_FEATURES while load does not.
28
+ ret = require_without_bootsnap(resolved)
29
+ Bootsnap::LoadPathCache.loaded_features_index.register(string_path, resolved)
30
+ return ret
32
31
  end
33
32
 
34
33
  raise(Bootsnap::LoadPathCache::CoreExt.make_load_error(path))
35
- rescue LoadError => e
36
- e.instance_variable_set(Bootsnap::LoadPathCache::ERROR_TAG_IVAR, true)
37
- raise(e)
34
+ rescue LoadError => error
35
+ error.instance_variable_set(Bootsnap::LoadPathCache::ERROR_TAG_IVAR, true)
36
+ raise(error)
38
37
  rescue Bootsnap::LoadPathCache::ReturnFalse
39
38
  false
40
39
  rescue Bootsnap::LoadPathCache::FallbackScan
41
40
  fallback = true
42
41
  ensure
42
+ # We raise from `ensure` so that any further exception don't have FallbackScan as a cause
43
+ # See: https://github.com/Shopify/bootsnap/issues/250
43
44
  if fallback
44
- require_with_bootsnap_lfi(path)
45
+ if (cursor = Bootsnap::LoadPathCache.loaded_features_index.cursor(string_path))
46
+ ret = require_without_bootsnap(path)
47
+ resolved = Bootsnap::LoadPathCache.loaded_features_index.identify(string_path, cursor)
48
+ Bootsnap::LoadPathCache.loaded_features_index.register(string_path, resolved)
49
+ ret
50
+ else # If we're not given a cursor, it means we don't need to register the path (likely an absolute path)
51
+ require_without_bootsnap(path)
52
+ end
45
53
  end
46
54
  end
47
55
 
@@ -67,6 +75,7 @@ end
67
75
  class Module
68
76
  alias_method(:autoload_without_bootsnap, :autoload)
69
77
  def autoload(const, path)
78
+ fallback = false
70
79
  # NOTE: This may defeat LoadedFeaturesIndex, but it's not immediately
71
80
  # obvious how to make it work. This feels like a pretty niche case, unclear
72
81
  # if it will ever burn anyone.
@@ -75,14 +84,16 @@ class Module
75
84
  # added to $LOADED_FEATURES and won't be able to hook that modification
76
85
  # since it's done in C-land.
77
86
  autoload_without_bootsnap(const, Bootsnap::LoadPathCache.load_path_cache.find(path) || path)
78
- rescue LoadError => e
79
- e.instance_variable_set(Bootsnap::LoadPathCache::ERROR_TAG_IVAR, true)
80
- raise(e)
87
+ rescue LoadError => error
88
+ error.instance_variable_set(Bootsnap::LoadPathCache::ERROR_TAG_IVAR, true)
89
+ raise(error)
81
90
  rescue Bootsnap::LoadPathCache::ReturnFalse
82
91
  false
83
92
  rescue Bootsnap::LoadPathCache::FallbackScan
84
93
  fallback = true
85
94
  ensure
95
+ # We raise from `ensure` so that any further exception don't have FallbackScan as a cause
96
+ # See: https://github.com/Shopify/bootsnap/issues/250
86
97
  if fallback
87
98
  autoload_without_bootsnap(const, path)
88
99
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class << $LOADED_FEATURES
3
4
  alias_method(:delete_without_bootsnap, :delete)
4
5
  def delete(key)
@@ -29,14 +29,15 @@ module Bootsnap
29
29
  @mutex = Mutex.new
30
30
 
31
31
  # In theory the user could mutate $LOADED_FEATURES and invalidate our
32
- # cache. If this ever comes up in practice or if you, the
33
- # enterprising reader, feels inclined to solve this problem we could
32
+ # cache. If this ever comes up in practice - or if you, the
33
+ # enterprising reader, feels inclined to solve this problem - we could
34
34
  # parallel the work done with ChangeObserver on $LOAD_PATH to mirror
35
35
  # updates to our @lfi.
36
36
  $LOADED_FEATURES.each do |feat|
37
37
  hash = feat.hash
38
38
  $LOAD_PATH.each do |lpe|
39
39
  next unless feat.start_with?(lpe)
40
+
40
41
  # /a/b/lib/my/foo.rb
41
42
  # ^^^^^^^^^
42
43
  short = feat[(lpe.length + 1)..-1]
@@ -68,6 +69,25 @@ module Bootsnap
68
69
  @mutex.synchronize { @lfi.key?(feature) }
69
70
  end
70
71
 
72
+ def cursor(short)
73
+ unless Bootsnap.absolute_path?(short.to_s)
74
+ $LOADED_FEATURES.size
75
+ end
76
+ end
77
+
78
+ def identify(short, cursor)
79
+ $LOADED_FEATURES[cursor..-1].detect do |feat|
80
+ offset = 0
81
+ while (offset = feat.index(short, offset))
82
+ if feat.index(".", offset + 1) && !feat.index("/", offset + 2)
83
+ break true
84
+ else
85
+ offset += 1
86
+ end
87
+ end
88
+ end
89
+ end
90
+
71
91
  # There is a relatively uncommon case where we could miss adding an
72
92
  # entry:
73
93
  #
@@ -82,23 +102,8 @@ module Bootsnap
82
102
  # not quite right; or
83
103
  # 2. Inspect $LOADED_FEATURES upon return from yield to find the matching
84
104
  # entry.
85
- def register(short, long = nil)
86
- if long.nil?
87
- len = $LOADED_FEATURES.size
88
- ret = yield
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
99
- else
100
- ret = yield
101
- end
105
+ def register(short, long)
106
+ return if Bootsnap.absolute_path?(short)
102
107
 
103
108
  hash = long.hash
104
109
 
@@ -117,13 +122,11 @@ module Bootsnap
117
122
  @lfi[short] = hash
118
123
  (@lfi[altname] = hash) if altname
119
124
  end
120
-
121
- ret
122
125
  end
123
126
 
124
127
  private
125
128
 
126
- STRIP_EXTENSION = /\.[^.]*?$/
129
+ STRIP_EXTENSION = /\.[^.]*?$/.freeze
127
130
  private_constant(:STRIP_EXTENSION)
128
131
 
129
132
  # Might Ruby automatically search for this extension if
@@ -140,15 +143,15 @@ module Bootsnap
140
143
  # with calling a Ruby file 'x.dylib.rb' and then requiring it as 'x.dylib'.)
141
144
  #
142
145
  # See <https://ruby-doc.org/core-2.6.4/Kernel.html#method-i-require>.
143
- def extension_elidable?(f)
144
- f.to_s.end_with?('.rb', '.so', '.o', '.dll', '.dylib')
146
+ def extension_elidable?(feature)
147
+ feature.to_s.end_with?(".rb", ".so", ".o", ".dll", ".dylib")
145
148
  end
146
149
 
147
- def strip_extension_if_elidable(f)
148
- if extension_elidable?(f)
149
- f.sub(STRIP_EXTENSION, '')
150
+ def strip_extension_if_elidable(feature)
151
+ if extension_elidable?(feature)
152
+ feature.sub(STRIP_EXTENSION, "")
150
153
  else
151
- f
154
+ feature
152
155
  end
153
156
  end
154
157
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
- require_relative('path_scanner')
2
+
3
+ require_relative("path_scanner")
3
4
 
4
5
  module Bootsnap
5
6
  module LoadPathCache
@@ -43,6 +44,7 @@ module Bootsnap
43
44
  # set to zero anyway, just in case we change the stability heuristics.
44
45
  _, entries, dirs = store.get(expanded_path)
45
46
  return [entries, dirs] if entries # cache hit
47
+
46
48
  entries, dirs = scan!
47
49
  store.set(expanded_path, [0, entries, dirs])
48
50
  return [entries, dirs]
@@ -93,8 +95,8 @@ module Bootsnap
93
95
 
94
96
  # Built-in ruby lib stuff doesn't change, but things can occasionally be
95
97
  # installed into sitedir, which generally lives under libdir.
96
- RUBY_LIBDIR = RbConfig::CONFIG['libdir']
97
- RUBY_SITEDIR = RbConfig::CONFIG['sitedir']
98
+ RUBY_LIBDIR = RbConfig::CONFIG["libdir"]
99
+ RUBY_SITEDIR = RbConfig::CONFIG["sitedir"]
98
100
 
99
101
  def stability
100
102
  @stability ||= begin
@@ -1,18 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative('../explicit_require')
3
+ require_relative("../explicit_require")
4
4
 
5
5
  module Bootsnap
6
6
  module LoadPathCache
7
7
  module PathScanner
8
8
  REQUIRABLE_EXTENSIONS = [DOT_RB] + DL_EXTENSIONS
9
9
  NORMALIZE_NATIVE_EXTENSIONS = !DL_EXTENSIONS.include?(LoadPathCache::DOT_SO)
10
- ALTERNATIVE_NATIVE_EXTENSIONS_PATTERN = /\.(o|bundle|dylib)\z/
10
+ ALTERNATIVE_NATIVE_EXTENSIONS_PATTERN = /\.(o|bundle|dylib)\z/.freeze
11
11
 
12
12
  BUNDLE_PATH = if Bootsnap.bundler?
13
13
  (Bundler.bundle_path.cleanpath.to_s << LoadPathCache::SLASH).freeze
14
14
  else
15
- ''
15
+ ""
16
16
  end
17
17
 
18
18
  class << self
@@ -44,7 +44,8 @@ module Bootsnap
44
44
 
45
45
  def walk(absolute_dir_path, relative_dir_path, &block)
46
46
  Dir.foreach(absolute_dir_path) do |name|
47
- next if name.start_with?('.')
47
+ next if name.start_with?(".")
48
+
48
49
  relative_path = relative_dir_path ? File.join(relative_dir_path, name) : name
49
50
 
50
51
  absolute_path = "#{absolute_dir_path}/#{name}"
@@ -58,7 +59,7 @@ module Bootsnap
58
59
  end
59
60
  end
60
61
 
61
- if RUBY_VERSION >= '3.1'
62
+ if RUBY_VERSION >= "3.1"
62
63
  def os_path(path)
63
64
  path.freeze
64
65
  end
@@ -21,6 +21,7 @@ module Bootsnap
21
21
 
22
22
  def find_file(name)
23
23
  return File.realpath(name).freeze if File.exist?(name)
24
+
24
25
  CACHED_EXTENSIONS.each do |ext|
25
26
  filename = "#{name}#{ext}"
26
27
  return File.realpath(filename).freeze if File.exist?(filename)
@@ -1,12 +1,15 @@
1
1
  # frozen_string_literal: true
2
- require_relative('../explicit_require')
3
2
 
4
- Bootsnap::ExplicitRequire.with_gems('msgpack') { require('msgpack') }
5
- Bootsnap::ExplicitRequire.from_rubylibdir('fileutils')
3
+ require_relative("../explicit_require")
4
+
5
+ Bootsnap::ExplicitRequire.with_gems("msgpack") { require("msgpack") }
6
6
 
7
7
  module Bootsnap
8
8
  module LoadPathCache
9
9
  class Store
10
+ VERSION_KEY = "__bootsnap_ruby_version__"
11
+ CURRENT_VERSION = "#{RUBY_REVISION}-#{RUBY_PLATFORM}".freeze # rubocop:disable Style/RedundantFreeze
12
+
10
13
  NestedTransactionError = Class.new(StandardError)
11
14
  SetOutsideTransactionNotAllowed = Class.new(StandardError)
12
15
 
@@ -23,6 +26,7 @@ module Bootsnap
23
26
 
24
27
  def fetch(key)
25
28
  raise(SetOutsideTransactionNotAllowed) unless @txn_mutex.owned?
29
+
26
30
  v = get(key)
27
31
  unless v
28
32
  @dirty = true
@@ -34,6 +38,7 @@ module Bootsnap
34
38
 
35
39
  def set(key, value)
36
40
  raise(SetOutsideTransactionNotAllowed) unless @txn_mutex.owned?
41
+
37
42
  if value != @data[key]
38
43
  @dirty = true
39
44
  @data[key] = value
@@ -42,6 +47,7 @@ module Bootsnap
42
47
 
43
48
  def transaction
44
49
  raise(NestedTransactionError) if @txn_mutex.owned?
50
+
45
51
  @txn_mutex.synchronize do
46
52
  begin
47
53
  yield
@@ -62,15 +68,20 @@ module Bootsnap
62
68
 
63
69
  def load_data
64
70
  @data = begin
65
- File.open(@store_path, encoding: Encoding::BINARY) do |io|
71
+ data = File.open(@store_path, encoding: Encoding::BINARY) do |io|
66
72
  MessagePack.load(io)
67
73
  end
74
+ if data.is_a?(Hash) && data[VERSION_KEY] == CURRENT_VERSION
75
+ data
76
+ else
77
+ default_data
78
+ end
68
79
  # handle malformed data due to upgrade incompatibility
69
80
  rescue Errno::ENOENT, MessagePack::MalformedFormatError, MessagePack::UnknownExtTypeError, EOFError
70
- {}
81
+ default_data
71
82
  rescue ArgumentError => error
72
83
  if error.message =~ /negative array size/
73
- {}
84
+ default_data
74
85
  else
75
86
  raise
76
87
  end
@@ -78,9 +89,11 @@ module Bootsnap
78
89
  end
79
90
 
80
91
  def dump_data
92
+ require "fileutils" unless defined? FileUtils
93
+
81
94
  # Change contents atomically so other processes can't get invalid
82
95
  # caches if they read at an inopportune time.
83
- tmp = "#{@store_path}.#{Process.pid}.#{(rand * 100000).to_i}.tmp"
96
+ tmp = "#{@store_path}.#{Process.pid}.#{(rand * 100_000).to_i}.tmp"
84
97
  FileUtils.mkpath(File.dirname(tmp))
85
98
  exclusive_write = File::Constants::CREAT | File::Constants::EXCL | File::Constants::WRONLY
86
99
  # `encoding:` looks redundant wrt `binwrite`, but necessary on windows
@@ -93,6 +106,10 @@ module Bootsnap
93
106
  retry
94
107
  rescue SystemCallError
95
108
  end
109
+
110
+ def default_data
111
+ {VERSION_KEY => CURRENT_VERSION}
112
+ end
96
113
  end
97
114
  end
98
115
  end
@@ -5,9 +5,9 @@ module Bootsnap
5
5
  ReturnFalse = Class.new(StandardError)
6
6
  FallbackScan = Class.new(StandardError)
7
7
 
8
- DOT_RB = '.rb'
9
- DOT_SO = '.so'
10
- SLASH = '/'
8
+ DOT_RB = ".rb"
9
+ DOT_SO = ".so"
10
+ SLASH = "/"
11
11
 
12
12
  # If a NameError happens several levels deep, don't re-handle it
13
13
  # all the way up the chain: mark it once and bubble it up without
@@ -15,7 +15,7 @@ module Bootsnap
15
15
  ERROR_TAG_IVAR = :@__bootsnap_rescued
16
16
 
17
17
  DL_EXTENSIONS = ::RbConfig::CONFIG
18
- .values_at('DLEXT', 'DLEXT2')
18
+ .values_at("DLEXT", "DLEXT2")
19
19
  .reject { |ext| !ext || ext.empty? }
20
20
  .map { |ext| ".#{ext}" }
21
21
  .freeze
@@ -42,24 +42,24 @@ module Bootsnap
42
42
  @realpath_cache = RealpathCache.new
43
43
 
44
44
  @load_path_cache = Cache.new(store, $LOAD_PATH, development_mode: development_mode)
45
- require_relative('load_path_cache/core_ext/kernel_require')
46
- require_relative('load_path_cache/core_ext/loaded_features')
45
+ require_relative("load_path_cache/core_ext/kernel_require")
46
+ require_relative("load_path_cache/core_ext/loaded_features")
47
47
  end
48
48
 
49
49
  def supported?
50
- RUBY_ENGINE == 'ruby' &&
51
- RUBY_PLATFORM =~ /darwin|linux|bsd|mswin|mingw|cygwin/
50
+ RUBY_ENGINE == "ruby" &&
51
+ RUBY_PLATFORM =~ /darwin|linux|bsd|mswin|mingw|cygwin/
52
52
  end
53
53
  end
54
54
  end
55
55
  end
56
56
 
57
57
  if Bootsnap::LoadPathCache.supported?
58
- require_relative('load_path_cache/path_scanner')
59
- require_relative('load_path_cache/path')
60
- require_relative('load_path_cache/cache')
61
- require_relative('load_path_cache/store')
62
- require_relative('load_path_cache/change_observer')
63
- require_relative('load_path_cache/loaded_features_index')
64
- require_relative('load_path_cache/realpath_cache')
58
+ require_relative("load_path_cache/path_scanner")
59
+ require_relative("load_path_cache/path")
60
+ require_relative("load_path_cache/cache")
61
+ require_relative("load_path_cache/store")
62
+ require_relative("load_path_cache/change_observer")
63
+ require_relative("load_path_cache/loaded_features_index")
64
+ require_relative("load_path_cache/realpath_cache")
65
65
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
- require_relative('../bootsnap')
2
+
3
+ require_relative("../bootsnap")
3
4
 
4
5
  Bootsnap.default_setup
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Bootsnap
3
- VERSION = "1.9.2"
4
+ VERSION = "1.10.1"
4
5
  end