bootsnap 1.18.4 → 1.19.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b2271b2fa08edc313e43ec1359be530fcb6b206a7b4b63f37065290289cbc9a
4
- data.tar.gz: c5838e7d01c33320e765a2bf668c68c09fc6b0938fb8789653b526cb3c22a244
3
+ metadata.gz: 71cd833fdf912a81069349b4de87a96cf15997710494eebb4535245aeeb02305
4
+ data.tar.gz: e502571bd2d4863d5f548ce50dcd6502cc18a51dcbf00a101ad1b65f47510534
5
5
  SHA512:
6
- metadata.gz: 77168e700a54163bf4574fbf9f82fea681a01f7d0c5c3a55340d3dabc98959fce1176bebef4c4d25d18efa257ad5314f13ca978a77f5cb4288296c63a1b36871
7
- data.tar.gz: cc770950cc3032a5033873457a23b19823c35d9d24285f3b13fb95848e51d8f34defca5396c7b545b5530381271979c93026401e4ac32d28ec0f89ceadd57823
6
+ metadata.gz: d5af0fb8cabbb09d026c8a73043c24d0669004a10edbf0ee3f5baaf8597ac99b7022c0bcaef1c25948dcd055cdd4dbac2ed614d9b2a5d6e58f1e94b6cc32f127
7
+ data.tar.gz: db4c64829ebc8177ed9a83bda8cf801e570f6d48db3e27ddd4522dbd48043a0d619615ba583be4a9ff1a24049785e5dfeed362f36ef1b9115662e9c3b612973d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Unreleased
2
2
 
3
+ # 1.19.0
4
+
5
+ * Remove JSON parsing cache. Recent versions of the `json` gem are as fast as `msgpack` if not faster.
6
+
7
+ # 1.18.6
8
+
9
+ * Fix cgroup CPU limits detection in CLI.
10
+
11
+ # 1.18.5
12
+
13
+ * Attempt to detect a QEMU bug that can cause `bootsnap precompile` to hang forever when building ARM64 docker images
14
+ from x86_64 machines. See #495.
15
+ * Improve CLI to detect cgroup CPU limits and avoid spawning too many worker processes.
16
+
3
17
  # 1.18.4
4
18
 
5
19
  * Allow using bootsnap without bundler. See #488.
@@ -95,7 +109,7 @@
95
109
 
96
110
  * Get rid of the `Kernel.require_relative` decorator by resolving `$LOAD_PATH` members to their real path.
97
111
  This way we handle symlinks in `$LOAD_PATH` much more efficiently. See #402 for the detailed explanation.
98
-
112
+
99
113
  * Drop support for Ruby 2.3 (to allow getting rid of the `Kernel.require_relative` decorator).
100
114
 
101
115
  # 1.10.3
@@ -221,7 +235,7 @@
221
235
  * Adds an instrumentation API to monitor cache misses.
222
236
  * Allow to control the behavior of `require 'bootsnap/setup'` using environment variables.
223
237
  * Deprecate the `disable_trace` option.
224
- * Deprecate the `ActiveSupport::Dependencies` (AKA Classic autoloader) integration. (#344)
238
+ * Deprecate the `ActiveSupport::Dependencies` (AKA Classic autoloader) integration. (#344)
225
239
 
226
240
  # 1.6.0
227
241
 
@@ -241,12 +255,12 @@
241
255
 
242
256
  # 1.4.9
243
257
 
244
- * [Windows support](https://github.com/Shopify/bootsnap/pull/319)
245
- * [Fix potential crash](https://github.com/Shopify/bootsnap/pull/322)
258
+ * [Windows support](https://github.com/rails/bootsnap/pull/319)
259
+ * [Fix potential crash](https://github.com/rails/bootsnap/pull/322)
246
260
 
247
261
  # 1.4.8
248
262
 
249
- * [Prevent FallbackScan from polluting exception cause](https://github.com/Shopify/bootsnap/pull/314)
263
+ * [Prevent FallbackScan from polluting exception cause](https://github.com/rails/bootsnap/pull/314)
250
264
 
251
265
  # 1.4.7
252
266
 
@@ -259,7 +273,7 @@
259
273
  required if a different file with the same name was already being required
260
274
 
261
275
  Example:
262
-
276
+
263
277
  require 'foo'
264
278
  require 'foo.en'
265
279
 
@@ -313,7 +327,7 @@
313
327
 
314
328
  # 1.3.0
315
329
 
316
- * Handle cases where load path entries are symlinked (https://github.com/Shopify/bootsnap/pull/136)
330
+ * Handle cases where load path entries are symlinked (https://github.com/rails/bootsnap/pull/136)
317
331
 
318
332
  # 1.2.1
319
333
 
data/LICENSE.txt CHANGED
@@ -1,6 +1,7 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2017-present Shopify, Inc.
3
+ Copyright (c) 2017-2025 Shopify, Inc.
4
+ Copyright (c) 2025-present Rails Foundation
4
5
 
5
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
7
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Bootsnap [![Actions Status](https://github.com/Shopify/bootsnap/workflows/ci/badge.svg)](https://github.com/Shopify/bootsnap/actions)
1
+ # Bootsnap [![Actions Status](https://github.com/rails/bootsnap/workflows/ci/badge.svg)](https://github.com/rails/bootsnap/actions)
2
2
 
3
3
  Bootsnap is a library that plugs into Ruby, with optional support for `YAML` and `JSON`,
4
4
  to optimize and cache expensive computations. See [How Does This Work](#how-does-this-work).
@@ -41,7 +41,7 @@ getting progressively slower, this is almost certainly the cause.**
41
41
  It's technically possible to simply specify `gem 'bootsnap', require: 'bootsnap/setup'`, but it's
42
42
  important to load Bootsnap as early as possible to get maximum performance improvement.
43
43
 
44
- You can see how this require works [here](https://github.com/Shopify/bootsnap/blob/main/lib/bootsnap/setup.rb).
44
+ You can see how this require works [here](https://github.com/rails/bootsnap/blob/main/lib/bootsnap/setup.rb).
45
45
 
46
46
  If you are not using Rails, or if you are but want more control over things, add this to your
47
47
  application setup immediately after `require 'bundler/setup'` (i.e. as early as possible: the sooner
@@ -57,13 +57,12 @@ Bootsnap.setup(
57
57
  load_path_cache: true, # Optimize the LOAD_PATH with a cache
58
58
  compile_cache_iseq: true, # Compile Ruby code into ISeq cache, breaks coverage reporting.
59
59
  compile_cache_yaml: true, # Compile YAML into a cache
60
- compile_cache_json: true, # Compile JSON into a cache
61
60
  readonly: true, # Use the caches but don't update them on miss or stale entries.
62
61
  )
63
62
  ```
64
63
 
65
64
  **Protip:** You can replace `require 'bootsnap'` with `BootLib::Require.from_gem('bootsnap',
66
- 'bootsnap')` using [this trick](https://github.com/Shopify/bootsnap/wiki/Bootlib::Require). This
65
+ 'bootsnap')` using [this trick](https://github.com/rails/bootsnap/wiki/Bootlib::Require). This
67
66
  will help optimize boot time further if you have an extremely large `$LOAD_PATH`.
68
67
 
69
68
  Note: Bootsnap and [Spring](https://github.com/rails/spring) are orthogonal tools. While Bootsnap
@@ -170,7 +169,7 @@ The only directories considered "stable" are things under the Ruby install prefi
170
169
  "volatile".
171
170
 
172
171
  In addition to the [`Bootsnap::LoadPathCache::Cache`
173
- source](https://github.com/Shopify/bootsnap/blob/main/lib/bootsnap/load_path_cache/cache.rb),
172
+ source](https://github.com/rails/bootsnap/blob/main/lib/bootsnap/load_path_cache/cache.rb),
174
173
  this diagram may help clarify how entry resolution works:
175
174
 
176
175
  ![How path searching works](https://cloud.githubusercontent.com/assets/3074765/25388270/670b5652-299b-11e7-87fb-975647f68981.png)
@@ -188,7 +187,7 @@ result too, raising a `LoadError` without touching the filesystem at all.
188
187
 
189
188
  Ruby has complex grammar and parsing it is not a particularly cheap operation. Since 1.9, Ruby has
190
189
  translated ruby source to an internal bytecode format, which is then executed by the Ruby VM. Since
191
- 2.3.0, Ruby [exposes an API](https://ruby-doc.org/core-2.3.0/RubyVM/InstructionSequence.html) that
190
+ 2.3.0, Ruby [exposes an API](https://docs.ruby-lang.org/en/master/RubyVM/InstructionSequence.html) that
192
191
  allows caching that bytecode. This allows us to bypass the relatively-expensive compilation step on
193
192
  subsequent loads of the same file.
194
193
 
@@ -331,9 +330,23 @@ To do so you can use the `bootsnap precompile` command.
331
330
  Example:
332
331
 
333
332
  ```bash
334
- $ bundle exec bootsnap precompile --gemfile app/ lib/
333
+ $ bundle exec bootsnap precompile --gemfile app/ lib/ config/
335
334
  ```
336
335
 
336
+ ## Known issues
337
+
338
+ ### QEMU environments
339
+
340
+ When building cross-platform Docker images, QEMU is often used for emulation and can be the source of a limitation that causes forked processes to hang. While Bootsnap includes automatic detection for this issue (as of [PR #501](https://github.com/rails/bootsnap/pull/501)), the detection may not always be sufficient.
341
+
342
+ If you encounter hangs during precompilation in QEMU-based environments (such as when using Docker buildx for cross-platform builds), you can work around this by disabling parallelization with the `-j 0` option:
343
+
344
+ ```bash
345
+ $ bundle exec bootsnap precompile -j 0 --gemfile app/ lib/ config/
346
+ ```
347
+
348
+ See [Issue #495](https://github.com/rails/bootsnap/issues/495) for more details about this QEMU-related issue.
349
+
337
350
  ## When not to use Bootsnap
338
351
 
339
352
  *Alternative engines*: Bootsnap is pretty reliant on MRI features, and parts are disabled entirely on alternative ruby
@@ -23,7 +23,7 @@
23
23
 
24
24
  #ifdef __APPLE__
25
25
  // The symbol is present, however not in the headers
26
- // See: https://github.com/Shopify/bootsnap/issues/470
26
+ // See: https://github.com/rails/bootsnap/issues/470
27
27
  extern int fdatasync(int);
28
28
  #endif
29
29
 
@@ -12,7 +12,7 @@ if %w[ruby truffleruby].include?(RUBY_ENGINE)
12
12
  append_cflags ["-O3", "-std=c99"]
13
13
 
14
14
  # ruby.h has some -Wpedantic fails in some cases
15
- # (e.g. https://github.com/Shopify/bootsnap/issues/15)
15
+ # (e.g. https://github.com/rails/bootsnap/issues/15)
16
16
  unless ["0", "", nil].include?(ENV["BOOTSNAP_PEDANTIC"])
17
17
  append_cflags([
18
18
  "-Wall",
@@ -1,16 +1,88 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "etc"
4
+ require "rbconfig"
5
+ require "io/wait" unless IO.method_defined?(:wait_readable)
6
+
3
7
  module Bootsnap
4
8
  class CLI
5
9
  class WorkerPool
6
10
  class << self
7
11
  def create(size:, jobs:)
12
+ size ||= default_size
8
13
  if size > 0 && Process.respond_to?(:fork)
9
14
  new(size: size, jobs: jobs)
10
15
  else
11
16
  Inline.new(jobs: jobs)
12
17
  end
13
18
  end
19
+
20
+ def default_size
21
+ nprocessors = Etc.nprocessors
22
+ size = [nprocessors, cpu_quota&.to_i || nprocessors].min
23
+ case size
24
+ when 0, 1
25
+ 0
26
+ else
27
+ if fork_defunct?
28
+ $stderr.puts "warning: faulty fork(2) detected, probably in cross platform docker builds. " \
29
+ "Disabling parallel compilation."
30
+ 0
31
+ else
32
+ size
33
+ end
34
+ end
35
+ end
36
+
37
+ def cpu_quota
38
+ if RbConfig::CONFIG["target_os"].include?("linux")
39
+ if File.exist?("/sys/fs/cgroup/cpu.max")
40
+ # cgroups v2: https://docs.kernel.org/admin-guide/cgroup-v2.html#cpu-interface-files
41
+ cpu_max = File.read("/sys/fs/cgroup/cpu.max")
42
+ return nil if cpu_max.start_with?("max ") # no limit
43
+
44
+ max, period = cpu_max.split.map(&:to_f)
45
+ max / period
46
+ elsif File.exist?("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us")
47
+ # cgroups v1: https://kernel.googlesource.com/pub/scm/linux/kernel/git/glommer/memcg/+/cpu_stat/Documentation/cgroups/cpu.txt
48
+ max = File.read("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us").to_i
49
+ # If the cpu.cfs_quota_us is -1, cgroup does not adhere to any CPU time restrictions
50
+ # https://docs.kernel.org/scheduler/sched-bwc.html#management
51
+ return nil if max <= 0
52
+
53
+ period = File.read("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_us").to_f
54
+ max / period
55
+ end
56
+ end
57
+ end
58
+
59
+ def fork_defunct?
60
+ return true unless ::Process.respond_to?(:fork)
61
+
62
+ # Ref: https://github.com/rails/bootsnap/issues/495
63
+ # The second forked process will hang on some QEMU environments
64
+ r, w = IO.pipe
65
+ pids = 2.times.map do
66
+ ::Process.fork do
67
+ exit!(true)
68
+ end
69
+ end
70
+ w.close
71
+ r.wait_readable(1) # Wait at most 1s
72
+
73
+ defunct = false
74
+
75
+ pids.each do |pid|
76
+ _pid, status = ::Process.wait2(pid, ::Process::WNOHANG)
77
+ if status.nil? # Didn't exit in 1s
78
+ defunct = true
79
+ Process.kill(:KILL, pid)
80
+ ::Process.wait2(pid)
81
+ end
82
+ end
83
+
84
+ defunct
85
+ end
14
86
  end
15
87
 
16
88
  class Inline
data/lib/bootsnap/cli.rb CHANGED
@@ -4,7 +4,6 @@ require "bootsnap"
4
4
  require "bootsnap/cli/worker_pool"
5
5
  require "optparse"
6
6
  require "fileutils"
7
- require "etc"
8
7
 
9
8
  module Bootsnap
10
9
  class CLI
@@ -21,7 +20,7 @@ module Bootsnap
21
20
 
22
21
  attr_reader :cache_dir, :argv
23
22
 
24
- attr_accessor :compile_gemfile, :exclude, :verbose, :iseq, :yaml, :json, :jobs
23
+ attr_accessor :compile_gemfile, :exclude, :verbose, :iseq, :yaml, :jobs
25
24
 
26
25
  def initialize(argv)
27
26
  @argv = argv
@@ -29,10 +28,9 @@ module Bootsnap
29
28
  self.compile_gemfile = false
30
29
  self.exclude = nil
31
30
  self.verbose = false
32
- self.jobs = Etc.nprocessors
31
+ self.jobs = nil
33
32
  self.iseq = true
34
33
  self.yaml = true
35
- self.json = true
36
34
  end
37
35
 
38
36
  def precompile_command(*sources)
@@ -43,21 +41,18 @@ module Bootsnap
43
41
  cache_dir: cache_dir,
44
42
  iseq: iseq,
45
43
  yaml: yaml,
46
- json: json,
47
44
  revalidation: true,
48
45
  )
49
46
 
50
47
  @work_pool = WorkerPool.create(size: jobs, jobs: {
51
48
  ruby: method(:precompile_ruby),
52
49
  yaml: method(:precompile_yaml),
53
- json: method(:precompile_json),
54
50
  })
55
51
  @work_pool.spawn
56
52
 
57
53
  main_sources = sources.map { |d| File.expand_path(d) }
58
54
  precompile_ruby_files(main_sources)
59
55
  precompile_yaml_files(main_sources)
60
- precompile_json_files(main_sources)
61
56
 
62
57
  if compile_gemfile
63
58
  # Gems that include JSON or YAML files usually don't put them in `lib/`.
@@ -71,7 +66,6 @@ module Bootsnap
71
66
 
72
67
  precompile_ruby_files(gem_paths, exclude: gem_exclude)
73
68
  precompile_yaml_files(gem_paths, exclude: gem_exclude)
74
- precompile_json_files(gem_paths, exclude: gem_exclude)
75
69
  end
76
70
 
77
71
  if (exitstatus = @work_pool.shutdown)
@@ -146,29 +140,6 @@ module Bootsnap
146
140
  end
147
141
  end
148
142
 
149
- def precompile_json_files(load_paths, exclude: self.exclude)
150
- return unless json
151
-
152
- load_paths.each do |path|
153
- if !exclude || !exclude.match?(path)
154
- list_files(path, "**/*.json").each do |json_file|
155
- # We ignore hidden files to not match the various .config.json files
156
- if !File.basename(json_file).start_with?(".") && (!exclude || !exclude.match?(json_file))
157
- @work_pool.push(:json, json_file)
158
- end
159
- end
160
- end
161
- end
162
- end
163
-
164
- def precompile_json(*json_files)
165
- Array(json_files).each do |json_file|
166
- if CompileCache::JSON.precompile(json_file) && verbose
167
- $stderr.puts(json_file)
168
- end
169
- end
170
- end
171
-
172
143
  def precompile_ruby_files(load_paths, exclude: self.exclude)
173
144
  return unless iseq
174
145
 
@@ -277,9 +248,9 @@ module Bootsnap
277
248
  opts.on("--no-yaml", help) { self.yaml = false }
278
249
 
279
250
  help = <<~HELP
280
- Disable JSON precompilation.
251
+ Disable JSON precompilation. Deprecated.
281
252
  HELP
282
- opts.on("--no-json", help) { self.json = false }
253
+ opts.on("--no-json", help) { $stderr.puts("The --no-json option is deprecated and now a noop.") }
283
254
  end
284
255
  end
285
256
  end
@@ -9,7 +9,11 @@ module Bootsnap
9
9
 
10
10
  Error = Class.new(StandardError)
11
11
 
12
- def self.setup(cache_dir:, iseq:, yaml:, json:, readonly: false, revalidation: false)
12
+ def self.setup(cache_dir:, iseq:, yaml:, json: (json_unset = true), readonly: false, revalidation: false)
13
+ unless json_unset
14
+ warn("Bootsnap::CompileCache.setup `json` argument is deprecated and has no effect")
15
+ end
16
+
13
17
  if iseq
14
18
  if supported?
15
19
  require_relative "compile_cache/iseq"
@@ -28,15 +32,6 @@ module Bootsnap
28
32
  end
29
33
  end
30
34
 
31
- if json
32
- if supported?
33
- require_relative "compile_cache/json"
34
- Bootsnap::CompileCache::JSON.install!(cache_dir)
35
- elsif $VERBOSE
36
- warn("[bootsnap/setup] JSON parsing caching is not supported on this implementation of Ruby")
37
- end
38
- end
39
-
40
35
  if supported? && defined?(Bootsnap::CompileCache::Native)
41
36
  Bootsnap::CompileCache::Native.readonly = readonly
42
37
  Bootsnap::CompileCache::Native.revalidation = revalidation
@@ -142,7 +142,7 @@ module Bootsnap
142
142
  # will _never_ run on MacOS, and therefore think they can get away
143
143
  # with calling a Ruby file 'x.dylib.rb' and then requiring it as 'x.dylib'.)
144
144
  #
145
- # See <https://ruby-doc.org/core-2.6.4/Kernel.html#method-i-require>.
145
+ # See <https://docs.ruby-lang.org/en/master/Kernel.html#method-i-require>.
146
146
  def extension_elidable?(feature)
147
147
  feature.to_s.end_with?(".rb", ".so", ".o", ".dll", ".dylib")
148
148
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bootsnap
4
- VERSION = "1.18.4"
4
+ VERSION = "1.19.0"
5
5
  end
data/lib/bootsnap.rb CHANGED
@@ -54,8 +54,12 @@ module Bootsnap
54
54
  revalidation: false,
55
55
  compile_cache_iseq: true,
56
56
  compile_cache_yaml: true,
57
- compile_cache_json: true
57
+ compile_cache_json: (compile_cache_json_unset = true)
58
58
  )
59
+ unless compile_cache_json_unset
60
+ warn("Bootsnap.setup `compile_cache_json` argument is deprecated and has no effect")
61
+ end
62
+
59
63
  if load_path_cache
60
64
  Bootsnap::LoadPathCache.setup(
61
65
  cache_path: "#{cache_dir}/bootsnap/load-path-cache",
@@ -69,7 +73,6 @@ module Bootsnap
69
73
  cache_dir: "#{cache_dir}/bootsnap/compile-cache",
70
74
  iseq: compile_cache_iseq,
71
75
  yaml: compile_cache_yaml,
72
- json: compile_cache_json,
73
76
  readonly: readonly,
74
77
  revalidation: revalidation,
75
78
  )
@@ -115,7 +118,6 @@ module Bootsnap
115
118
  load_path_cache: enabled?("BOOTSNAP_LOAD_PATH_CACHE"),
116
119
  compile_cache_iseq: enabled?("BOOTSNAP_COMPILE_CACHE"),
117
120
  compile_cache_yaml: enabled?("BOOTSNAP_COMPILE_CACHE"),
118
- compile_cache_json: enabled?("BOOTSNAP_COMPILE_CACHE"),
119
121
  readonly: bool_env("BOOTSNAP_READONLY"),
120
122
  revalidation: bool_env("BOOTSNAP_REVALIDATE"),
121
123
  ignore_directories: ignore_directories,
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootsnap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.18.4
4
+ version: 1.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Burke Libbey
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-08-05 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: msgpack
@@ -46,7 +45,6 @@ files:
46
45
  - lib/bootsnap/cli/worker_pool.rb
47
46
  - lib/bootsnap/compile_cache.rb
48
47
  - lib/bootsnap/compile_cache/iseq.rb
49
- - lib/bootsnap/compile_cache/json.rb
50
48
  - lib/bootsnap/compile_cache/yaml.rb
51
49
  - lib/bootsnap/explicit_require.rb
52
50
  - lib/bootsnap/load_path_cache.rb
@@ -60,15 +58,14 @@ files:
60
58
  - lib/bootsnap/load_path_cache/store.rb
61
59
  - lib/bootsnap/setup.rb
62
60
  - lib/bootsnap/version.rb
63
- homepage: https://github.com/Shopify/bootsnap
61
+ homepage: https://github.com/rails/bootsnap
64
62
  licenses:
65
63
  - MIT
66
64
  metadata:
67
- bug_tracker_uri: https://github.com/Shopify/bootsnap/issues
68
- changelog_uri: https://github.com/Shopify/bootsnap/blob/main/CHANGELOG.md
69
- source_code_uri: https://github.com/Shopify/bootsnap
65
+ bug_tracker_uri: https://github.com/rails/bootsnap/issues
66
+ changelog_uri: https://github.com/rails/bootsnap/blob/main/CHANGELOG.md
67
+ source_code_uri: https://github.com/rails/bootsnap
70
68
  allowed_push_host: https://rubygems.org
71
- post_install_message:
72
69
  rdoc_options: []
73
70
  require_paths:
74
71
  - lib
@@ -83,8 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
80
  - !ruby/object:Gem::Version
84
81
  version: '0'
85
82
  requirements: []
86
- rubygems_version: 3.5.16
87
- signing_key:
83
+ rubygems_version: 3.6.9
88
84
  specification_version: 4
89
85
  summary: Boot large ruby/rails apps faster
90
86
  test_files: []
@@ -1,89 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bootsnap/bootsnap"
4
-
5
- module Bootsnap
6
- module CompileCache
7
- module JSON
8
- class << self
9
- attr_accessor(:msgpack_factory, :supported_options)
10
- attr_reader(:cache_dir)
11
-
12
- def cache_dir=(cache_dir)
13
- @cache_dir = cache_dir.end_with?("/") ? "#{cache_dir}json" : "#{cache_dir}-json"
14
- end
15
-
16
- def input_to_storage(payload, _)
17
- obj = ::JSON.parse(payload)
18
- msgpack_factory.dump(obj)
19
- end
20
-
21
- def storage_to_output(data, kwargs)
22
- if kwargs&.key?(:symbolize_names)
23
- kwargs[:symbolize_keys] = kwargs.delete(:symbolize_names)
24
- end
25
- msgpack_factory.load(data, kwargs)
26
- end
27
-
28
- def input_to_output(data, kwargs)
29
- ::JSON.parse(data, **(kwargs || {}))
30
- end
31
-
32
- def precompile(path)
33
- Bootsnap::CompileCache::Native.precompile(
34
- cache_dir,
35
- path.to_s,
36
- self,
37
- )
38
- end
39
-
40
- def install!(cache_dir)
41
- self.cache_dir = cache_dir
42
- init!
43
- if ::JSON.respond_to?(:load_file)
44
- ::JSON.singleton_class.prepend(Patch)
45
- end
46
- end
47
-
48
- def init!
49
- require "json"
50
- require "msgpack"
51
-
52
- self.msgpack_factory = MessagePack::Factory.new
53
- self.supported_options = [:symbolize_names]
54
- if supports_freeze?
55
- self.supported_options = [:freeze]
56
- end
57
- supported_options.freeze
58
- end
59
-
60
- private
61
-
62
- def supports_freeze?
63
- ::JSON.parse('["foo"]', freeze: true).first.frozen? &&
64
- MessagePack.load(MessagePack.dump("foo"), freeze: true).frozen?
65
- end
66
- end
67
-
68
- module Patch
69
- def load_file(path, *args)
70
- return super if args.size > 1
71
-
72
- if (kwargs = args.first)
73
- return super unless kwargs.is_a?(Hash)
74
- return super unless (kwargs.keys - ::Bootsnap::CompileCache::JSON.supported_options).empty?
75
- end
76
-
77
- ::Bootsnap::CompileCache::Native.fetch(
78
- Bootsnap::CompileCache::JSON.cache_dir,
79
- File.realpath(path),
80
- ::Bootsnap::CompileCache::JSON,
81
- kwargs,
82
- )
83
- end
84
-
85
- ruby2_keywords :load_file if respond_to?(:ruby2_keywords, true)
86
- end
87
- end
88
- end
89
- end