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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -0
- data/README.md +1 -1
- data/ext/bootsnap/bootsnap.c +76 -42
- data/ext/bootsnap/extconf.rb +1 -0
- data/lib/bootsnap.rb +2 -0
- data/lib/bootsnap/bundler.rb +1 -0
- data/lib/bootsnap/compile_cache.rb +2 -1
- data/lib/bootsnap/compile_cache/iseq.rb +1 -0
- data/lib/bootsnap/compile_cache/yaml.rb +1 -0
- data/lib/bootsnap/explicit_require.rb +1 -0
- data/lib/bootsnap/load_path_cache/cache.rb +8 -8
- data/lib/bootsnap/load_path_cache/change_observer.rb +2 -1
- data/lib/bootsnap/load_path_cache/core_ext/active_support.rb +1 -0
- data/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb +18 -5
- data/lib/bootsnap/load_path_cache/core_ext/loaded_features.rb +1 -0
- data/lib/bootsnap/load_path_cache/loaded_features_index.rb +33 -10
- data/lib/bootsnap/load_path_cache/path.rb +3 -2
- data/lib/bootsnap/load_path_cache/path_scanner.rb +39 -26
- data/lib/bootsnap/load_path_cache/realpath_cache.rb +5 -5
- data/lib/bootsnap/load_path_cache/store.rb +18 -14
- data/lib/bootsnap/setup.rb +5 -1
- data/lib/bootsnap/version.rb +2 -1
- metadata +7 -25
- data/.github/CODEOWNERS +0 -2
- data/.github/probots.yml +0 -2
- data/.gitignore +0 -17
- data/.rubocop.yml +0 -20
- data/.travis.yml +0 -21
- data/CODE_OF_CONDUCT.md +0 -74
- data/CONTRIBUTING.md +0 -21
- data/Gemfile +0 -8
- data/README.jp.md +0 -231
- data/Rakefile +0 -12
- data/bin/ci +0 -10
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/bin/test-minimal-support +0 -7
- data/bin/testunit +0 -8
- data/bootsnap.gemspec +0 -45
- data/dev.yml +0 -10
- data/shipit.rubygems.yml +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f22bac3ef9ae0e60d14aa58792ac2d824b9e6af
|
4
|
+
data.tar.gz: 689f27baac58dab8c6fc3dfc9225225ada89545f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 226139367737c0832c66b3a36ca27cf400ab3add25130cdcfe9f572de35c3d17d03861e2715673d4cb0cb08bef9ccfa06da33a638a64f2e203c8cf281f3da209
|
7
|
+
data.tar.gz: c70b64e4273a4321e127ee4a7559412205821d0c97931d37c20fd0231b81312064ef9b238cc4749d15e41724bbf3cee6694b3e79b43adaf3790f153474a828f7
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,35 @@
|
|
1
|
+
# 1.4.8
|
2
|
+
|
3
|
+
* [Prevent FallbackScan from polluting exception cause](https://github.com/Shopify/bootsnap/pull/314)
|
4
|
+
|
5
|
+
# 1.4.7
|
6
|
+
|
7
|
+
* Various performance enhancements
|
8
|
+
* Fix race condition in heavy concurrent load scenarios that would cause bootsnap to raise
|
9
|
+
|
10
|
+
# 1.4.6
|
11
|
+
|
12
|
+
* Fix bug that was erroneously considering that files containing `.` in the names were being
|
13
|
+
required if a different file with the same name was already being required
|
14
|
+
|
15
|
+
Example:
|
16
|
+
|
17
|
+
require 'foo'
|
18
|
+
require 'foo.en'
|
19
|
+
|
20
|
+
Before bootsnap was considering `foo.en` to be the same file as `foo`
|
21
|
+
|
22
|
+
* Use glibc as part of the ruby_platform cache key
|
23
|
+
|
24
|
+
# 1.4.5
|
25
|
+
|
26
|
+
* MRI 2.7 support
|
27
|
+
* Fixed concurrency bugs
|
28
|
+
|
29
|
+
# 1.4.4
|
30
|
+
|
31
|
+
* Disable ISeq cache in `bootsnap/setup` by default in Ruby 2.5
|
32
|
+
|
1
33
|
# 1.4.3
|
2
34
|
|
3
35
|
* Fix some cache permissions and umask issues after switch to mkstemp
|
data/README.md
CHANGED
@@ -214,7 +214,7 @@ Bootsnap writes a cache file containing a 64 byte header followed by the cache c
|
|
214
214
|
is a cache key including several fields:
|
215
215
|
|
216
216
|
* `version`, hardcoded in bootsnap. Essentially a schema version;
|
217
|
-
* `
|
217
|
+
* `ruby_platform`, A hash of `RUBY_PLATFORM` (e.g. x86_64-linux-gnu) variable and glibc version (on Linux) or OS version (`uname -v` on BSD, macOS)
|
218
218
|
* `compile_option`, which changes with `RubyVM::InstructionSequence.compile_option` does;
|
219
219
|
* `ruby_revision`, the version of Ruby this was compiled with;
|
220
220
|
* `size`, the size of the source file;
|
data/ext/bootsnap/bootsnap.c
CHANGED
@@ -21,6 +21,9 @@
|
|
21
21
|
#ifndef _WIN32
|
22
22
|
#include <sys/utsname.h>
|
23
23
|
#endif
|
24
|
+
#ifdef __GLIBC__
|
25
|
+
#include <gnu/libc-version.h>
|
26
|
+
#endif
|
24
27
|
|
25
28
|
/* 1000 is an arbitrary limit; FNV64 plus some slashes brings the cap down to
|
26
29
|
* 981 for the cache dir */
|
@@ -29,6 +32,8 @@
|
|
29
32
|
|
30
33
|
#define KEY_SIZE 64
|
31
34
|
|
35
|
+
#define MAX_CREATE_TEMPFILE_ATTEMPT 3
|
36
|
+
|
32
37
|
/*
|
33
38
|
* An instance of this key is written as the first 64 bytes of each cache file.
|
34
39
|
* The mtime and size members track whether the file contents have changed, and
|
@@ -90,12 +95,13 @@ static VALUE bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handl
|
|
90
95
|
|
91
96
|
/* Helpers */
|
92
97
|
static uint64_t fnv1a_64(const char *str);
|
93
|
-
static void bs_cache_path(const char * cachedir, const char * path, char
|
98
|
+
static void bs_cache_path(const char * cachedir, const char * path, char (* cache_path)[MAX_CACHEPATH_SIZE]);
|
94
99
|
static int bs_read_key(int fd, struct bs_cache_key * key);
|
95
100
|
static int cache_key_equal(struct bs_cache_key * k1, struct bs_cache_key * k2);
|
96
101
|
static VALUE bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler);
|
97
|
-
static int open_current_file(char * path, struct bs_cache_key * key, char ** errno_provenance);
|
98
|
-
static int fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE * output_data, int * exception_tag, char ** errno_provenance);
|
102
|
+
static int open_current_file(char * path, struct bs_cache_key * key, const char ** errno_provenance);
|
103
|
+
static int fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE * output_data, int * exception_tag, const char ** errno_provenance);
|
104
|
+
static uint32_t get_ruby_revision(void);
|
99
105
|
static uint32_t get_ruby_platform(void);
|
100
106
|
|
101
107
|
/*
|
@@ -136,7 +142,7 @@ Init_bootsnap(void)
|
|
136
142
|
rb_mBootsnap_CompileCache_Native = rb_define_module_under(rb_mBootsnap_CompileCache, "Native");
|
137
143
|
rb_eBootsnap_CompileCache_Uncompilable = rb_define_class_under(rb_mBootsnap_CompileCache, "Uncompilable", rb_eStandardError);
|
138
144
|
|
139
|
-
current_ruby_revision =
|
145
|
+
current_ruby_revision = get_ruby_revision();
|
140
146
|
current_ruby_platform = get_ruby_platform();
|
141
147
|
|
142
148
|
uncompilable = rb_intern("__bootsnap_uncompilable__");
|
@@ -196,6 +202,26 @@ fnv1a_64(const char *str)
|
|
196
202
|
return fnv1a_64_iter(h, str);
|
197
203
|
}
|
198
204
|
|
205
|
+
/*
|
206
|
+
* Ruby's revision may be Integer or String. CRuby 2.7 or later uses
|
207
|
+
* Git commit ID as revision. It's String.
|
208
|
+
*/
|
209
|
+
static uint32_t
|
210
|
+
get_ruby_revision(void)
|
211
|
+
{
|
212
|
+
VALUE ruby_revision;
|
213
|
+
|
214
|
+
ruby_revision = rb_const_get(rb_cObject, rb_intern("RUBY_REVISION"));
|
215
|
+
if (RB_TYPE_P(ruby_revision, RUBY_T_FIXNUM)) {
|
216
|
+
return FIX2INT(ruby_revision);
|
217
|
+
} else {
|
218
|
+
uint64_t hash;
|
219
|
+
|
220
|
+
hash = fnv1a_64(StringValueCStr(ruby_revision));
|
221
|
+
return (uint32_t)(hash >> 32);
|
222
|
+
}
|
223
|
+
}
|
224
|
+
|
199
225
|
/*
|
200
226
|
* When ruby's version doesn't change, but it's recompiled on a different OS
|
201
227
|
* (or OS version), we need to invalidate the cache.
|
@@ -215,6 +241,9 @@ get_ruby_platform(void)
|
|
215
241
|
|
216
242
|
#ifdef _WIN32
|
217
243
|
return (uint32_t)(hash >> 32) ^ (uint32_t)GetVersion();
|
244
|
+
#elif defined(__GLIBC__)
|
245
|
+
hash = fnv1a_64_iter(hash, gnu_get_libc_version());
|
246
|
+
return (uint32_t)(hash >> 32);
|
218
247
|
#else
|
219
248
|
struct utsname utsname;
|
220
249
|
|
@@ -235,7 +264,7 @@ get_ruby_platform(void)
|
|
235
264
|
* The path will look something like: <cachedir>/12/34567890abcdef
|
236
265
|
*/
|
237
266
|
static void
|
238
|
-
bs_cache_path(const char * cachedir, const char * path, char
|
267
|
+
bs_cache_path(const char * cachedir, const char * path, char (* cache_path)[MAX_CACHEPATH_SIZE])
|
239
268
|
{
|
240
269
|
uint64_t hash = fnv1a_64(path);
|
241
270
|
|
@@ -287,10 +316,8 @@ bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler)
|
|
287
316
|
char * path = RSTRING_PTR(path_v);
|
288
317
|
char cache_path[MAX_CACHEPATH_SIZE];
|
289
318
|
|
290
|
-
|
291
|
-
|
292
|
-
bs_cache_path(cachedir, path, &tmp);
|
293
|
-
}
|
319
|
+
/* generate cache path to cache_path */
|
320
|
+
bs_cache_path(cachedir, path, &cache_path);
|
294
321
|
|
295
322
|
return bs_fetch(path, path_v, cache_path, handler);
|
296
323
|
}
|
@@ -300,14 +327,14 @@ bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler)
|
|
300
327
|
* was loaded.
|
301
328
|
*/
|
302
329
|
static int
|
303
|
-
open_current_file(char * path, struct bs_cache_key * key, char ** errno_provenance)
|
330
|
+
open_current_file(char * path, struct bs_cache_key * key, const char ** errno_provenance)
|
304
331
|
{
|
305
332
|
struct stat statbuf;
|
306
333
|
int fd;
|
307
334
|
|
308
335
|
fd = open(path, O_RDONLY);
|
309
336
|
if (fd < 0) {
|
310
|
-
*errno_provenance =
|
337
|
+
*errno_provenance = "bs_fetch:open_current_file:open";
|
311
338
|
return fd;
|
312
339
|
}
|
313
340
|
#ifdef _WIN32
|
@@ -315,7 +342,7 @@ open_current_file(char * path, struct bs_cache_key * key, char ** errno_provenan
|
|
315
342
|
#endif
|
316
343
|
|
317
344
|
if (fstat(fd, &statbuf) < 0) {
|
318
|
-
*errno_provenance =
|
345
|
+
*errno_provenance = "bs_fetch:open_current_file:fstat";
|
319
346
|
close(fd);
|
320
347
|
return -1;
|
321
348
|
}
|
@@ -361,13 +388,13 @@ bs_read_key(int fd, struct bs_cache_key * key)
|
|
361
388
|
* - ERROR_WITH_ERRNO (-1, errno is set)
|
362
389
|
*/
|
363
390
|
static int
|
364
|
-
open_cache_file(const char * path, struct bs_cache_key * key, char ** errno_provenance)
|
391
|
+
open_cache_file(const char * path, struct bs_cache_key * key, const char ** errno_provenance)
|
365
392
|
{
|
366
393
|
int fd, res;
|
367
394
|
|
368
395
|
fd = open(path, O_RDONLY);
|
369
396
|
if (fd < 0) {
|
370
|
-
*errno_provenance =
|
397
|
+
*errno_provenance = "bs_fetch:open_cache_file:open";
|
371
398
|
if (errno == ENOENT) return CACHE_MISSING_OR_INVALID;
|
372
399
|
return ERROR_WITH_ERRNO;
|
373
400
|
}
|
@@ -377,7 +404,7 @@ open_cache_file(const char * path, struct bs_cache_key * key, char ** errno_prov
|
|
377
404
|
|
378
405
|
res = bs_read_key(fd, key);
|
379
406
|
if (res < 0) {
|
380
|
-
*errno_provenance =
|
407
|
+
*errno_provenance = "bs_fetch:open_cache_file:read";
|
381
408
|
close(fd);
|
382
409
|
return res;
|
383
410
|
}
|
@@ -401,7 +428,7 @@ open_cache_file(const char * path, struct bs_cache_key * key, char ** errno_prov
|
|
401
428
|
* or exception, will be the final data returnable to the user.
|
402
429
|
*/
|
403
430
|
static int
|
404
|
-
fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE * output_data, int * exception_tag, char ** errno_provenance)
|
431
|
+
fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE * output_data, int * exception_tag, const char ** errno_provenance)
|
405
432
|
{
|
406
433
|
char * data = NULL;
|
407
434
|
ssize_t nread;
|
@@ -410,7 +437,7 @@ fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE * output_data,
|
|
410
437
|
VALUE storage_data;
|
411
438
|
|
412
439
|
if (data_size > 100000000000) {
|
413
|
-
*errno_provenance =
|
440
|
+
*errno_provenance = "bs_fetch:fetch_cached_data:datasize";
|
414
441
|
errno = EINVAL; /* because wtf? */
|
415
442
|
ret = -1;
|
416
443
|
goto done;
|
@@ -418,7 +445,7 @@ fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE * output_data,
|
|
418
445
|
data = ALLOC_N(char, data_size);
|
419
446
|
nread = read(fd, data, data_size);
|
420
447
|
if (nread < 0) {
|
421
|
-
*errno_provenance =
|
448
|
+
*errno_provenance = "bs_fetch:fetch_cached_data:read";
|
422
449
|
ret = -1;
|
423
450
|
goto done;
|
424
451
|
}
|
@@ -470,29 +497,36 @@ mkpath(char * file_path, mode_t mode)
|
|
470
497
|
* path.
|
471
498
|
*/
|
472
499
|
static int
|
473
|
-
atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data, char ** errno_provenance)
|
500
|
+
atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data, const char ** errno_provenance)
|
474
501
|
{
|
475
502
|
char template[MAX_CACHEPATH_SIZE + 20];
|
476
503
|
char * tmp_path;
|
477
|
-
int fd, ret;
|
504
|
+
int fd, ret, attempt;
|
478
505
|
ssize_t nwrite;
|
479
506
|
|
480
|
-
|
481
|
-
|
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");
|
482
510
|
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
}
|
490
|
-
fd = open(tmp_path, O_WRONLY | O_CREAT, 0664);
|
491
|
-
if (fd < 0) {
|
492
|
-
*errno_provenance = (char *)"bs_fetch:atomic_write_cache_file:open";
|
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) {
|
516
|
+
*errno_provenance = "bs_fetch:atomic_write_cache_file:mkpath";
|
493
517
|
return -1;
|
494
518
|
}
|
495
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
|
+
|
496
530
|
#ifdef _WIN32
|
497
531
|
setmode(fd, O_BINARY);
|
498
532
|
#endif
|
@@ -500,11 +534,11 @@ atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data, char
|
|
500
534
|
key->data_size = RSTRING_LEN(data);
|
501
535
|
nwrite = write(fd, key, KEY_SIZE);
|
502
536
|
if (nwrite < 0) {
|
503
|
-
*errno_provenance =
|
537
|
+
*errno_provenance = "bs_fetch:atomic_write_cache_file:write";
|
504
538
|
return -1;
|
505
539
|
}
|
506
540
|
if (nwrite != KEY_SIZE) {
|
507
|
-
*errno_provenance =
|
541
|
+
*errno_provenance = "bs_fetch:atomic_write_cache_file:keysize";
|
508
542
|
errno = EIO; /* Lies but whatever */
|
509
543
|
return -1;
|
510
544
|
}
|
@@ -512,7 +546,7 @@ atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data, char
|
|
512
546
|
nwrite = write(fd, RSTRING_PTR(data), RSTRING_LEN(data));
|
513
547
|
if (nwrite < 0) return -1;
|
514
548
|
if (nwrite != RSTRING_LEN(data)) {
|
515
|
-
*errno_provenance =
|
549
|
+
*errno_provenance = "bs_fetch:atomic_write_cache_file:writelength";
|
516
550
|
errno = EIO; /* Lies but whatever */
|
517
551
|
return -1;
|
518
552
|
}
|
@@ -520,12 +554,12 @@ atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data, char
|
|
520
554
|
close(fd);
|
521
555
|
ret = rename(tmp_path, path);
|
522
556
|
if (ret < 0) {
|
523
|
-
*errno_provenance =
|
557
|
+
*errno_provenance = "bs_fetch:atomic_write_cache_file:rename";
|
524
558
|
return -1;
|
525
559
|
}
|
526
560
|
ret = chmod(path, 0664 & ~current_umask);
|
527
561
|
if (ret < 0) {
|
528
|
-
*errno_provenance =
|
562
|
+
*errno_provenance = "bs_fetch:atomic_write_cache_file:chmod";
|
529
563
|
}
|
530
564
|
return ret;
|
531
565
|
}
|
@@ -534,13 +568,13 @@ atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data, char
|
|
534
568
|
/* Read contents from an fd, whose contents are asserted to be +size+ bytes
|
535
569
|
* long, into a buffer */
|
536
570
|
static ssize_t
|
537
|
-
bs_read_contents(int fd, size_t size, char ** contents, char ** errno_provenance)
|
571
|
+
bs_read_contents(int fd, size_t size, char ** contents, const char ** errno_provenance)
|
538
572
|
{
|
539
573
|
ssize_t nread;
|
540
574
|
*contents = ALLOC_N(char, size);
|
541
575
|
nread = read(fd, *contents, size);
|
542
576
|
if (nread < 0) {
|
543
|
-
*errno_provenance =
|
577
|
+
*errno_provenance = "bs_fetch:bs_read_contents:read";
|
544
578
|
}
|
545
579
|
return nread;
|
546
580
|
}
|
@@ -596,7 +630,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler)
|
|
596
630
|
char * contents = NULL;
|
597
631
|
int cache_fd = -1, current_fd = -1;
|
598
632
|
int res, valid_cache = 0, exception_tag = 0;
|
599
|
-
char * errno_provenance = NULL;
|
633
|
+
const char * errno_provenance = NULL;
|
600
634
|
|
601
635
|
VALUE input_data; /* data read from source file, e.g. YAML or ruby source */
|
602
636
|
VALUE storage_data; /* compiled data, e.g. msgpack / binary iseq */
|
@@ -664,7 +698,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler)
|
|
664
698
|
* using input_to_output */
|
665
699
|
if (NIL_P(output_data)) {
|
666
700
|
if (unlink(cache_path) < 0) {
|
667
|
-
errno_provenance =
|
701
|
+
errno_provenance = "bs_fetch:unlink";
|
668
702
|
goto fail_errno;
|
669
703
|
}
|
670
704
|
bs_input_to_output(handler, input_data, &output_data, &exception_tag);
|
@@ -775,7 +809,7 @@ try_input_to_storage(VALUE arg)
|
|
775
809
|
}
|
776
810
|
|
777
811
|
static VALUE
|
778
|
-
rescue_input_to_storage(VALUE arg)
|
812
|
+
rescue_input_to_storage(VALUE arg, VALUE e)
|
779
813
|
{
|
780
814
|
return uncompilable;
|
781
815
|
}
|
data/ext/bootsnap/extconf.rb
CHANGED
data/lib/bootsnap.rb
CHANGED
data/lib/bootsnap/bundler.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Bootsnap
|
2
3
|
module CompileCache
|
3
4
|
Error = Class.new(StandardError)
|
@@ -28,7 +29,7 @@ module Bootsnap
|
|
28
29
|
raise(
|
29
30
|
PermissionError,
|
30
31
|
"bootsnap doesn't have permission to write cache entries in '#{cpath}' " \
|
31
|
-
"(or, less likely, doesn't have
|
32
|
+
"(or, less likely, doesn't have permission to read '#{path}')",
|
32
33
|
)
|
33
34
|
end
|
34
35
|
|
@@ -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
|
@@ -67,7 +67,7 @@ module Bootsnap
|
|
67
67
|
# native dynamic extension, e.g. .bundle or .so), we know it was a
|
68
68
|
# failure and there's nothing more we can do to find the file.
|
69
69
|
# no extension, .rb, (.bundle or .so)
|
70
|
-
when '', *CACHED_EXTENSIONS
|
70
|
+
when '', *CACHED_EXTENSIONS
|
71
71
|
nil
|
72
72
|
# Ruby allows specifying native extensions as '.so' even when DLEXT
|
73
73
|
# is '.bundle'. This is where we handle that case.
|
@@ -144,7 +144,7 @@ module Bootsnap
|
|
144
144
|
expanded_path = p.expanded_path
|
145
145
|
entries, dirs = p.entries_and_dirs(@store)
|
146
146
|
# push -> low precedence -> set only if unset
|
147
|
-
dirs.each { |dir| @dirs[dir]
|
147
|
+
dirs.each { |dir| @dirs[dir] ||= path }
|
148
148
|
entries.each { |rel| @index[rel] ||= expanded_path }
|
149
149
|
end
|
150
150
|
end
|
@@ -178,25 +178,25 @@ module Bootsnap
|
|
178
178
|
|
179
179
|
if DLEXT2
|
180
180
|
def search_index(f)
|
181
|
-
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
|
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
|
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
|
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
|
199
|
+
"#{p}/#{f}"
|
200
200
|
end
|
201
201
|
end
|
202
202
|
|