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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64eaf08501294e6e0fd98b67a54eadfff566f5480a0722e2fb852611a28bd1f8
4
- data.tar.gz: 8e28bc6d5714952cf5abd837453be6774309dd4b45559c3cd31684ef6658490f
3
+ metadata.gz: 9f514d9a08cf2cbfa470c7d6745fe6388bfb4800a8cf659b9939bc57c93a67e1
4
+ data.tar.gz: e623cc84b0ce559e15eeb5ade64617ab6faff50a5004256ecdac5e93267ac5e0
5
5
  SHA512:
6
- metadata.gz: c92cf4fc73d5241a876647a67e9ff70ee63b2816a6f048f3b9f408de8c460e1f97f00162c883bbcc62b01a90d4f753126e3c3be885aee41d042fa166aad812af
7
- data.tar.gz: 3db013dee453d69e531d4c6cc1a0e763aeadce36a3d5254febb449957447bf801c06e06544a4f571b5a103e75d397b60d51d364eede8de5bfce63abd79dc0ddf
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
@@ -43,7 +43,7 @@ module Bootsnap
43
43
  yaml: yaml,
44
44
  revalidation: true,
45
45
  )
46
- Bootsnap.load_config
46
+ Bootsnap.load_config(ENV["BOOTSNAP_CONFIG"] || "config/bootsnap.rb")
47
47
 
48
48
  @work_pool = WorkerPool.create(size: jobs, jobs: {
49
49
  ruby: method(:precompile_ruby),
@@ -19,180 +19,207 @@ module Bootsnap
19
19
  end
20
20
  end
21
21
 
22
- class Compiler
23
- attr_reader :namespace, :compile_options
24
-
25
- def initialize(namespace = nil, compile_options = nil)
26
- @namespace = namespace
27
- @compile_options = compile_options
28
- end
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
- has_ruby_bug_18250 = RUBY_VERSION.start_with?("3.0.") && begin # https://bugs.ruby-lang.org/issues/18250
31
- if defined? RubyVM::InstructionSequence
32
- RubyVM::InstructionSequence.compile("def foo(*); ->{ super }; end; def foo(**); ->{ super }; end").to_binary
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
- has_ruby_bug_22023 = if defined?(RubyVM::InstructionSequence) && RubyVM::InstructionSequence.respond_to?(:compile_file_prism)
40
- begin
41
- RubyVM::InstructionSequence.compile_file(File.expand_path("../ruby_bug_22023_canary.rb", __FILE__))
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 SyntaxError
47
+ rescue TypeError
44
48
  true
45
49
  end
46
- end
47
50
 
48
- if has_ruby_bug_22023 && RUBY_DESCRIPTION.include?("+PRISM")
49
- module PatchRubyBug22023
50
- def compile_file(path, options = nil)
51
- compile_file_prism(path, options)
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
- has_ruby_bug_22023_bis = !RubyVM::InstructionSequence.compile_file_prism(
55
- File.expand_path("../ruby_bug_22023_canary.rb", __FILE__),
56
- {frozen_string_literal: true},
57
- ).eval.frozen?
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
- if has_ruby_bug_22023_bis
60
- def compile_file_prism(path, options = nil)
61
- compile_prism(::File.read(path, encoding: Encoding::UTF_8), path, path, nil, options)
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
- if has_ruby_bug_18250
69
- def input_to_storage(_, path)
70
- iseq = RubyVM::InstructionSequence.compile_file(path, @compile_options)
71
- iseq.to_binary
72
- rescue TypeError, SyntaxError # Ruby [Bug #18250] & [Bug #22023]
73
- UNCOMPILABLE
74
- end
75
- else
76
- def input_to_storage(_, path)
77
- RubyVM::InstructionSequence.compile_file(path, @compile_options).to_binary
78
- rescue SyntaxError # Ruby [Bug #22023]
79
- UNCOMPILABLE
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
- def storage_to_output(binary, _args)
84
- iseq = RubyVM::InstructionSequence.load_from_binary(binary)
85
- binary.clear
86
- iseq
87
- rescue RuntimeError => error
88
- if error.message == "broken binary format"
89
- $stderr.puts("[Bootsnap::CompileCache] warning: rejecting broken binary")
90
- nil
91
- else
92
- raise
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
- def input_to_output(source, path, _kwargs)
97
- if @compile_options
98
- RubyVM::InstructionSequence.compile(
99
- source.force_encoding(Encoding.default_external),
100
- path,
101
- path,
102
- nil,
103
- @compile_options,
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
- DEFAULT = Compiler.new
110
- FROZEN_STRING_LITERAL = Compiler.new("-fstr", {frozen_string_literal: true}.freeze)
111
- COVERAGE_SUPPORTED = RUBY_VERSION >= "4.0.4"
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
- return nil
133
- end
129
+ @default_compiler = DEFAULT
130
+ @coverage_support_warning_emitted = false
134
131
 
135
- Bootsnap::CompileCache::Native.fetch(
136
- cache_dir,
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
- def self.precompile(path)
145
- compiler = compiler_selector&.call(path) || default_compiler
146
- Bootsnap::CompileCache::Native.precompile(
147
- cache_dir,
148
- compiler.namespace,
149
- path.to_s,
150
- compiler,
151
- )
152
- end
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
- if RUBY_VERSION < "3.1."
155
- def self.coverage_on?
156
- defined?(Coverage) && Coverage.running?
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
- else
159
- def self.coverage_on?
160
- defined?(Coverage) && Coverage.state != :idle
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
- module InstructionSequenceMixin
165
- def load_iseq(path)
166
- Bootsnap::CompileCache::ISeq.fetch(path.to_s)
167
- rescue RuntimeError => error
168
- if error.message.include?("unmatched platform")
169
- puts("unmatched platform for file #{path}")
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
- def compile_option=(hash)
175
- super
176
- Bootsnap::CompileCache::ISeq.compile_option_updated
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
- def self.compile_option_updated
181
- option = RubyVM::InstructionSequence.compile_option
182
- crc = Zlib.crc32(option.inspect)
183
- Bootsnap::CompileCache::Native.compile_option_crc32 = crc
184
- end
185
- compile_option_updated if supported?
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
- def self.install!(cache_dir)
188
- Bootsnap::CompileCache::ISeq.cache_dir = cache_dir
205
+ def self.install!(cache_dir)
206
+ Bootsnap::CompileCache::ISeq.cache_dir = cache_dir
189
207
 
190
- return unless supported?
208
+ return unless supported?
191
209
 
192
- Bootsnap::CompileCache::ISeq.compile_option_updated
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
- class << RubyVM::InstructionSequence
195
- prepend(InstructionSequenceMixin)
221
+ def self.precompile(...)
222
+ # noop
196
223
  end
197
224
  end
198
225
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bootsnap
4
- VERSION = "1.24.4"
4
+ VERSION = "1.24.5"
5
5
  end
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
- Bootsnap::CompileCache::ISeq.compiler_selector = nil
106
- Bootsnap::CompileCache::ISeq.default_compiler = Bootsnap::CompileCache::ISeq::FROZEN_STRING_LITERAL
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
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: 1980-01-02 00:00:00.000000000 Z
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: 4.0.10
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: []