bootsnap 1.1.8-java → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +103 -0
  3. data/README.md +47 -6
  4. data/exe/bootsnap +5 -0
  5. data/ext/bootsnap/bootsnap.c +217 -88
  6. data/ext/bootsnap/extconf.rb +3 -1
  7. data/lib/bootsnap.rb +17 -8
  8. data/lib/bootsnap/bundler.rb +6 -3
  9. data/lib/bootsnap/cli.rb +246 -0
  10. data/lib/bootsnap/cli/worker_pool.rb +131 -0
  11. data/lib/bootsnap/compile_cache.rb +32 -4
  12. data/lib/bootsnap/compile_cache/iseq.rb +32 -15
  13. data/lib/bootsnap/compile_cache/yaml.rb +94 -40
  14. data/lib/bootsnap/explicit_require.rb +2 -1
  15. data/lib/bootsnap/load_path_cache.rb +35 -9
  16. data/lib/bootsnap/load_path_cache/cache.rb +48 -29
  17. data/lib/bootsnap/load_path_cache/change_observer.rb +36 -29
  18. data/lib/bootsnap/load_path_cache/core_ext/active_support.rb +39 -7
  19. data/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb +70 -53
  20. data/lib/bootsnap/load_path_cache/core_ext/loaded_features.rb +18 -0
  21. data/lib/bootsnap/load_path_cache/loaded_features_index.rb +148 -0
  22. data/lib/bootsnap/load_path_cache/path.rb +8 -7
  23. data/lib/bootsnap/load_path_cache/path_scanner.rb +50 -39
  24. data/lib/bootsnap/load_path_cache/realpath_cache.rb +32 -0
  25. data/lib/bootsnap/load_path_cache/store.rb +20 -14
  26. data/lib/bootsnap/setup.rb +11 -13
  27. data/lib/bootsnap/version.rb +2 -1
  28. metadata +44 -45
  29. data/.gitignore +0 -17
  30. data/.rubocop.yml +0 -20
  31. data/.travis.yml +0 -4
  32. data/CODE_OF_CONDUCT.md +0 -74
  33. data/CONTRIBUTING.md +0 -21
  34. data/Gemfile +0 -8
  35. data/Rakefile +0 -11
  36. data/bin/console +0 -14
  37. data/bin/setup +0 -8
  38. data/bin/testunit +0 -8
  39. data/bootsnap.gemspec +0 -39
  40. data/dev.yml +0 -10
@@ -1,4 +1,5 @@
1
- require_relative 'path_scanner'
1
+ # frozen_string_literal: true
2
+ require_relative('path_scanner')
2
3
 
3
4
  module Bootsnap
4
5
  module LoadPathCache
@@ -17,16 +18,16 @@ module Bootsnap
17
18
  stability == VOLATILE
18
19
  end
19
20
 
20
- attr_reader :path
21
+ attr_reader(:path)
21
22
 
22
23
  def initialize(path)
23
- @path = path.to_s
24
+ @path = path.to_s.freeze
24
25
  end
25
26
 
26
27
  # True if the path exists, but represents a non-directory object
27
28
  def non_directory?
28
29
  !File.stat(path).directory?
29
- rescue Errno::ENOENT
30
+ rescue Errno::ENOENT, Errno::ENOTDIR
30
31
  false
31
32
  end
32
33
 
@@ -59,7 +60,7 @@ module Bootsnap
59
60
  end
60
61
 
61
62
  def expanded_path
62
- File.expand_path(path)
63
+ File.expand_path(path).freeze
63
64
  end
64
65
 
65
66
  private
@@ -76,8 +77,8 @@ module Bootsnap
76
77
  ["", *dirs].each do |dir|
77
78
  curr = begin
78
79
  File.mtime("#{path}/#{dir}").to_i
79
- rescue Errno::ENOENT
80
- -1
80
+ rescue Errno::ENOENT, Errno::ENOTDIR
81
+ -1
81
82
  end
82
83
  max = curr if curr > max
83
84
  end
@@ -1,51 +1,62 @@
1
- require_relative '../explicit_require'
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
- # 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
+ 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
- BUNDLE_PATH = Bootsnap.bundler? ?
19
- (Bundler.bundle_path.cleanpath.to_s << LoadPathCache::SLASH).freeze : ''.freeze
20
-
21
- def self.call(path)
22
- path = path.to_s
23
-
24
- relative_slice = (path.size + 1)..-1
25
- # If the bundle path is a descendent of this path, we do additional
26
- # checks to prevent recursing into the bundle path as we recurse
27
- # through this path. We don't want to scan the bundle path because
28
- # anything useful in it will be present on other load path items.
29
- #
30
- # This can happen if, for example, the user adds '.' to the load path,
31
- # and the bundle path is '.bundle'.
32
- contains_bundle_path = BUNDLE_PATH.start_with?(path)
33
-
34
- dirs = []
35
- requirables = []
36
-
37
- Dir.glob(path + REQUIRABLES_AND_DIRS).each do |absolute_path|
38
- next if contains_bundle_path && absolute_path.start_with?(BUNDLE_PATH)
39
- relative_path = absolute_path.slice!(relative_slice)
40
-
41
- if relative_path.end_with?('/')
42
- dirs << relative_path[0..-2]
43
- else
44
- requirables << relative_path
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 << relative_path
37
+ !contains_bundle_path || !absolute_path.start_with?(BUNDLE_PATH)
38
+ elsif relative_path.end_with?(*REQUIRABLE_EXTENSIONS)
39
+ requirables << relative_path
40
+ end
45
41
  end
42
+ [requirables, dirs]
46
43
  end
47
44
 
48
- [requirables, dirs]
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 ? "#{relative_dir_path}/#{name}" : name.freeze
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
49
60
  end
50
61
  end
51
62
  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
- require_relative '../explicit_require'
1
+ # frozen_string_literal: true
2
+ require_relative('../explicit_require')
2
3
 
3
- Bootsnap::ExplicitRequire.with_gems('msgpack') { require 'msgpack' }
4
+ Bootsnap::ExplicitRequire.with_gems('msgpack') { require('msgpack') }
4
5
  Bootsnap::ExplicitRequire.from_rubylibdir('fileutils')
5
6
 
6
7
  module Bootsnap
@@ -11,7 +12,8 @@ module Bootsnap
11
12
 
12
13
  def initialize(store_path)
13
14
  @store_path = store_path
14
- @in_txn = false
15
+ # TODO: Remove conditional once Ruby 2.2 support is dropped.
16
+ @txn_mutex = defined?(::Mutex) ? ::Mutex.new : ::Thread::Mutex.new
15
17
  @dirty = false
16
18
  load_data
17
19
  end
@@ -21,7 +23,7 @@ module Bootsnap
21
23
  end
22
24
 
23
25
  def fetch(key)
24
- raise SetOutsideTransactionNotAllowed unless @in_txn
26
+ raise(SetOutsideTransactionNotAllowed) unless @txn_mutex.owned?
25
27
  v = get(key)
26
28
  unless v
27
29
  @dirty = true
@@ -32,7 +34,7 @@ module Bootsnap
32
34
  end
33
35
 
34
36
  def set(key, value)
35
- raise SetOutsideTransactionNotAllowed unless @in_txn
37
+ raise(SetOutsideTransactionNotAllowed) unless @txn_mutex.owned?
36
38
  if value != @data[key]
37
39
  @dirty = true
38
40
  @data[key] = value
@@ -40,12 +42,14 @@ module Bootsnap
40
42
  end
41
43
 
42
44
  def transaction
43
- raise NestedTransactionError if @in_txn
44
- @in_txn = true
45
- yield
46
- ensure
47
- commit_transaction
48
- @in_txn = false
45
+ raise(NestedTransactionError) if @txn_mutex.owned?
46
+ @txn_mutex.synchronize do
47
+ begin
48
+ yield
49
+ ensure
50
+ commit_transaction
51
+ end
52
+ end
49
53
  end
50
54
 
51
55
  private
@@ -60,9 +64,11 @@ module Bootsnap
60
64
  def load_data
61
65
  @data = begin
62
66
  MessagePack.load(File.binread(@store_path))
63
- # handle malformed data due to upgrade incompatability
64
- rescue Errno::ENOENT, MessagePack::MalformedFormatError, MessagePack::UnknownExtTypeError, EOFError
65
- {}
67
+ # handle malformed data due to upgrade incompatibility
68
+ rescue Errno::ENOENT, MessagePack::MalformedFormatError, MessagePack::UnknownExtTypeError, EOFError
69
+ {}
70
+ rescue ArgumentError => e
71
+ e.message =~ /negative array size/ ? {} : raise
66
72
  end
67
73
  end
68
74
 
@@ -1,14 +1,9 @@
1
- require_relative '../bootsnap'
1
+ # frozen_string_literal: true
2
+ require_relative('../bootsnap')
2
3
 
3
4
  env = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || ENV['ENV']
4
5
  development_mode = ['', nil, 'development'].include?(env)
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
- Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.3.0")
11
-
12
7
  cache_dir = ENV['BOOTSNAP_CACHE_DIR']
13
8
  unless cache_dir
14
9
  config_dir_frame = caller.detect do |line|
@@ -16,11 +11,11 @@ unless cache_dir
16
11
  end
17
12
 
18
13
  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"
14
+ $stderr.puts("[bootsnap/setup] couldn't infer cache directory! Either:")
15
+ $stderr.puts("[bootsnap/setup] 1. require bootsnap/setup from your application's config directory; or")
16
+ $stderr.puts("[bootsnap/setup] 2. Define the environment variable BOOTSNAP_CACHE_DIR")
22
17
 
23
- raise "couldn't infer bootsnap cache directory"
18
+ raise("couldn't infer bootsnap cache directory")
24
19
  end
25
20
 
26
21
  path = config_dir_frame.split(/:\d+:/).first
@@ -30,12 +25,15 @@ unless cache_dir
30
25
  cache_dir = File.join(app_root, 'tmp', 'cache')
31
26
  end
32
27
 
28
+ ruby_version = Gem::Version.new(RUBY_VERSION)
29
+ iseq_cache_enabled = ruby_version < Gem::Version.new('2.5.0') || ruby_version >= Gem::Version.new('2.6.0')
30
+
33
31
  Bootsnap.setup(
34
32
  cache_dir: cache_dir,
35
33
  development_mode: development_mode,
36
34
  load_path_cache: true,
37
35
  autoload_paths_cache: true, # assume rails. open to PRs to impl. detection
38
36
  disable_trace: false,
39
- compile_cache_iseq: enable_cc,
40
- compile_cache_yaml: enable_cc
37
+ compile_cache_iseq: iseq_cache_enabled,
38
+ compile_cache_yaml: true,
41
39
  )
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Bootsnap
2
- VERSION = "1.1.8"
3
+ VERSION = "1.6.0"
3
4
  end
metadata CHANGED
@@ -1,94 +1,94 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootsnap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.8
5
- platform: java
4
+ version: 1.6.0
5
+ platform: ruby
6
6
  authors:
7
7
  - Burke Libbey
8
- autorequire:
9
- bindir: bin
8
+ autorequire:
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2018-01-05 00:00:00.000000000 Z
11
+ date: 2021-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
+ name: bundler
14
15
  requirement: !ruby/object:Gem::Requirement
15
16
  requirements:
16
- - - "~>"
17
+ - - ">="
17
18
  - !ruby/object:Gem::Version
18
- version: '1'
19
- name: bundler
20
- prerelease: false
19
+ version: '0'
21
20
  type: :development
21
+ prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
+ name: rake
28
29
  requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - "~>"
31
+ - - ">="
31
32
  - !ruby/object:Gem::Version
32
- version: '10.0'
33
- name: rake
34
- prerelease: false
33
+ version: '0'
35
34
  type: :development
35
+ prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
+ name: rake-compiler
42
43
  requirement: !ruby/object:Gem::Requirement
43
44
  requirements:
44
45
  - - "~>"
45
46
  - !ruby/object:Gem::Version
46
47
  version: '0'
47
- name: rake-compiler
48
- prerelease: false
49
48
  type: :development
49
+ prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
+ name: minitest
56
57
  requirement: !ruby/object:Gem::Requirement
57
58
  requirements:
58
59
  - - "~>"
59
60
  - !ruby/object:Gem::Version
60
61
  version: '5.0'
61
- name: minitest
62
- prerelease: false
63
62
  type: :development
63
+ prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '5.0'
69
69
  - !ruby/object:Gem::Dependency
70
+ name: mocha
70
71
  requirement: !ruby/object:Gem::Requirement
71
72
  requirements:
72
73
  - - "~>"
73
74
  - !ruby/object:Gem::Version
74
75
  version: '1.2'
75
- name: mocha
76
- prerelease: false
77
76
  type: :development
77
+ prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.2'
83
83
  - !ruby/object:Gem::Dependency
84
+ name: msgpack
84
85
  requirement: !ruby/object:Gem::Requirement
85
86
  requirements:
86
87
  - - "~>"
87
88
  - !ruby/object:Gem::Version
88
89
  version: '1.0'
89
- name: msgpack
90
- prerelease: false
91
90
  type: :runtime
91
+ prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
@@ -97,30 +97,23 @@ dependencies:
97
97
  description: Boot large ruby/rails apps faster
98
98
  email:
99
99
  - burke.libbey@shopify.com
100
- executables: []
101
- extensions: []
100
+ executables:
101
+ - bootsnap
102
+ extensions:
103
+ - ext/bootsnap/extconf.rb
102
104
  extra_rdoc_files: []
103
105
  files:
104
- - ".gitignore"
105
- - ".rubocop.yml"
106
- - ".travis.yml"
107
106
  - CHANGELOG.md
108
- - CODE_OF_CONDUCT.md
109
- - CONTRIBUTING.md
110
- - Gemfile
111
107
  - LICENSE.txt
112
108
  - README.md
113
- - Rakefile
114
- - bin/console
115
- - bin/setup
116
- - bin/testunit
117
- - bootsnap.gemspec
118
- - dev.yml
109
+ - exe/bootsnap
119
110
  - ext/bootsnap/bootsnap.c
120
111
  - ext/bootsnap/bootsnap.h
121
112
  - ext/bootsnap/extconf.rb
122
113
  - lib/bootsnap.rb
123
114
  - lib/bootsnap/bundler.rb
115
+ - lib/bootsnap/cli.rb
116
+ - lib/bootsnap/cli/worker_pool.rb
124
117
  - lib/bootsnap/compile_cache.rb
125
118
  - lib/bootsnap/compile_cache/iseq.rb
126
119
  - lib/bootsnap/compile_cache/yaml.rb
@@ -130,16 +123,23 @@ files:
130
123
  - lib/bootsnap/load_path_cache/change_observer.rb
131
124
  - lib/bootsnap/load_path_cache/core_ext/active_support.rb
132
125
  - lib/bootsnap/load_path_cache/core_ext/kernel_require.rb
126
+ - lib/bootsnap/load_path_cache/core_ext/loaded_features.rb
127
+ - lib/bootsnap/load_path_cache/loaded_features_index.rb
133
128
  - lib/bootsnap/load_path_cache/path.rb
134
129
  - lib/bootsnap/load_path_cache/path_scanner.rb
130
+ - lib/bootsnap/load_path_cache/realpath_cache.rb
135
131
  - lib/bootsnap/load_path_cache/store.rb
136
132
  - lib/bootsnap/setup.rb
137
133
  - lib/bootsnap/version.rb
138
134
  homepage: https://github.com/Shopify/bootsnap
139
135
  licenses:
140
136
  - MIT
141
- metadata: {}
142
- post_install_message:
137
+ metadata:
138
+ bug_tracker_uri: https://github.com/Shopify/bootsnap/issues
139
+ changelog_uri: https://github.com/Shopify/bootsnap/blob/master/CHANGELOG.md
140
+ source_code_uri: https://github.com/Shopify/bootsnap
141
+ allowed_push_host: https://rubygems.org
142
+ post_install_message:
143
143
  rdoc_options: []
144
144
  require_paths:
145
145
  - lib
@@ -147,16 +147,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
147
147
  requirements:
148
148
  - - ">="
149
149
  - !ruby/object:Gem::Version
150
- version: 2.0.0
150
+ version: 2.3.0
151
151
  required_rubygems_version: !ruby/object:Gem::Requirement
152
152
  requirements:
153
153
  - - ">="
154
154
  - !ruby/object:Gem::Version
155
155
  version: '0'
156
156
  requirements: []
157
- rubyforge_project:
158
- rubygems_version: 2.4.8
159
- signing_key:
157
+ rubygems_version: 3.0.3
158
+ signing_key:
160
159
  specification_version: 4
161
160
  summary: Boot large ruby/rails apps faster
162
161
  test_files: []