bootsnap 1.4.7 → 1.5.1
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 +17 -0
- data/README.md +14 -1
- data/exe/bootsnap +5 -0
- data/ext/bootsnap/bootsnap.c +42 -28
- data/lib/bootsnap/cli.rb +151 -0
- data/lib/bootsnap/compile_cache.rb +2 -2
- data/lib/bootsnap/compile_cache/iseq.rb +14 -8
- data/lib/bootsnap/compile_cache/yaml.rb +66 -38
- data/lib/bootsnap/load_path_cache.rb +1 -1
- data/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb +15 -3
- data/lib/bootsnap/version.rb +1 -1
- metadata +9 -23
- data/.github/CODEOWNERS +0 -2
- data/.github/probots.yml +0 -2
- data/.gitignore +0 -17
- data/.rubocop.yml +0 -20
- data/.travis.yml +0 -25
- data/CODE_OF_CONDUCT.md +0 -74
- data/CONTRIBUTING.md +0 -21
- data/Gemfile +0 -9
- data/README.jp.md +0 -231
- data/Rakefile +0 -17
- data/bin/ci +0 -9
- data/bin/console +0 -15
- data/bin/setup +0 -8
- data/bin/test-minimal-support +0 -7
- data/bin/testunit +0 -8
- data/bootsnap.gemspec +0 -46
- data/dev.yml +0 -10
- data/shipit.rubygems.yml +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a15b298603bbdda820fa4aa3d37e32c72f181aa49aac240a02f076de2dd17eb
|
4
|
+
data.tar.gz: bbce00645395d42d30cb3c89b35dcb910003e3f9c3b65afd3a94b7e9019b868a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 982d29eb952ba2c053fd78d244493fc2c75d148f11bed24c67e657c0b59d1d6cb4cfc964583087dfababe0b3f977aa9d183c67c69949a31b1dca65c5d51886a4
|
7
|
+
data.tar.gz: 9e862ebb9a2ddb6cebdfec4835e78c9fcf14dd1451af73a6f04bf38edb362111f27cb70a04e381cb9550cdbdf4cf83d838aaf514126a41e1c9f1c1a12ab96417
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
# 1.5.1
|
2
|
+
|
3
|
+
* Workaround a Ruby bug in InstructionSequence.compile_file. (#332)
|
4
|
+
|
5
|
+
# 1.5.0
|
6
|
+
|
7
|
+
* Add a command line to statically precompile the ISeq cache. (#326)
|
8
|
+
|
9
|
+
# 1.4.9
|
10
|
+
|
11
|
+
* [Windows support](https://github.com/Shopify/bootsnap/pull/319)
|
12
|
+
* [Fix potential crash](https://github.com/Shopify/bootsnap/pull/322)
|
13
|
+
|
14
|
+
# 1.4.8
|
15
|
+
|
16
|
+
* [Prevent FallbackScan from polluting exception cause](https://github.com/Shopify/bootsnap/pull/314)
|
17
|
+
|
1
18
|
# 1.4.7
|
2
19
|
|
3
20
|
* Various performance enhancements
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Bootsnap [](https://github.com/Shopify/bootsnap/actions)
|
2
2
|
|
3
3
|
Bootsnap is a library that plugs into Ruby, with optional support for `ActiveSupport` and `YAML`,
|
4
4
|
to optimize and cache expensive computations. See [How Does This Work](#how-does-this-work).
|
@@ -294,6 +294,19 @@ open /c/nope.bundle -> -1
|
|
294
294
|
# (nothing!)
|
295
295
|
```
|
296
296
|
|
297
|
+
## Precompilation
|
298
|
+
|
299
|
+
In development environments the bootsnap compilation cache is generated on the fly when source files are loaded.
|
300
|
+
But in production environments, such as docker images, you might need to precompile the cache.
|
301
|
+
|
302
|
+
To do so you can use the `bootsnap precompile` command.
|
303
|
+
|
304
|
+
Example:
|
305
|
+
|
306
|
+
```bash
|
307
|
+
$ bundle exec bootsnap precompile --gemfile app/ lib/
|
308
|
+
```
|
309
|
+
|
297
310
|
## When not to use Bootsnap
|
298
311
|
|
299
312
|
*Alternative engines*: Bootsnap is pretty reliant on MRI features, and parts are disabled entirely on alternative ruby
|
data/exe/bootsnap
ADDED
data/ext/bootsnap/bootsnap.c
CHANGED
@@ -91,16 +91,16 @@ static ID uncompilable;
|
|
91
91
|
|
92
92
|
/* Functions exposed as module functions on Bootsnap::CompileCache::Native */
|
93
93
|
static VALUE bs_compile_option_crc32_set(VALUE self, VALUE crc32_v);
|
94
|
-
static VALUE bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler);
|
94
|
+
static VALUE bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler, VALUE args);
|
95
95
|
|
96
96
|
/* Helpers */
|
97
97
|
static uint64_t fnv1a_64(const char *str);
|
98
|
-
static void bs_cache_path(const char * cachedir, const char * path, char (* cache_path)[MAX_CACHEPATH_SIZE]);
|
98
|
+
static void bs_cache_path(const char * cachedir, const char * path, const char * extra, char (* cache_path)[MAX_CACHEPATH_SIZE]);
|
99
99
|
static int bs_read_key(int fd, struct bs_cache_key * key);
|
100
100
|
static int cache_key_equal(struct bs_cache_key * k1, struct bs_cache_key * k2);
|
101
|
-
static VALUE bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler);
|
101
|
+
static VALUE bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args);
|
102
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);
|
103
|
+
static int fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE args, VALUE * output_data, int * exception_tag, const char ** errno_provenance);
|
104
104
|
static uint32_t get_ruby_revision(void);
|
105
105
|
static uint32_t get_ruby_platform(void);
|
106
106
|
|
@@ -108,12 +108,12 @@ static uint32_t get_ruby_platform(void);
|
|
108
108
|
* Helper functions to call ruby methods on handler object without crashing on
|
109
109
|
* exception.
|
110
110
|
*/
|
111
|
-
static int bs_storage_to_output(VALUE handler, VALUE storage_data, VALUE * output_data);
|
111
|
+
static int bs_storage_to_output(VALUE handler, VALUE args, VALUE storage_data, VALUE * output_data);
|
112
112
|
static VALUE prot_storage_to_output(VALUE arg);
|
113
113
|
static VALUE prot_input_to_output(VALUE arg);
|
114
|
-
static void bs_input_to_output(VALUE handler, VALUE input_data, VALUE * output_data, int * exception_tag);
|
114
|
+
static void bs_input_to_output(VALUE handler, VALUE args, VALUE input_data, VALUE * output_data, int * exception_tag);
|
115
115
|
static VALUE prot_input_to_storage(VALUE arg);
|
116
|
-
static int bs_input_to_storage(VALUE handler, VALUE input_data, VALUE pathval, VALUE * storage_data);
|
116
|
+
static int bs_input_to_storage(VALUE handler, VALUE args, VALUE input_data, VALUE pathval, VALUE * storage_data);
|
117
117
|
struct s2o_data;
|
118
118
|
struct i2o_data;
|
119
119
|
struct i2s_data;
|
@@ -148,7 +148,7 @@ Init_bootsnap(void)
|
|
148
148
|
uncompilable = rb_intern("__bootsnap_uncompilable__");
|
149
149
|
|
150
150
|
rb_define_module_function(rb_mBootsnap_CompileCache_Native, "coverage_running?", bs_rb_coverage_running, 0);
|
151
|
-
rb_define_module_function(rb_mBootsnap_CompileCache_Native, "fetch", bs_rb_fetch,
|
151
|
+
rb_define_module_function(rb_mBootsnap_CompileCache_Native, "fetch", bs_rb_fetch, 4);
|
152
152
|
rb_define_module_function(rb_mBootsnap_CompileCache_Native, "compile_option_crc32=", bs_compile_option_crc32_set, 1);
|
153
153
|
|
154
154
|
current_umask = umask(0777);
|
@@ -264,9 +264,12 @@ get_ruby_platform(void)
|
|
264
264
|
* The path will look something like: <cachedir>/12/34567890abcdef
|
265
265
|
*/
|
266
266
|
static void
|
267
|
-
bs_cache_path(const char * cachedir, const char * path, char (* cache_path)[MAX_CACHEPATH_SIZE])
|
267
|
+
bs_cache_path(const char * cachedir, const char * path, const char * extra, char (* cache_path)[MAX_CACHEPATH_SIZE])
|
268
268
|
{
|
269
269
|
uint64_t hash = fnv1a_64(path);
|
270
|
+
if (extra) {
|
271
|
+
hash ^= fnv1a_64(extra);
|
272
|
+
}
|
270
273
|
|
271
274
|
uint8_t first_byte = (hash >> (64 - 8));
|
272
275
|
uint64_t remainder = hash & 0x00ffffffffffffff;
|
@@ -301,7 +304,7 @@ cache_key_equal(struct bs_cache_key * k1, struct bs_cache_key * k2)
|
|
301
304
|
* conversions on the ruby VALUE arguments before passing them along.
|
302
305
|
*/
|
303
306
|
static VALUE
|
304
|
-
bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler)
|
307
|
+
bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler, VALUE args)
|
305
308
|
{
|
306
309
|
FilePathValue(path_v);
|
307
310
|
|
@@ -315,11 +318,16 @@ bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler)
|
|
315
318
|
char * cachedir = RSTRING_PTR(cachedir_v);
|
316
319
|
char * path = RSTRING_PTR(path_v);
|
317
320
|
char cache_path[MAX_CACHEPATH_SIZE];
|
321
|
+
char * extra = NULL;
|
322
|
+
if (!NIL_P(args)) {
|
323
|
+
VALUE args_serial = rb_marshal_dump(args, Qnil);
|
324
|
+
extra = RSTRING_PTR(args_serial);
|
325
|
+
}
|
318
326
|
|
319
327
|
/* generate cache path to cache_path */
|
320
|
-
bs_cache_path(cachedir, path, &cache_path);
|
328
|
+
bs_cache_path(cachedir, path, extra, &cache_path);
|
321
329
|
|
322
|
-
return bs_fetch(path, path_v, cache_path, handler);
|
330
|
+
return bs_fetch(path, path_v, cache_path, handler, args);
|
323
331
|
}
|
324
332
|
|
325
333
|
/*
|
@@ -428,7 +436,7 @@ open_cache_file(const char * path, struct bs_cache_key * key, const char ** errn
|
|
428
436
|
* or exception, will be the final data returnable to the user.
|
429
437
|
*/
|
430
438
|
static int
|
431
|
-
fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE * output_data, int * exception_tag, const char ** errno_provenance)
|
439
|
+
fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE args, VALUE * output_data, int * exception_tag, const char ** errno_provenance)
|
432
440
|
{
|
433
441
|
char * data = NULL;
|
434
442
|
ssize_t nread;
|
@@ -454,9 +462,9 @@ fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE * output_data,
|
|
454
462
|
goto done;
|
455
463
|
}
|
456
464
|
|
457
|
-
storage_data =
|
465
|
+
storage_data = rb_str_new(data, data_size);
|
458
466
|
|
459
|
-
*exception_tag = bs_storage_to_output(handler, storage_data, output_data);
|
467
|
+
*exception_tag = bs_storage_to_output(handler, args, storage_data, output_data);
|
460
468
|
ret = 0;
|
461
469
|
done:
|
462
470
|
if (data != NULL) xfree(data);
|
@@ -624,7 +632,7 @@ bs_read_contents(int fd, size_t size, char ** contents, const char ** errno_prov
|
|
624
632
|
* - Return storage_to_output(storage_data)
|
625
633
|
*/
|
626
634
|
static VALUE
|
627
|
-
bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler)
|
635
|
+
bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args)
|
628
636
|
{
|
629
637
|
struct bs_cache_key cached_key, current_key;
|
630
638
|
char * contents = NULL;
|
@@ -657,7 +665,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler)
|
|
657
665
|
if (valid_cache) {
|
658
666
|
/* Fetch the cache data and return it if we're able to load it successfully */
|
659
667
|
res = fetch_cached_data(
|
660
|
-
cache_fd, (ssize_t)cached_key.data_size, handler,
|
668
|
+
cache_fd, (ssize_t)cached_key.data_size, handler, args,
|
661
669
|
&output_data, &exception_tag, &errno_provenance
|
662
670
|
);
|
663
671
|
if (exception_tag != 0) goto raise;
|
@@ -671,15 +679,15 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler)
|
|
671
679
|
|
672
680
|
/* Read the contents of the source file into a buffer */
|
673
681
|
if (bs_read_contents(current_fd, current_key.size, &contents, &errno_provenance) < 0) goto fail_errno;
|
674
|
-
input_data =
|
682
|
+
input_data = rb_str_new(contents, current_key.size);
|
675
683
|
|
676
684
|
/* Try to compile the input_data using input_to_storage(input_data) */
|
677
|
-
exception_tag = bs_input_to_storage(handler, input_data, path_v, &storage_data);
|
685
|
+
exception_tag = bs_input_to_storage(handler, args, input_data, path_v, &storage_data);
|
678
686
|
if (exception_tag != 0) goto raise;
|
679
687
|
/* If input_to_storage raised Bootsnap::CompileCache::Uncompilable, don't try
|
680
688
|
* to cache anything; just return input_to_output(input_data) */
|
681
689
|
if (storage_data == uncompilable) {
|
682
|
-
bs_input_to_output(handler, input_data, &output_data, &exception_tag);
|
690
|
+
bs_input_to_output(handler, args, input_data, &output_data, &exception_tag);
|
683
691
|
if (exception_tag != 0) goto raise;
|
684
692
|
goto succeed;
|
685
693
|
}
|
@@ -691,7 +699,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler)
|
|
691
699
|
if (res < 0) goto fail_errno;
|
692
700
|
|
693
701
|
/* Having written the cache, now convert storage_data to output_data */
|
694
|
-
exception_tag = bs_storage_to_output(handler, storage_data, &output_data);
|
702
|
+
exception_tag = bs_storage_to_output(handler, args, storage_data, &output_data);
|
695
703
|
if (exception_tag != 0) goto raise;
|
696
704
|
|
697
705
|
/* If output_data is nil, delete the cache entry and generate the output
|
@@ -701,7 +709,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler)
|
|
701
709
|
errno_provenance = "bs_fetch:unlink";
|
702
710
|
goto fail_errno;
|
703
711
|
}
|
704
|
-
bs_input_to_output(handler, input_data, &output_data, &exception_tag);
|
712
|
+
bs_input_to_output(handler, args, input_data, &output_data, &exception_tag);
|
705
713
|
if (exception_tag != 0) goto raise;
|
706
714
|
}
|
707
715
|
|
@@ -751,16 +759,19 @@ invalid_type_storage_data:
|
|
751
759
|
|
752
760
|
struct s2o_data {
|
753
761
|
VALUE handler;
|
762
|
+
VALUE args;
|
754
763
|
VALUE storage_data;
|
755
764
|
};
|
756
765
|
|
757
766
|
struct i2o_data {
|
758
767
|
VALUE handler;
|
768
|
+
VALUE args;
|
759
769
|
VALUE input_data;
|
760
770
|
};
|
761
771
|
|
762
772
|
struct i2s_data {
|
763
773
|
VALUE handler;
|
774
|
+
VALUE args;
|
764
775
|
VALUE input_data;
|
765
776
|
VALUE pathval;
|
766
777
|
};
|
@@ -769,15 +780,16 @@ static VALUE
|
|
769
780
|
prot_storage_to_output(VALUE arg)
|
770
781
|
{
|
771
782
|
struct s2o_data * data = (struct s2o_data *)arg;
|
772
|
-
return rb_funcall(data->handler, rb_intern("storage_to_output"),
|
783
|
+
return rb_funcall(data->handler, rb_intern("storage_to_output"), 2, data->storage_data, data->args);
|
773
784
|
}
|
774
785
|
|
775
786
|
static int
|
776
|
-
bs_storage_to_output(VALUE handler, VALUE storage_data, VALUE * output_data)
|
787
|
+
bs_storage_to_output(VALUE handler, VALUE args, VALUE storage_data, VALUE * output_data)
|
777
788
|
{
|
778
789
|
int state;
|
779
790
|
struct s2o_data s2o_data = {
|
780
791
|
.handler = handler,
|
792
|
+
.args = args,
|
781
793
|
.storage_data = storage_data,
|
782
794
|
};
|
783
795
|
*output_data = rb_protect(prot_storage_to_output, (VALUE)&s2o_data, &state);
|
@@ -785,10 +797,11 @@ bs_storage_to_output(VALUE handler, VALUE storage_data, VALUE * output_data)
|
|
785
797
|
}
|
786
798
|
|
787
799
|
static void
|
788
|
-
bs_input_to_output(VALUE handler, VALUE input_data, VALUE * output_data, int * exception_tag)
|
800
|
+
bs_input_to_output(VALUE handler, VALUE args, VALUE input_data, VALUE * output_data, int * exception_tag)
|
789
801
|
{
|
790
802
|
struct i2o_data i2o_data = {
|
791
803
|
.handler = handler,
|
804
|
+
.args = args,
|
792
805
|
.input_data = input_data,
|
793
806
|
};
|
794
807
|
*output_data = rb_protect(prot_input_to_output, (VALUE)&i2o_data, exception_tag);
|
@@ -798,14 +811,14 @@ static VALUE
|
|
798
811
|
prot_input_to_output(VALUE arg)
|
799
812
|
{
|
800
813
|
struct i2o_data * data = (struct i2o_data *)arg;
|
801
|
-
return rb_funcall(data->handler, rb_intern("input_to_output"),
|
814
|
+
return rb_funcall(data->handler, rb_intern("input_to_output"), 2, data->input_data, data->args);
|
802
815
|
}
|
803
816
|
|
804
817
|
static VALUE
|
805
818
|
try_input_to_storage(VALUE arg)
|
806
819
|
{
|
807
820
|
struct i2s_data * data = (struct i2s_data *)arg;
|
808
|
-
return rb_funcall(data->handler, rb_intern("input_to_storage"),
|
821
|
+
return rb_funcall(data->handler, rb_intern("input_to_storage"), 3, data->input_data, data->pathval, data->args);
|
809
822
|
}
|
810
823
|
|
811
824
|
static VALUE
|
@@ -825,11 +838,12 @@ prot_input_to_storage(VALUE arg)
|
|
825
838
|
}
|
826
839
|
|
827
840
|
static int
|
828
|
-
bs_input_to_storage(VALUE handler, VALUE input_data, VALUE pathval, VALUE * storage_data)
|
841
|
+
bs_input_to_storage(VALUE handler, VALUE args, VALUE input_data, VALUE pathval, VALUE * storage_data)
|
829
842
|
{
|
830
843
|
int state;
|
831
844
|
struct i2s_data i2s_data = {
|
832
845
|
.handler = handler,
|
846
|
+
.args = args,
|
833
847
|
.input_data = input_data,
|
834
848
|
.pathval = pathval,
|
835
849
|
};
|
data/lib/bootsnap/cli.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bootsnap'
|
4
|
+
require 'optparse'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
module Bootsnap
|
8
|
+
class CLI
|
9
|
+
unless Regexp.method_defined?(:match?)
|
10
|
+
module RegexpMatchBackport
|
11
|
+
refine Regexp do
|
12
|
+
def match?(string)
|
13
|
+
!!match(string)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
using RegexpMatchBackport
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :cache_dir, :argv
|
21
|
+
|
22
|
+
attr_accessor :compile_gemfile, :exclude
|
23
|
+
|
24
|
+
def initialize(argv)
|
25
|
+
@argv = argv
|
26
|
+
self.cache_dir = ENV.fetch('BOOTSNAP_CACHE_DIR', 'tmp/cache')
|
27
|
+
self.compile_gemfile = false
|
28
|
+
self.exclude = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def precompile_command(*sources)
|
32
|
+
require 'bootsnap/compile_cache/iseq'
|
33
|
+
|
34
|
+
fix_default_encoding do
|
35
|
+
Bootsnap::CompileCache::ISeq.cache_dir = self.cache_dir
|
36
|
+
|
37
|
+
if compile_gemfile
|
38
|
+
sources += $LOAD_PATH
|
39
|
+
end
|
40
|
+
|
41
|
+
sources.map { |d| File.expand_path(d) }.each do |path|
|
42
|
+
if !exclude || !exclude.match?(path)
|
43
|
+
list_ruby_files(path).each do |ruby_file|
|
44
|
+
if !exclude || !exclude.match?(ruby_file)
|
45
|
+
CompileCache::ISeq.fetch(ruby_file, cache_dir: cache_dir)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
0
|
52
|
+
end
|
53
|
+
|
54
|
+
dir_sort = begin
|
55
|
+
Dir['.', sort: false]
|
56
|
+
true
|
57
|
+
rescue ArgumentError, TypeError
|
58
|
+
false
|
59
|
+
end
|
60
|
+
|
61
|
+
if dir_sort
|
62
|
+
def list_ruby_files(path)
|
63
|
+
if File.directory?(path)
|
64
|
+
Dir[File.join(path, '**/*.rb'), sort: false]
|
65
|
+
elsif File.exist?(path)
|
66
|
+
[path]
|
67
|
+
else
|
68
|
+
[]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
else
|
72
|
+
def list_ruby_files(path)
|
73
|
+
if File.directory?(path)
|
74
|
+
Dir[File.join(path, '**/*.rb')]
|
75
|
+
elsif File.exist?(path)
|
76
|
+
[path]
|
77
|
+
else
|
78
|
+
[]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def run
|
84
|
+
parser.parse!(argv)
|
85
|
+
command = argv.shift
|
86
|
+
method = "#{command}_command"
|
87
|
+
if respond_to?(method)
|
88
|
+
public_send(method, *argv)
|
89
|
+
else
|
90
|
+
invalid_usage!("Unknown command: #{command}")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def fix_default_encoding
|
97
|
+
if Encoding.default_external == Encoding::US_ASCII
|
98
|
+
Encoding.default_external = Encoding::UTF_8
|
99
|
+
begin
|
100
|
+
yield
|
101
|
+
ensure
|
102
|
+
Encoding.default_external = Encoding::US_ASCII
|
103
|
+
end
|
104
|
+
else
|
105
|
+
yield
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def invalid_usage!(message)
|
110
|
+
STDERR.puts message
|
111
|
+
STDERR.puts
|
112
|
+
STDERR.puts parser
|
113
|
+
1
|
114
|
+
end
|
115
|
+
|
116
|
+
def cache_dir=(dir)
|
117
|
+
@cache_dir = File.expand_path(File.join(dir, 'bootsnap-compile-cache'))
|
118
|
+
end
|
119
|
+
|
120
|
+
def parser
|
121
|
+
@parser ||= OptionParser.new do |opts|
|
122
|
+
opts.banner = "Usage: bootsnap COMMAND [ARGS]"
|
123
|
+
opts.separator ""
|
124
|
+
opts.separator "GLOBAL OPTIONS"
|
125
|
+
opts.separator ""
|
126
|
+
|
127
|
+
help = <<~EOS
|
128
|
+
Path to the bootsnap cache directory. Defaults to tmp/cache
|
129
|
+
EOS
|
130
|
+
opts.on('--cache-dir DIR', help.strip) do |dir|
|
131
|
+
self.cache_dir = dir
|
132
|
+
end
|
133
|
+
|
134
|
+
opts.separator ""
|
135
|
+
opts.separator "COMMANDS"
|
136
|
+
opts.separator ""
|
137
|
+
opts.separator " precompile [DIRECTORIES...]: Precompile all .rb files in the passed directories"
|
138
|
+
|
139
|
+
help = <<~EOS
|
140
|
+
Precompile the gems in Gemfile
|
141
|
+
EOS
|
142
|
+
opts.on('--gemfile', help) { self.compile_gemfile = true }
|
143
|
+
|
144
|
+
help = <<~EOS
|
145
|
+
Path pattern to not precompile. e.g. --exclude 'aws-sdk|google-api'
|
146
|
+
EOS
|
147
|
+
opts.on('--exclude PATTERN', help) { |pattern| self.exclude = Regexp.new(pattern) }
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|