bootsnap 1.4.3-java → 1.4.8-java

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -0
  3. data/README.md +1 -1
  4. data/ext/bootsnap/bootsnap.c +76 -42
  5. data/ext/bootsnap/extconf.rb +1 -0
  6. data/lib/bootsnap.rb +2 -0
  7. data/lib/bootsnap/bundler.rb +1 -0
  8. data/lib/bootsnap/compile_cache.rb +2 -1
  9. data/lib/bootsnap/compile_cache/iseq.rb +1 -0
  10. data/lib/bootsnap/compile_cache/yaml.rb +1 -0
  11. data/lib/bootsnap/explicit_require.rb +1 -0
  12. data/lib/bootsnap/load_path_cache/cache.rb +8 -8
  13. data/lib/bootsnap/load_path_cache/change_observer.rb +2 -1
  14. data/lib/bootsnap/load_path_cache/core_ext/active_support.rb +1 -0
  15. data/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb +18 -5
  16. data/lib/bootsnap/load_path_cache/core_ext/loaded_features.rb +1 -0
  17. data/lib/bootsnap/load_path_cache/loaded_features_index.rb +33 -10
  18. data/lib/bootsnap/load_path_cache/path.rb +3 -2
  19. data/lib/bootsnap/load_path_cache/path_scanner.rb +39 -26
  20. data/lib/bootsnap/load_path_cache/realpath_cache.rb +5 -5
  21. data/lib/bootsnap/load_path_cache/store.rb +18 -14
  22. data/lib/bootsnap/setup.rb +5 -1
  23. data/lib/bootsnap/version.rb +2 -1
  24. metadata +7 -25
  25. data/.github/CODEOWNERS +0 -2
  26. data/.github/probots.yml +0 -2
  27. data/.gitignore +0 -17
  28. data/.rubocop.yml +0 -20
  29. data/.travis.yml +0 -21
  30. data/CODE_OF_CONDUCT.md +0 -74
  31. data/CONTRIBUTING.md +0 -21
  32. data/Gemfile +0 -8
  33. data/README.jp.md +0 -231
  34. data/Rakefile +0 -12
  35. data/bin/ci +0 -10
  36. data/bin/console +0 -14
  37. data/bin/setup +0 -8
  38. data/bin/test-minimal-support +0 -7
  39. data/bin/testunit +0 -8
  40. data/bootsnap.gemspec +0 -45
  41. data/dev.yml +0 -10
  42. data/shipit.rubygems.yml +0 -0
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Bootsnap
2
3
  module LoadPathCache
3
4
  module ChangeObserver
@@ -25,7 +26,7 @@ module Bootsnap
25
26
  super
26
27
  end
27
28
 
28
- # uniq! keeps the first occurance of each path, otherwise preserving
29
+ # uniq! keeps the first occurrence of each path, otherwise preserving
29
30
  # order, preserving the effective load path
30
31
  def uniq!(*args)
31
32
  ret = super
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Bootsnap
2
3
  module LoadPathCache
3
4
  module CoreExt
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  module Bootsnap
2
3
  module LoadPathCache
3
4
  module CoreExt
4
5
  def self.make_load_error(path)
5
- err = LoadError.new("cannot load such file -- #{path}")
6
+ err = LoadError.new(+"cannot load such file -- #{path}")
6
7
  err.instance_variable_set(Bootsnap::LoadPathCache::ERROR_TAG_IVAR, true)
7
8
  err.define_singleton_method(:path) { path }
8
9
  err
@@ -37,7 +38,11 @@ module Kernel
37
38
  rescue Bootsnap::LoadPathCache::ReturnFalse
38
39
  false
39
40
  rescue Bootsnap::LoadPathCache::FallbackScan
40
- require_with_bootsnap_lfi(path)
41
+ fallback = true
42
+ ensure
43
+ if fallback
44
+ require_with_bootsnap_lfi(path)
45
+ end
41
46
  end
42
47
 
43
48
  alias_method(:require_relative_without_bootsnap, :require_relative)
@@ -55,7 +60,7 @@ module Kernel
55
60
  end
56
61
 
57
62
  # load also allows relative paths from pwd even when not in $:
58
- if File.exist?(relative = File.expand_path(path))
63
+ if File.exist?(relative = File.expand_path(path).freeze)
59
64
  return load_without_bootsnap(relative, wrap)
60
65
  end
61
66
 
@@ -66,7 +71,11 @@ module Kernel
66
71
  rescue Bootsnap::LoadPathCache::ReturnFalse
67
72
  false
68
73
  rescue Bootsnap::LoadPathCache::FallbackScan
69
- load_without_bootsnap(path, wrap)
74
+ fallback = true
75
+ ensure
76
+ if fallback
77
+ load_without_bootsnap(path, wrap)
78
+ end
70
79
  end
71
80
  end
72
81
 
@@ -87,6 +96,10 @@ class Module
87
96
  rescue Bootsnap::LoadPathCache::ReturnFalse
88
97
  false
89
98
  rescue Bootsnap::LoadPathCache::FallbackScan
90
- autoload_without_bootsnap(const, path)
99
+ fallback = true
100
+ ensure
101
+ if fallback
102
+ autoload_without_bootsnap(const, path)
103
+ end
91
104
  end
92
105
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class << $LOADED_FEATURES
2
3
  alias_method(:delete_without_bootsnap, :delete)
3
4
  def delete(key)
@@ -40,7 +40,7 @@ module Bootsnap
40
40
  # /a/b/lib/my/foo.rb
41
41
  # ^^^^^^^^^
42
42
  short = feat[(lpe.length + 1)..-1]
43
- stripped = strip_extension(short)
43
+ stripped = strip_extension_if_elidable(short)
44
44
  @lfi[short] = hash
45
45
  @lfi[stripped] = hash
46
46
  end
@@ -94,13 +94,14 @@ module Bootsnap
94
94
 
95
95
  hash = long.hash
96
96
 
97
- # do we have 'bundler' or 'bundler.rb'?
98
- altname = if File.extname(short) != ''
99
- # strip the path from 'bundler.rb' -> 'bundler'
100
- strip_extension(short)
101
- elsif long && (ext = File.extname(long))
102
- # get the extension from the expanded path if given
103
- # 'bundler' + '.rb'
97
+ # Do we have a filename with an elidable extension, e.g.,
98
+ # 'bundler.rb', or 'libgit2.so'?
99
+ altname = if extension_elidable?(short)
100
+ # Strip the extension off, e.g. 'bundler.rb' -> 'bundler'.
101
+ strip_extension_if_elidable(short)
102
+ elsif long && (ext = File.extname(long.freeze))
103
+ # We already know the extension of the actual file this
104
+ # resolves to, so put that back on.
104
105
  short + ext
105
106
  end
106
107
 
@@ -117,8 +118,30 @@ module Bootsnap
117
118
  STRIP_EXTENSION = /\.[^.]*?$/
118
119
  private_constant(:STRIP_EXTENSION)
119
120
 
120
- def strip_extension(f)
121
- f.sub(STRIP_EXTENSION, '')
121
+ # Might Ruby automatically search for this extension if
122
+ # someone tries to 'require' the file without it? E.g. Ruby
123
+ # will implicitly try 'x.rb' if you ask for 'x'.
124
+ #
125
+ # This is complex and platform-dependent, and the Ruby docs are a little
126
+ # handwavy about what will be tried when and in what order.
127
+ # So optimistically pretend that all known elidable extensions
128
+ # will be tried on all platforms, and that people are unlikely
129
+ # to name files in a way that assumes otherwise.
130
+ # (E.g. It's unlikely that someone will know that their code
131
+ # will _never_ run on MacOS, and therefore think they can get away
132
+ # with calling a Ruby file 'x.dylib.rb' and then requiring it as 'x.dylib'.)
133
+ #
134
+ # See <https://ruby-doc.org/core-2.6.4/Kernel.html#method-i-require>.
135
+ def extension_elidable?(f)
136
+ f.to_s.end_with?('.rb', '.so', '.o', '.dll', '.dylib')
137
+ end
138
+
139
+ def strip_extension_if_elidable(f)
140
+ if extension_elidable?(f)
141
+ f.sub(STRIP_EXTENSION, '')
142
+ else
143
+ f
144
+ end
122
145
  end
123
146
  end
124
147
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require_relative('path_scanner')
2
3
 
3
4
  module Bootsnap
@@ -20,7 +21,7 @@ module Bootsnap
20
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
@@ -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
@@ -5,7 +5,6 @@ require_relative('../explicit_require')
5
5
  module Bootsnap
6
6
  module LoadPathCache
7
7
  module PathScanner
8
- ALL_FILES = "/{,**/*/**/}*"
9
8
  REQUIRABLE_EXTENSIONS = [DOT_RB] + DL_EXTENSIONS
10
9
  NORMALIZE_NATIVE_EXTENSIONS = !DL_EXTENSIONS.include?(LoadPathCache::DOT_SO)
11
10
  ALTERNATIVE_NATIVE_EXTENSIONS_PATTERN = /\.(o|bundle|dylib)\z/
@@ -16,34 +15,48 @@ module Bootsnap
16
15
  ''
17
16
  end
18
17
 
19
- def self.call(path)
20
- path = path.to_s
21
-
22
- relative_slice = (path.size + 1)..-1
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
-
35
- Dir.glob(path + ALL_FILES).each do |absolute_path|
36
- next if contains_bundle_path && absolute_path.start_with?(BUNDLE_PATH)
37
- relative_path = absolute_path.slice(relative_slice)
38
-
39
- if File.directory?(absolute_path)
40
- dirs << relative_path
41
- elsif REQUIRABLE_EXTENSIONS.include?(File.extname(relative_path))
42
- requirables << relative_path
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
43
41
  end
42
+ [requirables, dirs]
44
43
  end
45
44
 
46
- [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
47
60
  end
48
61
  end
49
62
  end
@@ -15,15 +15,15 @@ module Bootsnap
15
15
 
16
16
  def realpath(caller_location, path)
17
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))
18
+ abspath = File.expand_path(path, base).freeze
19
+ find_file(abspath)
21
20
  end
22
21
 
23
22
  def find_file(name)
24
- ['', *CACHED_EXTENSIONS].each do |ext|
23
+ return File.realpath(name).freeze if File.exist?(name)
24
+ CACHED_EXTENSIONS.each do |ext|
25
25
  filename = "#{name}#{ext}"
26
- return File.realpath(filename) if File.exist?(filename)
26
+ return File.realpath(filename).freeze if File.exist?(filename)
27
27
  end
28
28
  name
29
29
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require_relative('../explicit_require')
2
3
 
3
4
  Bootsnap::ExplicitRequire.with_gems('msgpack') { require('msgpack') }
@@ -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,11 +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
- {}
66
- rescue ArgumentError => e
67
- e.message =~ /negative array size/ ? {} : raise
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
68
72
  end
69
73
  end
70
74
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require_relative('../bootsnap')
2
3
 
3
4
  env = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || ENV['ENV']
@@ -24,12 +25,15 @@ unless cache_dir
24
25
  cache_dir = File.join(app_root, 'tmp', 'cache')
25
26
  end
26
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
+
27
31
  Bootsnap.setup(
28
32
  cache_dir: cache_dir,
29
33
  development_mode: development_mode,
30
34
  load_path_cache: true,
31
35
  autoload_paths_cache: true, # assume rails. open to PRs to impl. detection
32
36
  disable_trace: false,
33
- compile_cache_iseq: true,
37
+ compile_cache_iseq: iseq_cache_enabled,
34
38
  compile_cache_yaml: true,
35
39
  )
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Bootsnap
2
- VERSION = "1.4.3"
3
+ VERSION = "1.4.8"
3
4
  end
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.4.3
4
+ version: 1.4.8
5
5
  platform: java
6
6
  authors:
7
7
  - Burke Libbey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-08 00:00:00.000000000 Z
11
+ date: 2020-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -27,17 +27,17 @@ dependencies:
27
27
  - !ruby/object:Gem::Dependency
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
- - - "~>"
30
+ - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: '10.0'
32
+ version: '0'
33
33
  name: rake
34
34
  prerelease: false
35
35
  type: :development
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
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
@@ -101,26 +101,9 @@ executables: []
101
101
  extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
- - ".github/CODEOWNERS"
105
- - ".github/probots.yml"
106
- - ".gitignore"
107
- - ".rubocop.yml"
108
- - ".travis.yml"
109
104
  - CHANGELOG.md
110
- - CODE_OF_CONDUCT.md
111
- - CONTRIBUTING.md
112
- - Gemfile
113
105
  - LICENSE.txt
114
- - README.jp.md
115
106
  - README.md
116
- - Rakefile
117
- - bin/ci
118
- - bin/console
119
- - bin/setup
120
- - bin/test-minimal-support
121
- - bin/testunit
122
- - bootsnap.gemspec
123
- - dev.yml
124
107
  - ext/bootsnap/bootsnap.c
125
108
  - ext/bootsnap/bootsnap.h
126
109
  - ext/bootsnap/extconf.rb
@@ -143,7 +126,6 @@ files:
143
126
  - lib/bootsnap/load_path_cache/store.rb
144
127
  - lib/bootsnap/setup.rb
145
128
  - lib/bootsnap/version.rb
146
- - shipit.rubygems.yml
147
129
  homepage: https://github.com/Shopify/bootsnap
148
130
  licenses:
149
131
  - MIT
@@ -159,7 +141,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
159
141
  requirements:
160
142
  - - ">="
161
143
  - !ruby/object:Gem::Version
162
- version: 2.0.0
144
+ version: 2.3.0
163
145
  required_rubygems_version: !ruby/object:Gem::Requirement
164
146
  requirements:
165
147
  - - ">="