bootsnap 1.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.github/CODEOWNERS +2 -0
  3. data/.github/probots.yml +2 -0
  4. data/.gitignore +17 -0
  5. data/.rubocop.yml +20 -0
  6. data/.travis.yml +21 -0
  7. data/CHANGELOG.md +122 -0
  8. data/CODE_OF_CONDUCT.md +74 -0
  9. data/CONTRIBUTING.md +21 -0
  10. data/Gemfile +9 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.jp.md +231 -0
  13. data/README.md +304 -0
  14. data/Rakefile +13 -0
  15. data/bin/ci +10 -0
  16. data/bin/console +15 -0
  17. data/bin/setup +8 -0
  18. data/bin/test-minimal-support +7 -0
  19. data/bin/testunit +8 -0
  20. data/bootsnap.gemspec +46 -0
  21. data/dev.yml +10 -0
  22. data/ext/bootsnap/bootsnap.c +829 -0
  23. data/ext/bootsnap/bootsnap.h +6 -0
  24. data/ext/bootsnap/extconf.rb +19 -0
  25. data/lib/bootsnap.rb +48 -0
  26. data/lib/bootsnap/bundler.rb +15 -0
  27. data/lib/bootsnap/compile_cache.rb +43 -0
  28. data/lib/bootsnap/compile_cache/iseq.rb +73 -0
  29. data/lib/bootsnap/compile_cache/yaml.rb +63 -0
  30. data/lib/bootsnap/explicit_require.rb +50 -0
  31. data/lib/bootsnap/load_path_cache.rb +78 -0
  32. data/lib/bootsnap/load_path_cache/cache.rb +208 -0
  33. data/lib/bootsnap/load_path_cache/change_observer.rb +63 -0
  34. data/lib/bootsnap/load_path_cache/core_ext/active_support.rb +107 -0
  35. data/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb +93 -0
  36. data/lib/bootsnap/load_path_cache/core_ext/loaded_features.rb +18 -0
  37. data/lib/bootsnap/load_path_cache/loaded_features_index.rb +148 -0
  38. data/lib/bootsnap/load_path_cache/path.rb +114 -0
  39. data/lib/bootsnap/load_path_cache/path_scanner.rb +50 -0
  40. data/lib/bootsnap/load_path_cache/realpath_cache.rb +32 -0
  41. data/lib/bootsnap/load_path_cache/store.rb +90 -0
  42. data/lib/bootsnap/setup.rb +39 -0
  43. data/lib/bootsnap/version.rb +4 -0
  44. data/shipit.rubygems.yml +0 -0
  45. metadata +174 -0
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative('../explicit_require')
4
+
5
+ module Bootsnap
6
+ module LoadPathCache
7
+ module PathScanner
8
+ ALL_FILES = "/{,**/*/**/}*"
9
+ REQUIRABLE_EXTENSIONS = [DOT_RB] + DL_EXTENSIONS
10
+ NORMALIZE_NATIVE_EXTENSIONS = !DL_EXTENSIONS.include?(LoadPathCache::DOT_SO)
11
+ ALTERNATIVE_NATIVE_EXTENSIONS_PATTERN = /\.(o|bundle|dylib)\z/
12
+
13
+ BUNDLE_PATH = if Bootsnap.bundler?
14
+ (Bundler.bundle_path.cleanpath.to_s << LoadPathCache::SLASH).freeze
15
+ else
16
+ ''
17
+ end
18
+
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
43
+ end
44
+ end
45
+
46
+ [requirables, dirs]
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bootsnap
4
+ module LoadPathCache
5
+ class RealpathCache
6
+ def initialize
7
+ @cache = Hash.new { |h, k| h[k] = realpath(*k) }
8
+ end
9
+
10
+ def call(*key)
11
+ @cache[key]
12
+ end
13
+
14
+ private
15
+
16
+ def realpath(caller_location, path)
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))
21
+ end
22
+
23
+ def find_file(name)
24
+ ['', *CACHED_EXTENSIONS].each do |ext|
25
+ filename = "#{name}#{ext}"
26
+ return File.realpath(filename) if File.exist?(filename)
27
+ end
28
+ name
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+ require_relative('../explicit_require')
3
+
4
+ Bootsnap::ExplicitRequire.with_gems('msgpack') { require('msgpack') }
5
+ Bootsnap::ExplicitRequire.from_rubylibdir('fileutils')
6
+
7
+ module Bootsnap
8
+ module LoadPathCache
9
+ class Store
10
+ NestedTransactionError = Class.new(StandardError)
11
+ SetOutsideTransactionNotAllowed = Class.new(StandardError)
12
+
13
+ def initialize(store_path)
14
+ @store_path = store_path
15
+ # TODO: Remove conditional once Ruby 2.2 support is dropped.
16
+ @txn_mutex = defined?(::Mutex) ? ::Mutex.new : ::Thread::Mutex.new
17
+ @dirty = false
18
+ load_data
19
+ end
20
+
21
+ def get(key)
22
+ @data[key]
23
+ end
24
+
25
+ def fetch(key)
26
+ raise(SetOutsideTransactionNotAllowed) unless @txn_mutex.owned?
27
+ v = get(key)
28
+ unless v
29
+ @dirty = true
30
+ v = yield
31
+ @data[key] = v
32
+ end
33
+ v
34
+ end
35
+
36
+ def set(key, value)
37
+ raise(SetOutsideTransactionNotAllowed) unless @txn_mutex.owned?
38
+ if value != @data[key]
39
+ @dirty = true
40
+ @data[key] = value
41
+ end
42
+ end
43
+
44
+ def transaction
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
53
+ end
54
+
55
+ private
56
+
57
+ def commit_transaction
58
+ if @dirty
59
+ dump_data
60
+ @dirty = false
61
+ end
62
+ end
63
+
64
+ def load_data
65
+ @data = begin
66
+ MessagePack.load(File.binread(@store_path))
67
+ # handle malformed data due to upgrade incompatability
68
+ rescue Errno::ENOENT, MessagePack::MalformedFormatError, MessagePack::UnknownExtTypeError, EOFError
69
+ {}
70
+ rescue ArgumentError => e
71
+ e.message =~ /negative array size/ ? {} : raise
72
+ end
73
+ end
74
+
75
+ def dump_data
76
+ # Change contents atomically so other processes can't get invalid
77
+ # caches if they read at an inopportune time.
78
+ tmp = "#{@store_path}.#{Process.pid}.#{(rand * 100000).to_i}.tmp"
79
+ FileUtils.mkpath(File.dirname(tmp))
80
+ exclusive_write = File::Constants::CREAT | File::Constants::EXCL | File::Constants::WRONLY
81
+ # `encoding:` looks redundant wrt `binwrite`, but necessary on windows
82
+ # because binary is part of mode.
83
+ File.binwrite(tmp, MessagePack.dump(@data), mode: exclusive_write, encoding: Encoding::BINARY)
84
+ FileUtils.mv(tmp, @store_path)
85
+ rescue Errno::EEXIST
86
+ retry
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+ require_relative('../bootsnap')
3
+
4
+ env = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || ENV['ENV']
5
+ development_mode = ['', nil, 'development'].include?(env)
6
+
7
+ cache_dir = ENV['BOOTSNAP_CACHE_DIR']
8
+ unless cache_dir
9
+ config_dir_frame = caller.detect do |line|
10
+ line.include?('/config/')
11
+ end
12
+
13
+ unless config_dir_frame
14
+ $stderr.puts("[bootsnap/setup] couldn't infer cache directory! Either:")
15
+ $stderr.puts("[bootsnap/setup] 1. require bootsnap/setup from your application's config directory; or")
16
+ $stderr.puts("[bootsnap/setup] 2. Define the environment variable BOOTSNAP_CACHE_DIR")
17
+
18
+ raise("couldn't infer bootsnap cache directory")
19
+ end
20
+
21
+ path = config_dir_frame.split(/:\d+:/).first
22
+ path = File.dirname(path) until File.basename(path) == 'config'
23
+ app_root = File.dirname(path)
24
+
25
+ cache_dir = File.join(app_root, 'tmp', 'cache')
26
+ end
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
+
31
+ Bootsnap.setup(
32
+ cache_dir: cache_dir,
33
+ development_mode: development_mode,
34
+ load_path_cache: true,
35
+ autoload_paths_cache: true, # assume rails. open to PRs to impl. detection
36
+ disable_trace: false,
37
+ compile_cache_iseq: iseq_cache_enabled,
38
+ compile_cache_yaml: true,
39
+ )
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+ module Bootsnap
3
+ VERSION = "1.4.6"
4
+ end
File without changes
metadata ADDED
@@ -0,0 +1,174 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bootsnap
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.4.6
5
+ platform: ruby
6
+ authors:
7
+ - Burke Libbey
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-02-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake-compiler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mocha
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.2'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.2'
83
+ - !ruby/object:Gem::Dependency
84
+ name: msgpack
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.0'
97
+ description: Boot large ruby/rails apps faster
98
+ email:
99
+ - burke.libbey@shopify.com
100
+ executables: []
101
+ extensions:
102
+ - ext/bootsnap/extconf.rb
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".github/CODEOWNERS"
106
+ - ".github/probots.yml"
107
+ - ".gitignore"
108
+ - ".rubocop.yml"
109
+ - ".travis.yml"
110
+ - CHANGELOG.md
111
+ - CODE_OF_CONDUCT.md
112
+ - CONTRIBUTING.md
113
+ - Gemfile
114
+ - LICENSE.txt
115
+ - README.jp.md
116
+ - README.md
117
+ - Rakefile
118
+ - bin/ci
119
+ - bin/console
120
+ - bin/setup
121
+ - bin/test-minimal-support
122
+ - bin/testunit
123
+ - bootsnap.gemspec
124
+ - dev.yml
125
+ - ext/bootsnap/bootsnap.c
126
+ - ext/bootsnap/bootsnap.h
127
+ - ext/bootsnap/extconf.rb
128
+ - lib/bootsnap.rb
129
+ - lib/bootsnap/bundler.rb
130
+ - lib/bootsnap/compile_cache.rb
131
+ - lib/bootsnap/compile_cache/iseq.rb
132
+ - lib/bootsnap/compile_cache/yaml.rb
133
+ - lib/bootsnap/explicit_require.rb
134
+ - lib/bootsnap/load_path_cache.rb
135
+ - lib/bootsnap/load_path_cache/cache.rb
136
+ - lib/bootsnap/load_path_cache/change_observer.rb
137
+ - lib/bootsnap/load_path_cache/core_ext/active_support.rb
138
+ - lib/bootsnap/load_path_cache/core_ext/kernel_require.rb
139
+ - lib/bootsnap/load_path_cache/core_ext/loaded_features.rb
140
+ - lib/bootsnap/load_path_cache/loaded_features_index.rb
141
+ - lib/bootsnap/load_path_cache/path.rb
142
+ - lib/bootsnap/load_path_cache/path_scanner.rb
143
+ - lib/bootsnap/load_path_cache/realpath_cache.rb
144
+ - lib/bootsnap/load_path_cache/store.rb
145
+ - lib/bootsnap/setup.rb
146
+ - lib/bootsnap/version.rb
147
+ - shipit.rubygems.yml
148
+ homepage: https://github.com/Shopify/bootsnap
149
+ licenses:
150
+ - MIT
151
+ metadata:
152
+ bug_tracker_uri: https://github.com/Shopify/bootsnap/issues
153
+ changelog_uri: https://github.com/Shopify/bootsnap/blob/master/CHANGELOG.md
154
+ source_code_uri: https://github.com/Shopify/bootsnap
155
+ post_install_message:
156
+ rdoc_options: []
157
+ require_paths:
158
+ - lib
159
+ required_ruby_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - ">="
162
+ - !ruby/object:Gem::Version
163
+ version: 2.3.0
164
+ required_rubygems_version: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ">="
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ requirements: []
170
+ rubygems_version: 3.0.6
171
+ signing_key:
172
+ specification_version: 4
173
+ summary: Boot large ruby/rails apps faster
174
+ test_files: []