bootsnap 1.4.6-java → 1.4.7-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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1bc6287c7bacc07db2b707a99dac5e6cd0b3a5b1
4
- data.tar.gz: 98d79072d34f986dc1caa38aee469cbc070bd334
3
+ metadata.gz: 8899832e85cf667b8998afb667ab8d2148dc3888
4
+ data.tar.gz: 079fc2b08369692117a9d36131ecede24d203fbc
5
5
  SHA512:
6
- metadata.gz: f823dc1c7a10d57b4cefac71dbca6a4b94d8fd0015a69c194cb7ea47ac28fc9694888533d7de58b8a7adedab0b779ac422d389a669690f880afeff9bb3b6487b
7
- data.tar.gz: 9d80f121235529847a427b286772b758c5efa14e208799f3761502b521a84b44e495d7c5024f1acc2d70bb8071d95e2d12a05e043ec57668d2edce20f9504fd7
6
+ metadata.gz: 11cd0f02fa786ed636d282d673694ce45f94f9a73909c10d5599ade29dec84c61707ce3bc4c6e83faa6d57419b397f16e0865c83491d5c76d53baaa146cf82d9
7
+ data.tar.gz: 43cff5bf18a24c7207cd2b0d74bfb4893f59538dc91844aac748eeec54df6499623cd8d3e3bef86504498d6b0d439e1f480f5a9fb9bb36fd7cadc12dc7a9b306
@@ -8,7 +8,7 @@ AllCops:
8
8
  TargetRubyVersion: '2.3'
9
9
 
10
10
  # This doesn't take into account retrying from an exception
11
- Lint/HandleExceptions:
11
+ Lint/SuppressedException:
12
12
  Enabled: false
13
13
 
14
14
  # allow String.new to create mutable strings
@@ -6,8 +6,10 @@ os:
6
6
  - osx
7
7
 
8
8
  rvm:
9
- - ruby-2.4
10
- - ruby-2.5
9
+ - '2.4'
10
+ - '2.5'
11
+ - '2.6'
12
+ - '2.7'
11
13
  - ruby-head
12
14
 
13
15
  matrix:
@@ -17,5 +19,7 @@ matrix:
17
19
  - rvm: jruby
18
20
  os: linux
19
21
  env: MINIMAL_SUPPORT=1
20
-
22
+ - rvm: truffleruby
23
+ os: linux
24
+ env: MINIMAL_SUPPORT=1
21
25
  script: bin/ci
@@ -1,3 +1,22 @@
1
+ # 1.4.7
2
+
3
+ * Various performance enhancements
4
+ * Fix race condition in heavy concurrent load scenarios that would cause bootsnap to raise
5
+
6
+ # 1.4.6
7
+
8
+ * Fix bug that was erroneously considering that files containing `.` in the names were being
9
+ required if a different file with the same name was already being required
10
+
11
+ Example:
12
+
13
+ require 'foo'
14
+ require 'foo.en'
15
+
16
+ Before bootsnap was considering `foo.en` to be the same file as `foo`
17
+
18
+ * Use glibc as part of the ruby_platform cache key
19
+
1
20
  # 1.4.5
2
21
 
3
22
  * MRI 2.7 support
data/Rakefile CHANGED
@@ -10,4 +10,8 @@ Rake::ExtensionTask.new do |ext|
10
10
  ext.gem_spec = gemspec
11
11
  end
12
12
 
13
- task(default: :compile)
13
+ task :test do
14
+ sh 'bin/testunit'
15
+ end
16
+
17
+ task(default: %i(compile test))
data/bin/ci CHANGED
@@ -5,6 +5,5 @@ set -euxo pipefail
5
5
  if [[ "${MINIMAL_SUPPORT-0}" -eq 1 ]]; then
6
6
  exec bin/test-minimal-support
7
7
  else
8
- rake
9
- exec bin/testunit
8
+ exec rake
10
9
  fi
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
37
37
  end
38
38
 
39
39
  spec.add_development_dependency("bundler")
40
- spec.add_development_dependency('rake', '~> 10.0')
40
+ spec.add_development_dependency('rake')
41
41
  spec.add_development_dependency('rake-compiler', '~> 0')
42
42
  spec.add_development_dependency("minitest", "~> 5.0")
43
43
  spec.add_development_dependency("mocha", "~> 1.2")
@@ -32,6 +32,8 @@
32
32
 
33
33
  #define KEY_SIZE 64
34
34
 
35
+ #define MAX_CREATE_TEMPFILE_ATTEMPT 3
36
+
35
37
  /*
36
38
  * An instance of this key is written as the first 64 bytes of each cache file.
37
39
  * The mtime and size members track whether the file contents have changed, and
@@ -499,25 +501,32 @@ atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data, cons
499
501
  {
500
502
  char template[MAX_CACHEPATH_SIZE + 20];
501
503
  char * tmp_path;
502
- int fd, ret;
504
+ int fd, ret, attempt;
503
505
  ssize_t nwrite;
504
506
 
505
- tmp_path = strncpy(template, path, MAX_CACHEPATH_SIZE);
506
- strcat(tmp_path, ".tmp.XXXXXX");
507
+ for (attempt = 0; attempt < MAX_CREATE_TEMPFILE_ATTEMPT; ++attempt) {
508
+ tmp_path = strncpy(template, path, MAX_CACHEPATH_SIZE);
509
+ strcat(tmp_path, ".tmp.XXXXXX");
507
510
 
508
- // mkstemp modifies the template to be the actual created path
509
- fd = mkstemp(tmp_path);
510
- if (fd < 0) {
511
- if (mkpath(tmp_path, 0775) < 0) {
511
+ // mkstemp modifies the template to be the actual created path
512
+ fd = mkstemp(tmp_path);
513
+ if (fd > 0) break;
514
+
515
+ if (attempt == 0 && mkpath(tmp_path, 0775) < 0) {
512
516
  *errno_provenance = "bs_fetch:atomic_write_cache_file:mkpath";
513
517
  return -1;
514
518
  }
515
- fd = open(tmp_path, O_WRONLY | O_CREAT, 0664);
516
- if (fd < 0) {
517
- *errno_provenance = "bs_fetch:atomic_write_cache_file:open";
518
- return -1;
519
- }
520
519
  }
520
+ if (fd < 0) {
521
+ *errno_provenance = "bs_fetch:atomic_write_cache_file:mkstemp";
522
+ return -1;
523
+ }
524
+
525
+ if (chmod(tmp_path, 0644) < 0) {
526
+ *errno_provenance = "bs_fetch:atomic_write_cache_file:chmod";
527
+ return -1;
528
+ }
529
+
521
530
  #ifdef _WIN32
522
531
  setmode(fd, O_BINARY);
523
532
  #endif
@@ -800,7 +809,7 @@ try_input_to_storage(VALUE arg)
800
809
  }
801
810
 
802
811
  static VALUE
803
- rescue_input_to_storage(VALUE arg)
812
+ rescue_input_to_storage(VALUE arg, VALUE e)
804
813
  {
805
814
  return uncompilable;
806
815
  }
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative('bootsnap/version')
3
4
  require_relative('bootsnap/bundler')
4
5
  require_relative('bootsnap/load_path_cache')
@@ -46,7 +46,7 @@ module Bootsnap
46
46
  # loadpath.
47
47
  def find(feature)
48
48
  reinitialize if (@has_relative_paths && dir_changed?) || stale?
49
- feature = feature.to_s
49
+ feature = feature.to_s.freeze
50
50
  return feature if absolute_path?(feature)
51
51
  return expand_path(feature) if feature.start_with?('./')
52
52
  @mutex.synchronize do
@@ -178,25 +178,25 @@ module Bootsnap
178
178
 
179
179
  if DLEXT2
180
180
  def search_index(f)
181
- try_index(f + DOT_RB) || try_index(f + DLEXT) || try_index(f + DLEXT2) || try_index(f)
181
+ try_index("#{f}#{DOT_RB}") || try_index("#{f}#{DLEXT}") || try_index("#{f}#{DLEXT2}") || try_index(f)
182
182
  end
183
183
 
184
184
  def maybe_append_extension(f)
185
- try_ext(f + DOT_RB) || try_ext(f + DLEXT) || try_ext(f + DLEXT2) || f
185
+ try_ext("#{f}#{DOT_RB}") || try_ext("#{f}#{DLEXT}") || try_ext("#{f}#{DLEXT2}") || f
186
186
  end
187
187
  else
188
188
  def search_index(f)
189
- try_index(f + DOT_RB) || try_index(f + DLEXT) || try_index(f)
189
+ try_index("#{f}#{DOT_RB}") || try_index("#{f}#{DLEXT}") || try_index(f)
190
190
  end
191
191
 
192
192
  def maybe_append_extension(f)
193
- try_ext(f + DOT_RB) || try_ext(f + DLEXT) || f
193
+ try_ext("#{f}#{DOT_RB}") || try_ext("#{f}#{DLEXT}") || f
194
194
  end
195
195
  end
196
196
 
197
197
  def try_index(f)
198
198
  if (p = @index[f])
199
- p + '/' + f
199
+ "#{p}/#{f}"
200
200
  end
201
201
  end
202
202
 
@@ -26,7 +26,7 @@ module Bootsnap
26
26
  super
27
27
  end
28
28
 
29
- # uniq! keeps the first occurance of each path, otherwise preserving
29
+ # uniq! keeps the first occurrence of each path, otherwise preserving
30
30
  # order, preserving the effective load path
31
31
  def uniq!(*args)
32
32
  ret = super
@@ -56,7 +56,7 @@ module Kernel
56
56
  end
57
57
 
58
58
  # load also allows relative paths from pwd even when not in $:
59
- if File.exist?(relative = File.expand_path(path))
59
+ if File.exist?(relative = File.expand_path(path).freeze)
60
60
  return load_without_bootsnap(relative, wrap)
61
61
  end
62
62
 
@@ -99,7 +99,7 @@ module Bootsnap
99
99
  altname = if extension_elidable?(short)
100
100
  # Strip the extension off, e.g. 'bundler.rb' -> 'bundler'.
101
101
  strip_extension_if_elidable(short)
102
- elsif long && (ext = File.extname(long))
102
+ elsif long && (ext = File.extname(long.freeze))
103
103
  # We already know the extension of the actual file this
104
104
  # resolves to, so put that back on.
105
105
  short + ext
@@ -129,7 +129,7 @@ module Bootsnap
129
129
  # to name files in a way that assumes otherwise.
130
130
  # (E.g. It's unlikely that someone will know that their code
131
131
  # will _never_ run on MacOS, and therefore think they can get away
132
- # with callling a Ruby file 'x.dylib.rb' and then requiring it as 'x.dylib'.)
132
+ # with calling a Ruby file 'x.dylib.rb' and then requiring it as 'x.dylib'.)
133
133
  #
134
134
  # See <https://ruby-doc.org/core-2.6.4/Kernel.html#method-i-require>.
135
135
  def extension_elidable?(f)
@@ -21,7 +21,7 @@ module Bootsnap
21
21
  attr_reader(:path)
22
22
 
23
23
  def initialize(path)
24
- @path = path.to_s
24
+ @path = path.to_s.freeze
25
25
  end
26
26
 
27
27
  # True if the path exists, but represents a non-directory object
@@ -60,7 +60,7 @@ module Bootsnap
60
60
  end
61
61
 
62
62
  def expanded_path
63
- File.expand_path(path)
63
+ File.expand_path(path).freeze
64
64
  end
65
65
 
66
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
@@ -64,7 +64,7 @@ module Bootsnap
64
64
  def load_data
65
65
  @data = begin
66
66
  MessagePack.load(File.binread(@store_path))
67
- # handle malformed data due to upgrade incompatability
67
+ # handle malformed data due to upgrade incompatibility
68
68
  rescue Errno::ENOENT, MessagePack::MalformedFormatError, MessagePack::UnknownExtTypeError, EOFError
69
69
  {}
70
70
  rescue ArgumentError => e
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Bootsnap
3
- VERSION = "1.4.6"
3
+ VERSION = "1.4.7"
4
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.6
4
+ version: 1.4.7
5
5
  platform: java
6
6
  authors:
7
7
  - Burke Libbey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-24 00:00:00.000000000 Z
11
+ date: 2020-07-22 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: