bootsnap 1.1.8 → 1.7.2
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 +5 -5
- data/CHANGELOG.md +121 -0
- data/README.md +72 -14
- data/exe/bootsnap +5 -0
- data/ext/bootsnap/bootsnap.c +283 -105
- data/ext/bootsnap/extconf.rb +21 -14
- data/lib/bootsnap.rb +95 -14
- data/lib/bootsnap/bundler.rb +6 -3
- data/lib/bootsnap/cli.rb +246 -0
- data/lib/bootsnap/cli/worker_pool.rb +131 -0
- data/lib/bootsnap/compile_cache.rb +32 -4
- data/lib/bootsnap/compile_cache/iseq.rb +32 -15
- data/lib/bootsnap/compile_cache/yaml.rb +97 -40
- data/lib/bootsnap/explicit_require.rb +2 -1
- data/lib/bootsnap/load_path_cache.rb +33 -20
- data/lib/bootsnap/load_path_cache/cache.rb +65 -29
- data/lib/bootsnap/load_path_cache/change_observer.rb +36 -29
- data/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb +70 -53
- data/lib/bootsnap/load_path_cache/core_ext/loaded_features.rb +18 -0
- data/lib/bootsnap/load_path_cache/loaded_features_index.rb +148 -0
- data/lib/bootsnap/load_path_cache/path.rb +8 -7
- data/lib/bootsnap/load_path_cache/path_scanner.rb +61 -39
- data/lib/bootsnap/load_path_cache/realpath_cache.rb +32 -0
- data/lib/bootsnap/load_path_cache/store.rb +27 -14
- data/lib/bootsnap/setup.rb +3 -40
- data/lib/bootsnap/version.rb +2 -1
- metadata +26 -29
- data/.gitignore +0 -17
- data/.rubocop.yml +0 -20
- data/.travis.yml +0 -4
- data/CODE_OF_CONDUCT.md +0 -74
- data/CONTRIBUTING.md +0 -21
- data/Gemfile +0 -8
- data/Rakefile +0 -11
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/bin/testunit +0 -8
- data/bootsnap.gemspec +0 -39
- data/dev.yml +0 -10
- data/lib/bootsnap/load_path_cache/core_ext/active_support.rb +0 -75
@@ -1,51 +1,73 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative('../explicit_require')
|
2
4
|
|
3
5
|
module Bootsnap
|
4
6
|
module LoadPathCache
|
5
7
|
module PathScanner
|
6
|
-
|
7
|
-
# It expands to:
|
8
|
-
#
|
9
|
-
# * `/*{.rb,.so,/}` - It matches requirable files, directories and
|
10
|
-
# symlinks to directories at given path.
|
11
|
-
# * `/*/**/*{.rb,.so,/}` - It matches requirable files and
|
12
|
-
# subdirectories in any (even symlinked) directory at given path at
|
13
|
-
# any directory tree depth.
|
14
|
-
#
|
15
|
-
REQUIRABLES_AND_DIRS = "/{,*/**/}*{#{DOT_RB},#{DL_EXTENSIONS.join(',')},/}"
|
8
|
+
REQUIRABLE_EXTENSIONS = [DOT_RB] + DL_EXTENSIONS
|
16
9
|
NORMALIZE_NATIVE_EXTENSIONS = !DL_EXTENSIONS.include?(LoadPathCache::DOT_SO)
|
17
10
|
ALTERNATIVE_NATIVE_EXTENSIONS_PATTERN = /\.(o|bundle|dylib)\z/
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
11
|
+
|
12
|
+
BUNDLE_PATH = if Bootsnap.bundler?
|
13
|
+
(Bundler.bundle_path.cleanpath.to_s << LoadPathCache::SLASH).freeze
|
14
|
+
else
|
15
|
+
''
|
16
|
+
end
|
17
|
+
|
18
|
+
class << self
|
19
|
+
def call(path)
|
20
|
+
path = File.expand_path(path.to_s).freeze
|
21
|
+
return [[], []] unless File.directory?(path)
|
22
|
+
|
23
|
+
# If the bundle path is a descendent of this path, we do additional
|
24
|
+
# checks to prevent recursing into the bundle path as we recurse
|
25
|
+
# through this path. We don't want to scan the bundle path because
|
26
|
+
# anything useful in it will be present on other load path items.
|
27
|
+
#
|
28
|
+
# This can happen if, for example, the user adds '.' to the load path,
|
29
|
+
# and the bundle path is '.bundle'.
|
30
|
+
contains_bundle_path = BUNDLE_PATH.start_with?(path)
|
31
|
+
|
32
|
+
dirs = []
|
33
|
+
requirables = []
|
34
|
+
walk(path, nil) do |relative_path, absolute_path, is_directory|
|
35
|
+
if is_directory
|
36
|
+
dirs << os_path(relative_path)
|
37
|
+
!contains_bundle_path || !absolute_path.start_with?(BUNDLE_PATH)
|
38
|
+
elsif relative_path.end_with?(*REQUIRABLE_EXTENSIONS)
|
39
|
+
requirables << os_path(relative_path)
|
40
|
+
end
|
45
41
|
end
|
42
|
+
[requirables, dirs]
|
46
43
|
end
|
47
44
|
|
48
|
-
|
45
|
+
def walk(absolute_dir_path, relative_dir_path, &block)
|
46
|
+
Dir.foreach(absolute_dir_path) do |name|
|
47
|
+
next if name.start_with?('.')
|
48
|
+
relative_path = relative_dir_path ? File.join(relative_dir_path, name) : name
|
49
|
+
|
50
|
+
absolute_path = "#{absolute_dir_path}/#{name}"
|
51
|
+
if File.directory?(absolute_path)
|
52
|
+
if yield relative_path, absolute_path, true
|
53
|
+
walk(absolute_path, relative_path, &block)
|
54
|
+
end
|
55
|
+
else
|
56
|
+
yield relative_path, absolute_path, false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
if RUBY_VERSION >= '3.1'
|
62
|
+
def os_path(path)
|
63
|
+
path.freeze
|
64
|
+
end
|
65
|
+
else
|
66
|
+
def os_path(path)
|
67
|
+
path.force_encoding(Encoding::US_ASCII) if path.ascii_only?
|
68
|
+
path.freeze
|
69
|
+
end
|
70
|
+
end
|
49
71
|
end
|
50
72
|
end
|
51
73
|
end
|
@@ -0,0 +1,32 @@
|
|
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
|
@@ -1,6 +1,7 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative('../explicit_require')
|
2
3
|
|
3
|
-
Bootsnap::ExplicitRequire.with_gems('msgpack') { require
|
4
|
+
Bootsnap::ExplicitRequire.with_gems('msgpack') { require('msgpack') }
|
4
5
|
Bootsnap::ExplicitRequire.from_rubylibdir('fileutils')
|
5
6
|
|
6
7
|
module Bootsnap
|
@@ -11,7 +12,7 @@ module Bootsnap
|
|
11
12
|
|
12
13
|
def initialize(store_path)
|
13
14
|
@store_path = store_path
|
14
|
-
@
|
15
|
+
@txn_mutex = Mutex.new
|
15
16
|
@dirty = false
|
16
17
|
load_data
|
17
18
|
end
|
@@ -21,7 +22,7 @@ module Bootsnap
|
|
21
22
|
end
|
22
23
|
|
23
24
|
def fetch(key)
|
24
|
-
raise
|
25
|
+
raise(SetOutsideTransactionNotAllowed) unless @txn_mutex.owned?
|
25
26
|
v = get(key)
|
26
27
|
unless v
|
27
28
|
@dirty = true
|
@@ -32,7 +33,7 @@ module Bootsnap
|
|
32
33
|
end
|
33
34
|
|
34
35
|
def set(key, value)
|
35
|
-
raise
|
36
|
+
raise(SetOutsideTransactionNotAllowed) unless @txn_mutex.owned?
|
36
37
|
if value != @data[key]
|
37
38
|
@dirty = true
|
38
39
|
@data[key] = value
|
@@ -40,12 +41,14 @@ module Bootsnap
|
|
40
41
|
end
|
41
42
|
|
42
43
|
def transaction
|
43
|
-
raise
|
44
|
-
@
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
44
|
+
raise(NestedTransactionError) if @txn_mutex.owned?
|
45
|
+
@txn_mutex.synchronize do
|
46
|
+
begin
|
47
|
+
yield
|
48
|
+
ensure
|
49
|
+
commit_transaction
|
50
|
+
end
|
51
|
+
end
|
49
52
|
end
|
50
53
|
|
51
54
|
private
|
@@ -59,10 +62,18 @@ module Bootsnap
|
|
59
62
|
|
60
63
|
def load_data
|
61
64
|
@data = begin
|
62
|
-
|
63
|
-
|
65
|
+
File.open(@store_path, encoding: Encoding::BINARY) do |io|
|
66
|
+
MessagePack.load(io)
|
67
|
+
end
|
68
|
+
# handle malformed data due to upgrade incompatibility
|
64
69
|
rescue Errno::ENOENT, MessagePack::MalformedFormatError, MessagePack::UnknownExtTypeError, EOFError
|
65
70
|
{}
|
71
|
+
rescue ArgumentError => error
|
72
|
+
if error.message =~ /negative array size/
|
73
|
+
{}
|
74
|
+
else
|
75
|
+
raise
|
76
|
+
end
|
66
77
|
end
|
67
78
|
end
|
68
79
|
|
@@ -74,7 +85,9 @@ module Bootsnap
|
|
74
85
|
exclusive_write = File::Constants::CREAT | File::Constants::EXCL | File::Constants::WRONLY
|
75
86
|
# `encoding:` looks redundant wrt `binwrite`, but necessary on windows
|
76
87
|
# because binary is part of mode.
|
77
|
-
File.
|
88
|
+
File.open(tmp, mode: exclusive_write, encoding: Encoding::BINARY) do |io|
|
89
|
+
MessagePack.dump(@data, io, freeze: true)
|
90
|
+
end
|
78
91
|
FileUtils.mv(tmp, @store_path)
|
79
92
|
rescue Errno::EEXIST
|
80
93
|
retry
|
data/lib/bootsnap/setup.rb
CHANGED
@@ -1,41 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative('../bootsnap')
|
2
3
|
|
3
|
-
|
4
|
-
development_mode = ['', nil, 'development'].include?(env)
|
5
|
-
|
6
|
-
# only enable on 'ruby' (MRI), POSIX (darin, linux, *bsd), and >= 2.3.0
|
7
|
-
enable_cc =
|
8
|
-
RUBY_ENGINE == 'ruby' &&
|
9
|
-
RUBY_PLATFORM =~ /darwin|linux|bsd/ &&
|
10
|
-
Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.3.0")
|
11
|
-
|
12
|
-
cache_dir = ENV['BOOTSNAP_CACHE_DIR']
|
13
|
-
unless cache_dir
|
14
|
-
config_dir_frame = caller.detect do |line|
|
15
|
-
line.include?('/config/')
|
16
|
-
end
|
17
|
-
|
18
|
-
unless config_dir_frame
|
19
|
-
$stderr.puts "[bootsnap/setup] couldn't infer cache directory! Either:"
|
20
|
-
$stderr.puts "[bootsnap/setup] 1. require bootsnap/setup from your application's config directory; or"
|
21
|
-
$stderr.puts "[bootsnap/setup] 2. Define the environment variable BOOTSNAP_CACHE_DIR"
|
22
|
-
|
23
|
-
raise "couldn't infer bootsnap cache directory"
|
24
|
-
end
|
25
|
-
|
26
|
-
path = config_dir_frame.split(/:\d+:/).first
|
27
|
-
path = File.dirname(path) until File.basename(path) == 'config'
|
28
|
-
app_root = File.dirname(path)
|
29
|
-
|
30
|
-
cache_dir = File.join(app_root, 'tmp', 'cache')
|
31
|
-
end
|
32
|
-
|
33
|
-
Bootsnap.setup(
|
34
|
-
cache_dir: cache_dir,
|
35
|
-
development_mode: development_mode,
|
36
|
-
load_path_cache: true,
|
37
|
-
autoload_paths_cache: true, # assume rails. open to PRs to impl. detection
|
38
|
-
disable_trace: false,
|
39
|
-
compile_cache_iseq: enable_cc,
|
40
|
-
compile_cache_yaml: enable_cc
|
41
|
-
)
|
4
|
+
Bootsnap.default_setup
|
data/lib/bootsnap/version.rb
CHANGED
metadata
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bootsnap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Burke Libbey
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake-compiler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -97,31 +97,23 @@ dependencies:
|
|
97
97
|
description: Boot large ruby/rails apps faster
|
98
98
|
email:
|
99
99
|
- burke.libbey@shopify.com
|
100
|
-
executables:
|
100
|
+
executables:
|
101
|
+
- bootsnap
|
101
102
|
extensions:
|
102
103
|
- ext/bootsnap/extconf.rb
|
103
104
|
extra_rdoc_files: []
|
104
105
|
files:
|
105
|
-
- ".gitignore"
|
106
|
-
- ".rubocop.yml"
|
107
|
-
- ".travis.yml"
|
108
106
|
- CHANGELOG.md
|
109
|
-
- CODE_OF_CONDUCT.md
|
110
|
-
- CONTRIBUTING.md
|
111
|
-
- Gemfile
|
112
107
|
- LICENSE.txt
|
113
108
|
- README.md
|
114
|
-
-
|
115
|
-
- bin/console
|
116
|
-
- bin/setup
|
117
|
-
- bin/testunit
|
118
|
-
- bootsnap.gemspec
|
119
|
-
- dev.yml
|
109
|
+
- exe/bootsnap
|
120
110
|
- ext/bootsnap/bootsnap.c
|
121
111
|
- ext/bootsnap/bootsnap.h
|
122
112
|
- ext/bootsnap/extconf.rb
|
123
113
|
- lib/bootsnap.rb
|
124
114
|
- lib/bootsnap/bundler.rb
|
115
|
+
- lib/bootsnap/cli.rb
|
116
|
+
- lib/bootsnap/cli/worker_pool.rb
|
125
117
|
- lib/bootsnap/compile_cache.rb
|
126
118
|
- lib/bootsnap/compile_cache/iseq.rb
|
127
119
|
- lib/bootsnap/compile_cache/yaml.rb
|
@@ -129,17 +121,23 @@ files:
|
|
129
121
|
- lib/bootsnap/load_path_cache.rb
|
130
122
|
- lib/bootsnap/load_path_cache/cache.rb
|
131
123
|
- lib/bootsnap/load_path_cache/change_observer.rb
|
132
|
-
- lib/bootsnap/load_path_cache/core_ext/active_support.rb
|
133
124
|
- lib/bootsnap/load_path_cache/core_ext/kernel_require.rb
|
125
|
+
- lib/bootsnap/load_path_cache/core_ext/loaded_features.rb
|
126
|
+
- lib/bootsnap/load_path_cache/loaded_features_index.rb
|
134
127
|
- lib/bootsnap/load_path_cache/path.rb
|
135
128
|
- lib/bootsnap/load_path_cache/path_scanner.rb
|
129
|
+
- lib/bootsnap/load_path_cache/realpath_cache.rb
|
136
130
|
- lib/bootsnap/load_path_cache/store.rb
|
137
131
|
- lib/bootsnap/setup.rb
|
138
132
|
- lib/bootsnap/version.rb
|
139
133
|
homepage: https://github.com/Shopify/bootsnap
|
140
134
|
licenses:
|
141
135
|
- MIT
|
142
|
-
metadata:
|
136
|
+
metadata:
|
137
|
+
bug_tracker_uri: https://github.com/Shopify/bootsnap/issues
|
138
|
+
changelog_uri: https://github.com/Shopify/bootsnap/blob/master/CHANGELOG.md
|
139
|
+
source_code_uri: https://github.com/Shopify/bootsnap
|
140
|
+
allowed_push_host: https://rubygems.org
|
143
141
|
post_install_message:
|
144
142
|
rdoc_options: []
|
145
143
|
require_paths:
|
@@ -148,15 +146,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
148
146
|
requirements:
|
149
147
|
- - ">="
|
150
148
|
- !ruby/object:Gem::Version
|
151
|
-
version: 2.
|
149
|
+
version: 2.3.0
|
152
150
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
151
|
requirements:
|
154
152
|
- - ">="
|
155
153
|
- !ruby/object:Gem::Version
|
156
154
|
version: '0'
|
157
155
|
requirements: []
|
158
|
-
|
159
|
-
rubygems_version: 2.6.14
|
156
|
+
rubygems_version: 3.0.3
|
160
157
|
signing_key:
|
161
158
|
specification_version: 4
|
162
159
|
summary: Boot large ruby/rails apps faster
|
data/.gitignore
DELETED
data/.rubocop.yml
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
inherit_from:
|
2
|
-
- http://shopify.github.io/ruby-style-guide/rubocop.yml
|
3
|
-
|
4
|
-
AllCops:
|
5
|
-
Exclude:
|
6
|
-
- 'vendor/**/*'
|
7
|
-
- 'tmp/**/*'
|
8
|
-
TargetRubyVersion: '2.2'
|
9
|
-
|
10
|
-
# This doesn't take into account retrying from an exception
|
11
|
-
Lint/HandleExceptions:
|
12
|
-
Enabled: false
|
13
|
-
|
14
|
-
# allow String.new to create mutable strings
|
15
|
-
Style/EmptyLiteral:
|
16
|
-
Enabled: false
|
17
|
-
|
18
|
-
# allow the use of globals which makes sense in a CLI app like this
|
19
|
-
Style/GlobalVars:
|
20
|
-
Enabled: false
|