bootsnap 1.1.1 → 1.3.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.
@@ -99,7 +99,7 @@ module Bootsnap
99
99
  @stability ||= begin
100
100
  if Gem.path.detect { |p| expanded_path.start_with?(p.to_s) }
101
101
  STABLE
102
- elsif expanded_path.start_with?(Bundler.bundle_path.to_s)
102
+ elsif Bootsnap.bundler? && expanded_path.start_with?(Bundler.bundle_path.to_s)
103
103
  STABLE
104
104
  elsif expanded_path.start_with?(RUBY_LIBDIR) && !expanded_path.start_with?(RUBY_SITEDIR)
105
105
  STABLE
@@ -1,13 +1,22 @@
1
- require_relative '../load_path_cache'
1
+ require_relative '../explicit_require'
2
2
 
3
3
  module Bootsnap
4
4
  module LoadPathCache
5
5
  module PathScanner
6
- REQUIRABLES_AND_DIRS = "/**/*{#{DOT_RB},#{DL_EXTENSIONS.join(',')},/}"
7
- IS_DIR = %r{(.*)/\z}
6
+ # Glob pattern to find requirable files and subdirectories in given path.
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
16
  NORMALIZE_NATIVE_EXTENSIONS = !DL_EXTENSIONS.include?(LoadPathCache::DOT_SO)
9
17
  ALTERNATIVE_NATIVE_EXTENSIONS_PATTERN = /\.(o|bundle|dylib)\z/
10
- BUNDLE_PATH = (Bundler.bundle_path.cleanpath.to_s << LoadPathCache::SLASH).freeze
18
+ BUNDLE_PATH = Bootsnap.bundler? ?
19
+ (Bundler.bundle_path.cleanpath.to_s << LoadPathCache::SLASH).freeze : ''.freeze
11
20
 
12
21
  def self.call(path)
13
22
  path = path.to_s
@@ -29,12 +38,13 @@ module Bootsnap
29
38
  next if contains_bundle_path && absolute_path.start_with?(BUNDLE_PATH)
30
39
  relative_path = absolute_path.slice!(relative_slice)
31
40
 
32
- if md = relative_path.match(IS_DIR)
33
- dirs << md[1]
41
+ if relative_path.end_with?('/')
42
+ dirs << relative_path[0..-2]
34
43
  else
35
44
  requirables << relative_path
36
45
  end
37
46
  end
47
+
38
48
  [requirables, dirs]
39
49
  end
40
50
  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
+ file = find_file(File.expand_path(path, base))
19
+ dir = File.dirname(file)
20
+ File.join(dir, File.basename(file))
21
+ end
22
+
23
+ def find_file(name)
24
+ ['', *CACHED_EXTENSIONS].each do |ext|
25
+ filename = "#{name}#{ext}"
26
+ return File.realpath(filename) if File.exist?(filename)
27
+ end
28
+ name
29
+ end
30
+ end
31
+ end
32
+ end
@@ -11,6 +11,8 @@ module Bootsnap
11
11
 
12
12
  def initialize(store_path)
13
13
  @store_path = store_path
14
+ @in_txn = false
15
+ @dirty = false
14
16
  load_data
15
17
  end
16
18
 
@@ -67,10 +69,15 @@ module Bootsnap
67
69
  def dump_data
68
70
  # Change contents atomically so other processes can't get invalid
69
71
  # caches if they read at an inopportune time.
70
- tmp = "#{@store_path}.#{(rand * 100000).to_i}.tmp"
72
+ tmp = "#{@store_path}.#{Process.pid}.#{(rand * 100000).to_i}.tmp"
71
73
  FileUtils.mkpath(File.dirname(tmp))
72
- File.binwrite(tmp, MessagePack.dump(@data))
74
+ exclusive_write = File::Constants::CREAT | File::Constants::EXCL | File::Constants::WRONLY
75
+ # `encoding:` looks redundant wrt `binwrite`, but necessary on windows
76
+ # because binary is part of mode.
77
+ File.binwrite(tmp, MessagePack.dump(@data), mode: exclusive_write, encoding: Encoding::BINARY)
73
78
  FileUtils.mv(tmp, @store_path)
79
+ rescue Errno::EEXIST
80
+ retry
74
81
  end
75
82
  end
76
83
  end
@@ -4,16 +4,10 @@ env = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || ENV['ENV']
4
4
  development_mode = ['', nil, 'development'].include?(env)
5
5
 
6
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
- RUBY_VERSION # "1.9.3"
11
- .split('.') # ["1", "9", "3"]
12
- .map(&:to_i) # [1, 9, 3]
13
- .zip([2, 3, -1]) # [[1, 2], [9, 3], [3, -1]]
14
- .map { |a, b| a <=> b } # [-1, 1, 1]
15
- .detect { |e| !e.zero? } # -1
16
- .==(1) # false
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")
17
11
 
18
12
  cache_dir = ENV['BOOTSNAP_CACHE_DIR']
19
13
  unless cache_dir
@@ -1,3 +1,3 @@
1
1
  module Bootsnap
2
- VERSION = "1.1.1"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -0,0 +1,4 @@
1
+ dependencies:
2
+ bundler:
3
+ without:
4
+ - development
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootsnap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Burke Libbey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-22 00:00:00.000000000 Z
11
+ date: 2018-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,7 +94,7 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '1.0'
97
- description: wip.
97
+ description: Boot large ruby/rails apps faster
98
98
  email:
99
99
  - burke.libbey@shopify.com
100
100
  executables: []
@@ -106,9 +106,11 @@ files:
106
106
  - ".rubocop.yml"
107
107
  - ".travis.yml"
108
108
  - CHANGELOG.md
109
+ - CODE_OF_CONDUCT.md
109
110
  - CONTRIBUTING.md
110
111
  - Gemfile
111
- - LICENSE
112
+ - LICENSE.txt
113
+ - README.jp.md
112
114
  - README.md
113
115
  - Rakefile
114
116
  - bin/console
@@ -120,6 +122,7 @@ files:
120
122
  - ext/bootsnap/bootsnap.h
121
123
  - ext/bootsnap/extconf.rb
122
124
  - lib/bootsnap.rb
125
+ - lib/bootsnap/bundler.rb
123
126
  - lib/bootsnap/compile_cache.rb
124
127
  - lib/bootsnap/compile_cache/iseq.rb
125
128
  - lib/bootsnap/compile_cache/yaml.rb
@@ -129,11 +132,14 @@ files:
129
132
  - lib/bootsnap/load_path_cache/change_observer.rb
130
133
  - lib/bootsnap/load_path_cache/core_ext/active_support.rb
131
134
  - lib/bootsnap/load_path_cache/core_ext/kernel_require.rb
135
+ - lib/bootsnap/load_path_cache/loaded_features_index.rb
132
136
  - lib/bootsnap/load_path_cache/path.rb
133
137
  - lib/bootsnap/load_path_cache/path_scanner.rb
138
+ - lib/bootsnap/load_path_cache/realpath_cache.rb
134
139
  - lib/bootsnap/load_path_cache/store.rb
135
140
  - lib/bootsnap/setup.rb
136
141
  - lib/bootsnap/version.rb
142
+ - shipit.rubygems.yml
137
143
  homepage: https://github.com/Shopify/bootsnap
138
144
  licenses:
139
145
  - MIT
@@ -154,8 +160,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
160
  version: '0'
155
161
  requirements: []
156
162
  rubyforge_project:
157
- rubygems_version: 2.6.10
163
+ rubygems_version: 2.7.6
158
164
  signing_key:
159
165
  specification_version: 4
160
- summary: wip
166
+ summary: Boot large ruby/rails apps faster
161
167
  test_files: []
data/LICENSE DELETED
@@ -1,20 +0,0 @@
1
- Copyright (c) 2017 Shopify
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.