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.
- 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
|
|