bootsnap 1.24.4 → 1.24.5
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 +5 -0
- data/lib/bootsnap/cli.rb +1 -1
- data/lib/bootsnap/compile_cache/iseq.rb +164 -137
- data/lib/bootsnap/version.rb +1 -1
- data/lib/bootsnap.rb +15 -11
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9f514d9a08cf2cbfa470c7d6745fe6388bfb4800a8cf659b9939bc57c93a67e1
|
|
4
|
+
data.tar.gz: e623cc84b0ce559e15eeb5ade64617ab6faff50a5004256ecdac5e93267ac5e0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 517950fbb71bbfc7e9ecbc0220849bc4c6fba0f410edb3d08db13d7e1e55f6602cef80c0636ed656cd76eab3c100da317a40d7cf7527dbf97bb4e2b250bc820f
|
|
7
|
+
data.tar.gz: 97fdc6fee1ac2945fba9b79ec3e6b8d65f265c5e90fc9da16ced08aff3b09f6f516bcdec46aa703452666dfbfaff3db319b912282f0bb1b5ed3d355d0a24e5a0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Unreleased
|
|
2
2
|
|
|
3
|
+
# 1.24.5
|
|
4
|
+
|
|
5
|
+
* No longer load the config file by default when setup is done manually. This is so cli applications like homebrew
|
|
6
|
+
don't mistakenly load another app's boostnap config.
|
|
7
|
+
|
|
3
8
|
# 1.24.4
|
|
4
9
|
|
|
5
10
|
* Fix several compatibility issues with Ruby `4.0.4`, particularly the `should not compile with coverage` error. See #547.
|
data/lib/bootsnap/cli.rb
CHANGED
|
@@ -19,180 +19,207 @@ module Bootsnap
|
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
|
33
38
|
end
|
|
34
|
-
false
|
|
35
|
-
rescue TypeError
|
|
36
|
-
true
|
|
37
|
-
end
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
|
42
46
|
false
|
|
43
|
-
rescue
|
|
47
|
+
rescue TypeError
|
|
44
48
|
true
|
|
45
49
|
end
|
|
46
|
-
end
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
has_ruby_bug_22023 = if defined?(RubyVM::InstructionSequence) && RubyVM::InstructionSequence.respond_to?(:compile_file_prism)
|
|
52
|
+
begin
|
|
53
|
+
RubyVM::InstructionSequence.compile_file(File.expand_path("../ruby_bug_22023_canary.rb", __FILE__))
|
|
54
|
+
false
|
|
55
|
+
rescue SyntaxError
|
|
56
|
+
true
|
|
52
57
|
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
if has_ruby_bug_22023 && RUBY_DESCRIPTION.include?("+PRISM")
|
|
61
|
+
module PatchRubyBug22023
|
|
62
|
+
def compile_file(path, options = nil)
|
|
63
|
+
compile_file_prism(path, options)
|
|
64
|
+
end
|
|
53
65
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
66
|
+
has_ruby_bug_22023_bis = !RubyVM::InstructionSequence.compile_file_prism(
|
|
67
|
+
File.expand_path("../ruby_bug_22023_canary.rb", __FILE__),
|
|
68
|
+
{frozen_string_literal: true},
|
|
69
|
+
).eval.frozen?
|
|
58
70
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
71
|
+
if has_ruby_bug_22023_bis
|
|
72
|
+
def compile_file_prism(path, options = nil)
|
|
73
|
+
compile_prism(::File.read(path, encoding: Encoding::UTF_8), path, path, nil, options)
|
|
74
|
+
end
|
|
62
75
|
end
|
|
63
76
|
end
|
|
77
|
+
RubyVM::InstructionSequence.singleton_class.prepend(PatchRubyBug22023)
|
|
64
78
|
end
|
|
65
|
-
RubyVM::InstructionSequence.singleton_class.prepend(PatchRubyBug22023)
|
|
66
|
-
end
|
|
67
79
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
+
if has_ruby_bug_18250
|
|
81
|
+
def input_to_storage(_, path)
|
|
82
|
+
iseq = RubyVM::InstructionSequence.compile_file(path, @compile_options)
|
|
83
|
+
iseq.to_binary
|
|
84
|
+
rescue TypeError, SyntaxError # Ruby [Bug #18250] & [Bug #22023]
|
|
85
|
+
UNCOMPILABLE
|
|
86
|
+
end
|
|
87
|
+
else
|
|
88
|
+
def input_to_storage(_, path)
|
|
89
|
+
RubyVM::InstructionSequence.compile_file(path, @compile_options).to_binary
|
|
90
|
+
rescue SyntaxError # Ruby [Bug #22023]
|
|
91
|
+
UNCOMPILABLE
|
|
92
|
+
end
|
|
80
93
|
end
|
|
81
|
-
end
|
|
82
94
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
95
|
+
def storage_to_output(binary, _args)
|
|
96
|
+
iseq = RubyVM::InstructionSequence.load_from_binary(binary)
|
|
97
|
+
binary.clear
|
|
98
|
+
iseq
|
|
99
|
+
rescue RuntimeError => error
|
|
100
|
+
if error.message == "broken binary format"
|
|
101
|
+
$stderr.puts("[Bootsnap::CompileCache] warning: rejecting broken binary")
|
|
102
|
+
nil
|
|
103
|
+
else
|
|
104
|
+
raise
|
|
105
|
+
end
|
|
93
106
|
end
|
|
94
|
-
end
|
|
95
107
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
108
|
+
def input_to_output(source, path, _kwargs)
|
|
109
|
+
if @compile_options
|
|
110
|
+
if source
|
|
111
|
+
RubyVM::InstructionSequence.compile(
|
|
112
|
+
source.force_encoding(Encoding.default_external),
|
|
113
|
+
path,
|
|
114
|
+
path,
|
|
115
|
+
nil,
|
|
116
|
+
@compile_options,
|
|
117
|
+
)
|
|
118
|
+
else
|
|
119
|
+
RubyVM::InstructionSequence.compile_file(path, @compile_options)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
105
122
|
end
|
|
106
123
|
end
|
|
107
|
-
end
|
|
108
124
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
@default_compiler = DEFAULT
|
|
113
|
-
@coverage_support_warning_emitted = false
|
|
114
|
-
|
|
115
|
-
def self.fetch(path, cache_dir: ISeq.cache_dir)
|
|
116
|
-
compiler = compiler_selector&.call(path) || default_compiler
|
|
117
|
-
|
|
118
|
-
# Having coverage enabled prevents iseq dumping/loading.
|
|
119
|
-
if coverage_on?
|
|
120
|
-
return nil if compiler.equal?(DEFAULT)
|
|
121
|
-
|
|
122
|
-
if COVERAGE_SUPPORTED
|
|
123
|
-
return compiler.input_to_output(File.read(path.to_s), path.to_s, nil)
|
|
124
|
-
elsif !@coverage_support_warning_emitted
|
|
125
|
-
@coverage_support_warning_emitted = true
|
|
126
|
-
warn(<<~MSG)
|
|
127
|
-
Using `Bootsnap.enable_frozen_string_literal` with code coverage enabled is only supported on Ruby 4.0.4+.
|
|
128
|
-
Files loaded while coverage is on, will have mutable string literals.
|
|
129
|
-
MSG
|
|
130
|
-
end
|
|
125
|
+
DEFAULT = Compiler.new
|
|
126
|
+
FROZEN_STRING_LITERAL = Compiler.new("-fstr", {frozen_string_literal: true}.freeze)
|
|
127
|
+
COVERAGE_SUPPORTED = RUBY_VERSION >= "4.0.4"
|
|
131
128
|
|
|
132
|
-
|
|
133
|
-
|
|
129
|
+
@default_compiler = DEFAULT
|
|
130
|
+
@coverage_support_warning_emitted = false
|
|
134
131
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
compiler.namespace,
|
|
138
|
-
path.to_s,
|
|
139
|
-
compiler,
|
|
140
|
-
nil,
|
|
141
|
-
)
|
|
142
|
-
end
|
|
132
|
+
def self.fetch(path, cache_dir: ISeq.cache_dir)
|
|
133
|
+
compiler = compiler_selector&.call(path) || default_compiler
|
|
143
134
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
135
|
+
# Having coverage enabled prevents iseq dumping/loading.
|
|
136
|
+
if coverage_on?
|
|
137
|
+
return nil if compiler.equal?(DEFAULT)
|
|
138
|
+
|
|
139
|
+
if COVERAGE_SUPPORTED
|
|
140
|
+
return compiler.input_to_output(nil, path.to_s, nil)
|
|
141
|
+
elsif !@coverage_support_warning_emitted
|
|
142
|
+
@coverage_support_warning_emitted = true
|
|
143
|
+
warn(<<~MSG)
|
|
144
|
+
Using `Bootsnap.enable_frozen_string_literal` with code coverage enabled is only supported on Ruby 4.0.4+.
|
|
145
|
+
Files loaded while coverage is on, will have mutable string literals.
|
|
146
|
+
MSG
|
|
147
|
+
end
|
|
153
148
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
149
|
+
return nil
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
Bootsnap::CompileCache::Native.fetch(
|
|
153
|
+
cache_dir,
|
|
154
|
+
compiler.namespace,
|
|
155
|
+
path.to_s,
|
|
156
|
+
compiler,
|
|
157
|
+
nil,
|
|
158
|
+
)
|
|
157
159
|
end
|
|
158
|
-
|
|
159
|
-
def self.
|
|
160
|
-
|
|
160
|
+
|
|
161
|
+
def self.precompile(path)
|
|
162
|
+
compiler = compiler_selector&.call(path) || default_compiler
|
|
163
|
+
Bootsnap::CompileCache::Native.precompile(
|
|
164
|
+
cache_dir,
|
|
165
|
+
compiler.namespace,
|
|
166
|
+
path.to_s,
|
|
167
|
+
compiler,
|
|
168
|
+
)
|
|
161
169
|
end
|
|
162
|
-
end
|
|
163
170
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
171
|
+
if RUBY_VERSION < "3.1."
|
|
172
|
+
def self.coverage_on?
|
|
173
|
+
defined?(Coverage) && Coverage.running?
|
|
174
|
+
end
|
|
175
|
+
else
|
|
176
|
+
def self.coverage_on?
|
|
177
|
+
defined?(Coverage) && Coverage.state != :idle
|
|
170
178
|
end
|
|
171
|
-
raise
|
|
172
179
|
end
|
|
173
180
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
181
|
+
module InstructionSequenceMixin
|
|
182
|
+
def load_iseq(path)
|
|
183
|
+
Bootsnap::CompileCache::ISeq.fetch(path.to_s)
|
|
184
|
+
rescue RuntimeError => error
|
|
185
|
+
if error.message.include?("unmatched platform")
|
|
186
|
+
puts("unmatched platform for file #{path}")
|
|
187
|
+
end
|
|
188
|
+
raise
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def compile_option=(hash)
|
|
192
|
+
super
|
|
193
|
+
Bootsnap::CompileCache::ISeq.compile_option_updated
|
|
194
|
+
end
|
|
177
195
|
end
|
|
178
|
-
end
|
|
179
196
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
197
|
+
def self.compile_option_updated
|
|
198
|
+
option = RubyVM::InstructionSequence.compile_option
|
|
199
|
+
crc = Zlib.crc32(option.inspect)
|
|
200
|
+
Bootsnap::CompileCache::Native.compile_option_crc32 = crc
|
|
201
|
+
FROZEN_STRING_LITERAL.update_options
|
|
202
|
+
end
|
|
203
|
+
compile_option_updated if supported?
|
|
186
204
|
|
|
187
|
-
|
|
188
|
-
|
|
205
|
+
def self.install!(cache_dir)
|
|
206
|
+
Bootsnap::CompileCache::ISeq.cache_dir = cache_dir
|
|
189
207
|
|
|
190
|
-
|
|
208
|
+
return unless supported?
|
|
191
209
|
|
|
192
|
-
|
|
210
|
+
Bootsnap::CompileCache::ISeq.compile_option_updated
|
|
211
|
+
|
|
212
|
+
class << RubyVM::InstructionSequence
|
|
213
|
+
prepend(InstructionSequenceMixin)
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
else
|
|
217
|
+
def self.install!(...)
|
|
218
|
+
# noop
|
|
219
|
+
end
|
|
193
220
|
|
|
194
|
-
|
|
195
|
-
|
|
221
|
+
def self.precompile(...)
|
|
222
|
+
# noop
|
|
196
223
|
end
|
|
197
224
|
end
|
|
198
225
|
end
|
data/lib/bootsnap/version.rb
CHANGED
data/lib/bootsnap.rb
CHANGED
|
@@ -43,13 +43,6 @@ module Bootsnap
|
|
|
43
43
|
@instrumentation.call(event, path)
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
def load_config
|
|
47
|
-
config_path = File.expand_path(ENV["BOOTSNAP_CONFIG"] || "config/bootsnap.rb")
|
|
48
|
-
if File.exist?(config_path)
|
|
49
|
-
require(config_path)
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
46
|
def setup(
|
|
54
47
|
cache_dir:,
|
|
55
48
|
development_mode: true,
|
|
@@ -59,7 +52,8 @@ module Bootsnap
|
|
|
59
52
|
revalidation: false,
|
|
60
53
|
compile_cache_iseq: true,
|
|
61
54
|
compile_cache_yaml: true,
|
|
62
|
-
compile_cache_json: (compile_cache_json_unset = true)
|
|
55
|
+
compile_cache_json: (compile_cache_json_unset = true),
|
|
56
|
+
config_path: nil
|
|
63
57
|
)
|
|
64
58
|
unless compile_cache_json_unset
|
|
65
59
|
warn("Bootsnap.setup `compile_cache_json` argument is deprecated and has no effect")
|
|
@@ -84,7 +78,16 @@ module Bootsnap
|
|
|
84
78
|
revalidation: revalidation,
|
|
85
79
|
)
|
|
86
80
|
|
|
87
|
-
load_config
|
|
81
|
+
load_config(config_path)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def load_config(config_path)
|
|
85
|
+
if config_path
|
|
86
|
+
config_path = File.expand_path(config_path)
|
|
87
|
+
if File.exist?(config_path)
|
|
88
|
+
require(config_path)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
88
91
|
end
|
|
89
92
|
|
|
90
93
|
def enable_frozen_string_literal(app_only: false)
|
|
@@ -102,8 +105,8 @@ module Bootsnap
|
|
|
102
105
|
end
|
|
103
106
|
}
|
|
104
107
|
else
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
options = RubyVM::InstructionSequence.compile_option.merge(frozen_string_literal: true)
|
|
109
|
+
RubyVM::InstructionSequence.compile_option = options
|
|
107
110
|
end
|
|
108
111
|
end
|
|
109
112
|
|
|
@@ -150,6 +153,7 @@ module Bootsnap
|
|
|
150
153
|
readonly: bool_env("BOOTSNAP_READONLY"),
|
|
151
154
|
revalidation: bool_env("BOOTSNAP_REVALIDATE"),
|
|
152
155
|
ignore_directories: ignore_directories,
|
|
156
|
+
config_path: ENV["BOOTSNAP_CONFIG"] || "config/bootsnap.rb",
|
|
153
157
|
)
|
|
154
158
|
|
|
155
159
|
if ENV["BOOTSNAP_LOG"]
|
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bootsnap
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.24.
|
|
4
|
+
version: 1.24.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Burke Libbey
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: exe
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2026-05-22 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: msgpack
|
|
@@ -67,6 +68,7 @@ metadata:
|
|
|
67
68
|
changelog_uri: https://github.com/rails/bootsnap/blob/main/CHANGELOG.md
|
|
68
69
|
source_code_uri: https://github.com/rails/bootsnap
|
|
69
70
|
allowed_push_host: https://rubygems.org
|
|
71
|
+
post_install_message:
|
|
70
72
|
rdoc_options: []
|
|
71
73
|
require_paths:
|
|
72
74
|
- lib
|
|
@@ -81,7 +83,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
81
83
|
- !ruby/object:Gem::Version
|
|
82
84
|
version: '0'
|
|
83
85
|
requirements: []
|
|
84
|
-
rubygems_version:
|
|
86
|
+
rubygems_version: 3.5.22
|
|
87
|
+
signing_key:
|
|
85
88
|
specification_version: 4
|
|
86
89
|
summary: Boot large ruby/rails apps faster
|
|
87
90
|
test_files: []
|