bootsnap 1.4.3-java → 1.4.8-java

Sign up to get free protection for your applications and to get access to all the features.
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
  - - ">="