bootsnap 1.9.4 → 1.12.0
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/CHANGELOG.md +76 -3
- data/LICENSE.txt +1 -1
- data/README.md +4 -4
- data/exe/bootsnap +1 -1
- data/ext/bootsnap/bootsnap.c +47 -84
- data/ext/bootsnap/extconf.rb +13 -11
- data/lib/bootsnap/bundler.rb +1 -0
- data/lib/bootsnap/cli/worker_pool.rb +1 -0
- data/lib/bootsnap/cli.rb +49 -49
- data/lib/bootsnap/compile_cache/iseq.rb +16 -11
- data/lib/bootsnap/compile_cache/json.rb +18 -9
- data/lib/bootsnap/compile_cache/yaml.rb +264 -77
- data/lib/bootsnap/compile_cache.rb +11 -7
- data/lib/bootsnap/explicit_require.rb +4 -3
- data/lib/bootsnap/load_path_cache/cache.rb +46 -30
- data/lib/bootsnap/load_path_cache/change_observer.rb +2 -0
- data/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb +26 -72
- data/lib/bootsnap/load_path_cache/core_ext/loaded_features.rb +1 -0
- data/lib/bootsnap/load_path_cache/loaded_features_index.rb +32 -34
- data/lib/bootsnap/load_path_cache/path.rb +29 -5
- data/lib/bootsnap/load_path_cache/path_scanner.rb +6 -5
- data/lib/bootsnap/load_path_cache/store.rb +36 -13
- data/lib/bootsnap/load_path_cache.rb +16 -24
- data/lib/bootsnap/setup.rb +2 -1
- data/lib/bootsnap/version.rb +2 -1
- data/lib/bootsnap.rb +111 -99
- metadata +6 -77
- data/lib/bootsnap/load_path_cache/realpath_cache.rb +0 -32
data/lib/bootsnap.rb
CHANGED
|
@@ -1,136 +1,148 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative(
|
|
4
|
-
require_relative(
|
|
5
|
-
require_relative(
|
|
6
|
-
require_relative(
|
|
3
|
+
require_relative("bootsnap/version")
|
|
4
|
+
require_relative("bootsnap/bundler")
|
|
5
|
+
require_relative("bootsnap/load_path_cache")
|
|
6
|
+
require_relative("bootsnap/compile_cache")
|
|
7
7
|
|
|
8
8
|
module Bootsnap
|
|
9
9
|
InvalidConfiguration = Class.new(StandardError)
|
|
10
10
|
|
|
11
11
|
class << self
|
|
12
12
|
attr_reader :logger
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def self.log!
|
|
16
|
-
self.logger = $stderr.method(:puts)
|
|
17
|
-
end
|
|
18
13
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if logger.respond_to?(:debug)
|
|
22
|
-
self.instrumentation = ->(event, path) { @logger.debug("[Bootsnap] #{event} #{path}") }
|
|
23
|
-
else
|
|
24
|
-
self.instrumentation = ->(event, path) { @logger.call("[Bootsnap] #{event} #{path}") }
|
|
14
|
+
def log!
|
|
15
|
+
self.logger = $stderr.method(:puts)
|
|
25
16
|
end
|
|
26
|
-
end
|
|
27
17
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
18
|
+
def logger=(logger)
|
|
19
|
+
@logger = logger
|
|
20
|
+
self.instrumentation = if logger.respond_to?(:debug)
|
|
21
|
+
->(event, path) { @logger.debug("[Bootsnap] #{event} #{path}") }
|
|
22
|
+
else
|
|
23
|
+
->(event, path) { @logger.call("[Bootsnap] #{event} #{path}") }
|
|
24
|
+
end
|
|
32
25
|
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def self._instrument(event, path)
|
|
36
|
-
@instrumentation.call(event, path)
|
|
37
|
-
end
|
|
38
26
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
disable_trace: nil,
|
|
45
|
-
compile_cache_iseq: true,
|
|
46
|
-
compile_cache_yaml: true,
|
|
47
|
-
compile_cache_json: true
|
|
48
|
-
)
|
|
49
|
-
unless autoload_paths_cache.nil?
|
|
50
|
-
warn "[DEPRECATED] Bootsnap's `autoload_paths_cache:` option is deprecated and will be removed. " \
|
|
51
|
-
"If you use Zeitwerk this option is useless, and if you are still using the classic autoloader " \
|
|
52
|
-
"upgrading is recommended."
|
|
27
|
+
def instrumentation=(callback)
|
|
28
|
+
@instrumentation = callback
|
|
29
|
+
if respond_to?(:instrumentation_enabled=, true)
|
|
30
|
+
self.instrumentation_enabled = !!callback
|
|
31
|
+
end
|
|
53
32
|
end
|
|
54
33
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"If you use Ruby 2.5 or newer this option is useless, if not upgrading is recommended."
|
|
34
|
+
def _instrument(event, path)
|
|
35
|
+
@instrumentation.call(event, path)
|
|
58
36
|
end
|
|
59
37
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
38
|
+
def setup(
|
|
39
|
+
cache_dir:,
|
|
40
|
+
development_mode: true,
|
|
41
|
+
load_path_cache: true,
|
|
42
|
+
autoload_paths_cache: nil,
|
|
43
|
+
disable_trace: nil,
|
|
44
|
+
compile_cache_iseq: true,
|
|
45
|
+
compile_cache_yaml: true,
|
|
46
|
+
compile_cache_json: true
|
|
47
|
+
)
|
|
48
|
+
unless autoload_paths_cache.nil?
|
|
49
|
+
warn "[DEPRECATED] Bootsnap's `autoload_paths_cache:` option is deprecated and will be removed. " \
|
|
50
|
+
"If you use Zeitwerk this option is useless, and if you are still using the classic autoloader " \
|
|
51
|
+
"upgrading is recommended."
|
|
52
|
+
end
|
|
64
53
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
54
|
+
unless disable_trace.nil?
|
|
55
|
+
warn "[DEPRECATED] Bootsnap's `disable_trace:` option is deprecated and will be removed. " \
|
|
56
|
+
"If you use Ruby 2.5 or newer this option is useless, if not upgrading is recommended."
|
|
57
|
+
end
|
|
69
58
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
json: compile_cache_json,
|
|
75
|
-
)
|
|
76
|
-
end
|
|
59
|
+
if compile_cache_iseq && !iseq_cache_supported?
|
|
60
|
+
warn "Ruby 2.5 has a bug that break code tracing when code is loaded from cache. It is recommened " \
|
|
61
|
+
"to turn `compile_cache_iseq` off on Ruby 2.5"
|
|
62
|
+
end
|
|
77
63
|
|
|
78
|
-
|
|
79
|
-
|
|
64
|
+
if load_path_cache
|
|
65
|
+
Bootsnap::LoadPathCache.setup(
|
|
66
|
+
cache_path: cache_dir + "/bootsnap/load-path-cache",
|
|
67
|
+
development_mode: development_mode,
|
|
68
|
+
)
|
|
69
|
+
end
|
|
80
70
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
71
|
+
Bootsnap::CompileCache.setup(
|
|
72
|
+
cache_dir: cache_dir + "/bootsnap/compile-cache",
|
|
73
|
+
iseq: compile_cache_iseq,
|
|
74
|
+
yaml: compile_cache_yaml,
|
|
75
|
+
json: compile_cache_json,
|
|
76
|
+
)
|
|
77
|
+
end
|
|
84
78
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
development_mode = ['', nil, 'development'].include?(env)
|
|
79
|
+
def iseq_cache_supported?
|
|
80
|
+
return @iseq_cache_supported if defined? @iseq_cache_supported
|
|
88
81
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
config_dir_frame = caller.detect do |line|
|
|
93
|
-
line.include?('/config/')
|
|
94
|
-
end
|
|
82
|
+
ruby_version = Gem::Version.new(RUBY_VERSION)
|
|
83
|
+
@iseq_cache_supported = ruby_version < Gem::Version.new("2.5.0") || ruby_version >= Gem::Version.new("2.6.0")
|
|
84
|
+
end
|
|
95
85
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
$stderr.puts("[bootsnap/setup] 2. Define the environment variable BOOTSNAP_CACHE_DIR")
|
|
86
|
+
def default_setup
|
|
87
|
+
env = ENV["RAILS_ENV"] || ENV["RACK_ENV"] || ENV["ENV"]
|
|
88
|
+
development_mode = ["", nil, "development"].include?(env)
|
|
100
89
|
|
|
101
|
-
|
|
102
|
-
|
|
90
|
+
unless ENV["DISABLE_BOOTSNAP"]
|
|
91
|
+
cache_dir = ENV["BOOTSNAP_CACHE_DIR"]
|
|
92
|
+
unless cache_dir
|
|
93
|
+
config_dir_frame = caller.detect do |line|
|
|
94
|
+
line.include?("/config/")
|
|
95
|
+
end
|
|
103
96
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
97
|
+
unless config_dir_frame
|
|
98
|
+
$stderr.puts("[bootsnap/setup] couldn't infer cache directory! Either:")
|
|
99
|
+
$stderr.puts("[bootsnap/setup] 1. require bootsnap/setup from your application's config directory; or")
|
|
100
|
+
$stderr.puts("[bootsnap/setup] 2. Define the environment variable BOOTSNAP_CACHE_DIR")
|
|
107
101
|
|
|
108
|
-
|
|
109
|
-
|
|
102
|
+
raise("couldn't infer bootsnap cache directory")
|
|
103
|
+
end
|
|
110
104
|
|
|
105
|
+
path = config_dir_frame.split(/:\d+:/).first
|
|
106
|
+
path = File.dirname(path) until File.basename(path) == "config"
|
|
107
|
+
app_root = File.dirname(path)
|
|
111
108
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
development_mode: development_mode,
|
|
115
|
-
load_path_cache: !ENV['DISABLE_BOOTSNAP_LOAD_PATH_CACHE'],
|
|
116
|
-
compile_cache_iseq: !ENV['DISABLE_BOOTSNAP_COMPILE_CACHE'] && iseq_cache_supported?,
|
|
117
|
-
compile_cache_yaml: !ENV['DISABLE_BOOTSNAP_COMPILE_CACHE'],
|
|
118
|
-
compile_cache_json: !ENV['DISABLE_BOOTSNAP_COMPILE_CACHE'],
|
|
119
|
-
)
|
|
109
|
+
cache_dir = File.join(app_root, "tmp", "cache")
|
|
110
|
+
end
|
|
120
111
|
|
|
121
|
-
|
|
122
|
-
|
|
112
|
+
setup(
|
|
113
|
+
cache_dir: cache_dir,
|
|
114
|
+
development_mode: development_mode,
|
|
115
|
+
load_path_cache: !ENV["DISABLE_BOOTSNAP_LOAD_PATH_CACHE"],
|
|
116
|
+
compile_cache_iseq: !ENV["DISABLE_BOOTSNAP_COMPILE_CACHE"] && iseq_cache_supported?,
|
|
117
|
+
compile_cache_yaml: !ENV["DISABLE_BOOTSNAP_COMPILE_CACHE"],
|
|
118
|
+
compile_cache_json: !ENV["DISABLE_BOOTSNAP_COMPILE_CACHE"],
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
if ENV["BOOTSNAP_LOG"]
|
|
122
|
+
log!
|
|
123
|
+
end
|
|
123
124
|
end
|
|
124
125
|
end
|
|
125
|
-
end
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
if RbConfig::CONFIG["host_os"] =~ /mswin|mingw|cygwin/
|
|
128
|
+
def absolute_path?(path)
|
|
129
|
+
path[1] == ":"
|
|
130
|
+
end
|
|
131
|
+
else
|
|
132
|
+
def absolute_path?(path)
|
|
133
|
+
path.start_with?("/")
|
|
134
|
+
end
|
|
130
135
|
end
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
136
|
+
|
|
137
|
+
# This is a semi-accurate ruby implementation of the native `rb_get_path(VALUE)` function.
|
|
138
|
+
# The native version is very intricate and may behave differently on windows etc.
|
|
139
|
+
# But we only use it for non-MRI platform.
|
|
140
|
+
def rb_get_path(fname)
|
|
141
|
+
path_path = fname.respond_to?(:to_path) ? fname.to_path : fname
|
|
142
|
+
String.try_convert(path_path) || raise(TypeError, "no implicit conversion of #{path_path.class} into String")
|
|
134
143
|
end
|
|
144
|
+
|
|
145
|
+
# Allow the C extension to redefine `rb_get_path` without warning.
|
|
146
|
+
alias_method :rb_get_path, :rb_get_path # rubocop:disable Lint/DuplicateMethods
|
|
135
147
|
end
|
|
136
148
|
end
|
metadata
CHANGED
|
@@ -1,99 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bootsnap
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.12.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Burke Libbey
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-05-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
-
- !ruby/object:Gem::Dependency
|
|
14
|
-
name: bundler
|
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
|
16
|
-
requirements:
|
|
17
|
-
- - ">="
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: '0'
|
|
20
|
-
type: :development
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - ">="
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: '0'
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: rake
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - ">="
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0'
|
|
34
|
-
type: :development
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - ">="
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0'
|
|
41
|
-
- !ruby/object:Gem::Dependency
|
|
42
|
-
name: rake-compiler
|
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - ">="
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '0'
|
|
48
|
-
type: :development
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - ">="
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '0'
|
|
55
|
-
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: minitest
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - "~>"
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: '5.0'
|
|
62
|
-
type: :development
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - "~>"
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: '5.0'
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: mocha
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - "~>"
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '1.2'
|
|
76
|
-
type: :development
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - "~>"
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: '1.2'
|
|
83
13
|
- !ruby/object:Gem::Dependency
|
|
84
14
|
name: msgpack
|
|
85
15
|
requirement: !ruby/object:Gem::Requirement
|
|
86
16
|
requirements:
|
|
87
17
|
- - "~>"
|
|
88
18
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '1.
|
|
19
|
+
version: '1.2'
|
|
90
20
|
type: :runtime
|
|
91
21
|
prerelease: false
|
|
92
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
23
|
requirements:
|
|
94
24
|
- - "~>"
|
|
95
25
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '1.
|
|
26
|
+
version: '1.2'
|
|
97
27
|
description: Boot large ruby/rails apps faster
|
|
98
28
|
email:
|
|
99
29
|
- burke.libbey@shopify.com
|
|
@@ -127,7 +57,6 @@ files:
|
|
|
127
57
|
- lib/bootsnap/load_path_cache/loaded_features_index.rb
|
|
128
58
|
- lib/bootsnap/load_path_cache/path.rb
|
|
129
59
|
- lib/bootsnap/load_path_cache/path_scanner.rb
|
|
130
|
-
- lib/bootsnap/load_path_cache/realpath_cache.rb
|
|
131
60
|
- lib/bootsnap/load_path_cache/store.rb
|
|
132
61
|
- lib/bootsnap/setup.rb
|
|
133
62
|
- lib/bootsnap/version.rb
|
|
@@ -136,7 +65,7 @@ licenses:
|
|
|
136
65
|
- MIT
|
|
137
66
|
metadata:
|
|
138
67
|
bug_tracker_uri: https://github.com/Shopify/bootsnap/issues
|
|
139
|
-
changelog_uri: https://github.com/Shopify/bootsnap/blob/
|
|
68
|
+
changelog_uri: https://github.com/Shopify/bootsnap/blob/main/CHANGELOG.md
|
|
140
69
|
source_code_uri: https://github.com/Shopify/bootsnap
|
|
141
70
|
allowed_push_host: https://rubygems.org
|
|
142
71
|
post_install_message:
|
|
@@ -147,7 +76,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
147
76
|
requirements:
|
|
148
77
|
- - ">="
|
|
149
78
|
- !ruby/object:Gem::Version
|
|
150
|
-
version: 2.
|
|
79
|
+
version: 2.4.0
|
|
151
80
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
152
81
|
requirements:
|
|
153
82
|
- - ">="
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Bootsnap
|
|
4
|
-
module LoadPathCache
|
|
5
|
-
class RealpathCache
|
|
6
|
-
def initialize
|
|
7
|
-
@cache = Hash.new { |h, k| h[k] = realpath(*k) }
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def call(*key)
|
|
11
|
-
@cache[key]
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
private
|
|
15
|
-
|
|
16
|
-
def realpath(caller_location, path)
|
|
17
|
-
base = File.dirname(caller_location)
|
|
18
|
-
abspath = File.expand_path(path, base).freeze
|
|
19
|
-
find_file(abspath)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def find_file(name)
|
|
23
|
-
return File.realpath(name).freeze if File.exist?(name)
|
|
24
|
-
CACHED_EXTENSIONS.each do |ext|
|
|
25
|
-
filename = "#{name}#{ext}"
|
|
26
|
-
return File.realpath(filename).freeze if File.exist?(filename)
|
|
27
|
-
end
|
|
28
|
-
name
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|