bootsnap 1.7.5 → 1.11.1
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 +111 -2
- data/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/exe/bootsnap +1 -1
- data/ext/bootsnap/bootsnap.c +47 -36
- data/ext/bootsnap/extconf.rb +13 -11
- data/lib/bootsnap/bundler.rb +1 -0
- data/lib/bootsnap/cli/worker_pool.rb +6 -1
- data/lib/bootsnap/cli.rb +78 -43
- data/lib/bootsnap/compile_cache/iseq.rb +42 -12
- data/lib/bootsnap/compile_cache/json.rb +88 -0
- data/lib/bootsnap/compile_cache/yaml.rb +272 -53
- data/lib/bootsnap/compile_cache.rb +20 -7
- data/lib/bootsnap/explicit_require.rb +4 -3
- data/lib/bootsnap/load_path_cache/cache.rb +61 -41
- data/lib/bootsnap/load_path_cache/change_observer.rb +4 -0
- data/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb +33 -73
- data/lib/bootsnap/load_path_cache/core_ext/loaded_features.rb +1 -0
- data/lib/bootsnap/load_path_cache/loaded_features_index.rb +34 -23
- 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 +48 -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 +114 -89
- metadata +8 -78
- data/lib/bootsnap/load_path_cache/realpath_cache.rb +0 -32
data/lib/bootsnap.rb
CHANGED
@@ -1,123 +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
|
-
)
|
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."
|
27
|
+
def instrumentation=(callback)
|
28
|
+
@instrumentation = callback
|
29
|
+
if respond_to?(:instrumentation_enabled=, true)
|
30
|
+
self.instrumentation_enabled = !!callback
|
31
|
+
end
|
52
32
|
end
|
53
33
|
|
54
|
-
|
55
|
-
|
56
|
-
"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)
|
57
36
|
end
|
58
37
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
63
53
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
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
|
68
58
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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
|
63
|
+
|
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
|
75
70
|
|
76
|
-
|
77
|
-
|
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
|
78
78
|
|
79
|
-
|
80
|
-
|
81
|
-
end
|
79
|
+
def iseq_cache_supported?
|
80
|
+
return @iseq_cache_supported if defined? @iseq_cache_supported
|
82
81
|
|
83
|
-
|
84
|
-
|
85
|
-
|
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
|
86
85
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
config_dir_frame = caller.detect do |line|
|
91
|
-
line.include?('/config/')
|
92
|
-
end
|
86
|
+
def default_setup
|
87
|
+
env = ENV["RAILS_ENV"] || ENV["RACK_ENV"] || ENV["ENV"]
|
88
|
+
development_mode = ["", nil, "development"].include?(env)
|
93
89
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
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
|
98
96
|
|
99
|
-
|
100
|
-
|
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")
|
101
101
|
|
102
|
-
|
103
|
-
|
104
|
-
app_root = File.dirname(path)
|
102
|
+
raise("couldn't infer bootsnap cache directory")
|
103
|
+
end
|
105
104
|
|
106
|
-
|
107
|
-
|
105
|
+
path = config_dir_frame.split(/:\d+:/).first
|
106
|
+
path = File.dirname(path) until File.basename(path) == "config"
|
107
|
+
app_root = File.dirname(path)
|
108
108
|
|
109
|
+
cache_dir = File.join(app_root, "tmp", "cache")
|
110
|
+
end
|
109
111
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
124
|
+
end
|
125
|
+
end
|
117
126
|
|
118
|
-
|
119
|
-
|
127
|
+
if RbConfig::CONFIG["host_os"] =~ /mswin|mingw|cygwin/
|
128
|
+
def absolute_path?(path)
|
129
|
+
path[1] == ":"
|
120
130
|
end
|
131
|
+
else
|
132
|
+
def absolute_path?(path)
|
133
|
+
path.start_with?("/")
|
134
|
+
end
|
135
|
+
end
|
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")
|
121
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
|
122
147
|
end
|
123
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.11.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Burke Libbey
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-08 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
|
@@ -116,6 +46,7 @@ files:
|
|
116
46
|
- lib/bootsnap/cli/worker_pool.rb
|
117
47
|
- lib/bootsnap/compile_cache.rb
|
118
48
|
- lib/bootsnap/compile_cache/iseq.rb
|
49
|
+
- lib/bootsnap/compile_cache/json.rb
|
119
50
|
- lib/bootsnap/compile_cache/yaml.rb
|
120
51
|
- lib/bootsnap/explicit_require.rb
|
121
52
|
- lib/bootsnap/load_path_cache.rb
|
@@ -126,7 +57,6 @@ files:
|
|
126
57
|
- lib/bootsnap/load_path_cache/loaded_features_index.rb
|
127
58
|
- lib/bootsnap/load_path_cache/path.rb
|
128
59
|
- lib/bootsnap/load_path_cache/path_scanner.rb
|
129
|
-
- lib/bootsnap/load_path_cache/realpath_cache.rb
|
130
60
|
- lib/bootsnap/load_path_cache/store.rb
|
131
61
|
- lib/bootsnap/setup.rb
|
132
62
|
- lib/bootsnap/version.rb
|
@@ -135,7 +65,7 @@ licenses:
|
|
135
65
|
- MIT
|
136
66
|
metadata:
|
137
67
|
bug_tracker_uri: https://github.com/Shopify/bootsnap/issues
|
138
|
-
changelog_uri: https://github.com/Shopify/bootsnap/blob/
|
68
|
+
changelog_uri: https://github.com/Shopify/bootsnap/blob/main/CHANGELOG.md
|
139
69
|
source_code_uri: https://github.com/Shopify/bootsnap
|
140
70
|
allowed_push_host: https://rubygems.org
|
141
71
|
post_install_message:
|
@@ -146,14 +76,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
146
76
|
requirements:
|
147
77
|
- - ">="
|
148
78
|
- !ruby/object:Gem::Version
|
149
|
-
version: 2.
|
79
|
+
version: 2.4.0
|
150
80
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
81
|
requirements:
|
152
82
|
- - ">="
|
153
83
|
- !ruby/object:Gem::Version
|
154
84
|
version: '0'
|
155
85
|
requirements: []
|
156
|
-
rubygems_version: 3.
|
86
|
+
rubygems_version: 3.2.20
|
157
87
|
signing_key:
|
158
88
|
specification_version: 4
|
159
89
|
summary: Boot large ruby/rails apps faster
|
@@ -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
|