bootsnap 1.24.4 → 1.24.6

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: c89c653bbd5db473e06179c6606268271c8c540a588cca938662f168d64f2d39
4
+ data.tar.gz: 449c08c79a258dea90e56646c9d62a06e1d696c065ce96c38a7f50ef2fb83f7b
5
5
  SHA512:
6
- metadata.gz: c92cf4fc73d5241a876647a67e9ff70ee63b2816a6f048f3b9f408de8c460e1f97f00162c883bbcc62b01a90d4f753126e3c3be885aee41d042fa166aad812af
7
- data.tar.gz: 3db013dee453d69e531d4c6cc1a0e763aeadce36a3d5254febb449957447bf801c06e06544a4f571b5a103e75d397b60d51d364eede8de5bfce63abd79dc0ddf
6
+ metadata.gz: 2ea80faffec0206b9bb7b3d19c1419b2e7eefc2dc5f4eb03352862b83afa07ed293d0b15f04fc069d89dac1cd4d4636770626e90e6129ffad77f0cfcb8c3f676
7
+ data.tar.gz: 82dcb1a4c934a9de29a8aa935ffe2d1a7c6e23ebf36ea743c3d29a4d9a1d8bd42696cdefd37dacdd21a4102f88f0b605d1cc6faef9c15ccdc6d99eef15f4483e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Unreleased
2
2
 
3
+ # 1.24.6
4
+
5
+ * Fix detection of Ruby bug #22023 on some patch versions of Ruby 3.4, and properly apply the workaround.
6
+
7
+ # 1.24.5
8
+
9
+ * No longer load the config file by default when setup is done manually. This is so cli applications like homebrew
10
+ don't mistakenly load another app's boostnap config.
11
+
3
12
  # 1.24.4
4
13
 
5
14
  * Fix several compatibility issues with Ruby `4.0.4`, particularly the `should not compile with coverage` error. See #547.
@@ -403,11 +403,14 @@ bs_cache_path(VALUE cachedir_v, VALUE namespace_v, VALUE path_v, char (* cache_p
403
403
 
404
404
  Check_Type(cachedir_v, T_STRING);
405
405
  Check_Type(path_v, T_STRING);
406
+
407
+ long namespace_len = 0;
406
408
  if (!NIL_P(namespace_v)) {
407
409
  Check_Type(namespace_v, T_STRING);
410
+ namespace_len = RSTRING_LEN(namespace_v);
408
411
  }
409
412
 
410
- if (RSTRING_LEN(cachedir_v) > MAX_CACHEDIR_SIZE) {
413
+ if (RSTRING_LEN(cachedir_v) + namespace_len > MAX_CACHEDIR_SIZE) {
411
414
  rb_raise(rb_eArgError, "cachedir too long");
412
415
  }
413
416
 
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,209 @@ 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)
52
- end
51
+ has_ruby_bug_22023 = case RUBY_VERSION
52
+ when /^3\.3\./
53
+ true
54
+ when /^3\.4\.(\d+)/
55
+ $1.to_i < 10
56
+ when /^4\.0\.(\d+)/
57
+ $1.to_i < 4
58
+ else
59
+ false
60
+ end
61
+
62
+ if has_ruby_bug_22023 && RUBY_DESCRIPTION.include?("+PRISM")
63
+ module PatchRubyBug22023
64
+ def compile_file(path, options = nil)
65
+ compile_file_prism(path, options)
66
+ end
53
67
 
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?
68
+ has_ruby_bug_22023_bis = !RubyVM::InstructionSequence.compile_file_prism(
69
+ File.expand_path("../ruby_bug_22023_canary.rb", __FILE__),
70
+ {frozen_string_literal: true},
71
+ ).eval.frozen?
58
72
 
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)
73
+ if has_ruby_bug_22023_bis
74
+ def compile_file_prism(path, options = nil)
75
+ compile_prism(::File.read(path, encoding: Encoding::UTF_8), path, path, nil, options)
76
+ end
62
77
  end
63
78
  end
79
+ RubyVM::InstructionSequence.singleton_class.prepend(PatchRubyBug22023)
64
80
  end
65
- RubyVM::InstructionSequence.singleton_class.prepend(PatchRubyBug22023)
66
- end
67
81
 
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
82
+ if has_ruby_bug_18250
83
+ def input_to_storage(_, path)
84
+ iseq = RubyVM::InstructionSequence.compile_file(path, @compile_options)
85
+ iseq.to_binary
86
+ rescue TypeError, SyntaxError # Ruby [Bug #18250] & [Bug #22023]
87
+ UNCOMPILABLE
88
+ end
89
+ else
90
+ def input_to_storage(_, path)
91
+ RubyVM::InstructionSequence.compile_file(path, @compile_options).to_binary
92
+ rescue SyntaxError # Ruby [Bug #22023]
93
+ UNCOMPILABLE
94
+ end
80
95
  end
81
- end
82
96
 
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
97
+ def storage_to_output(binary, _args)
98
+ iseq = RubyVM::InstructionSequence.load_from_binary(binary)
99
+ binary.clear
100
+ iseq
101
+ rescue RuntimeError => error
102
+ if error.message == "broken binary format"
103
+ $stderr.puts("[Bootsnap::CompileCache] warning: rejecting broken binary")
104
+ nil
105
+ else
106
+ raise
107
+ end
93
108
  end
94
- end
95
109
 
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
- )
110
+ def input_to_output(source, path, _kwargs)
111
+ if @compile_options
112
+ if source
113
+ RubyVM::InstructionSequence.compile(
114
+ source.force_encoding(Encoding.default_external),
115
+ path,
116
+ path,
117
+ nil,
118
+ @compile_options,
119
+ )
120
+ else
121
+ RubyVM::InstructionSequence.compile_file(path, @compile_options)
122
+ end
123
+ end
105
124
  end
106
125
  end
107
- end
108
126
 
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
127
+ DEFAULT = Compiler.new
128
+ FROZEN_STRING_LITERAL = Compiler.new("-fstr", {frozen_string_literal: true}.freeze)
129
+ COVERAGE_SUPPORTED = RUBY_VERSION >= "4.0.4"
131
130
 
132
- return nil
133
- end
131
+ @default_compiler = DEFAULT
132
+ @coverage_support_warning_emitted = false
134
133
 
135
- Bootsnap::CompileCache::Native.fetch(
136
- cache_dir,
137
- compiler.namespace,
138
- path.to_s,
139
- compiler,
140
- nil,
141
- )
142
- end
134
+ def self.fetch(path, cache_dir: ISeq.cache_dir)
135
+ compiler = compiler_selector&.call(path) || default_compiler
143
136
 
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
137
+ # Having coverage enabled prevents iseq dumping/loading.
138
+ if coverage_on?
139
+ return nil if compiler.equal?(DEFAULT)
140
+
141
+ if COVERAGE_SUPPORTED
142
+ return compiler.input_to_output(nil, path.to_s, nil)
143
+ elsif !@coverage_support_warning_emitted
144
+ @coverage_support_warning_emitted = true
145
+ warn(<<~MSG)
146
+ Using `Bootsnap.enable_frozen_string_literal` with code coverage enabled is only supported on Ruby 4.0.4+.
147
+ Files loaded while coverage is on, will have mutable string literals.
148
+ MSG
149
+ end
150
+
151
+ return nil
152
+ end
153
153
 
154
- if RUBY_VERSION < "3.1."
155
- def self.coverage_on?
156
- defined?(Coverage) && Coverage.running?
154
+ Bootsnap::CompileCache::Native.fetch(
155
+ cache_dir,
156
+ compiler.namespace,
157
+ path.to_s,
158
+ compiler,
159
+ nil,
160
+ )
157
161
  end
158
- else
159
- def self.coverage_on?
160
- defined?(Coverage) && Coverage.state != :idle
162
+
163
+ def self.precompile(path)
164
+ compiler = compiler_selector&.call(path) || default_compiler
165
+ Bootsnap::CompileCache::Native.precompile(
166
+ cache_dir,
167
+ compiler.namespace,
168
+ path.to_s,
169
+ compiler,
170
+ )
161
171
  end
162
- end
163
172
 
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}")
173
+ if RUBY_VERSION < "3.1."
174
+ def self.coverage_on?
175
+ defined?(Coverage) && Coverage.running?
176
+ end
177
+ else
178
+ def self.coverage_on?
179
+ defined?(Coverage) && Coverage.state != :idle
170
180
  end
171
- raise
172
181
  end
173
182
 
174
- def compile_option=(hash)
175
- super
176
- Bootsnap::CompileCache::ISeq.compile_option_updated
183
+ module InstructionSequenceMixin
184
+ def load_iseq(path)
185
+ Bootsnap::CompileCache::ISeq.fetch(path.to_s)
186
+ rescue RuntimeError => error
187
+ if error.message.include?("unmatched platform")
188
+ puts("unmatched platform for file #{path}")
189
+ end
190
+ raise
191
+ end
192
+
193
+ def compile_option=(hash)
194
+ super
195
+ Bootsnap::CompileCache::ISeq.compile_option_updated
196
+ end
177
197
  end
178
- end
179
198
 
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?
199
+ def self.compile_option_updated
200
+ option = RubyVM::InstructionSequence.compile_option
201
+ crc = Zlib.crc32(option.inspect)
202
+ Bootsnap::CompileCache::Native.compile_option_crc32 = crc
203
+ FROZEN_STRING_LITERAL.update_options
204
+ end
205
+ compile_option_updated if supported?
206
+
207
+ def self.install!(cache_dir)
208
+ Bootsnap::CompileCache::ISeq.cache_dir = cache_dir
186
209
 
187
- def self.install!(cache_dir)
188
- Bootsnap::CompileCache::ISeq.cache_dir = cache_dir
210
+ return unless supported?
189
211
 
190
- return unless supported?
212
+ Bootsnap::CompileCache::ISeq.compile_option_updated
191
213
 
192
- Bootsnap::CompileCache::ISeq.compile_option_updated
214
+ class << RubyVM::InstructionSequence
215
+ prepend(InstructionSequenceMixin)
216
+ end
217
+ end
218
+ else
219
+ def self.install!(...)
220
+ # noop
221
+ end
193
222
 
194
- class << RubyVM::InstructionSequence
195
- prepend(InstructionSequenceMixin)
223
+ def self.precompile(...)
224
+ # noop
196
225
  end
197
226
  end
198
227
  end
@@ -1,7 +1 @@
1
- _f = -> {
2
- case foo
3
- in [one, "a" | "b" => two]
4
- puts "#{one} - #{two}"
5
- end
6
- }
7
1
  _ = "test"
@@ -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.6"
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,7 +1,7 @@
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.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Burke Libbey
@@ -81,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  requirements: []
84
- rubygems_version: 4.0.10
84
+ rubygems_version: 3.6.9
85
85
  specification_version: 4
86
86
  summary: Boot large ruby/rails apps faster
87
87
  test_files: []