bootsnap 1.4.5 → 1.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +74 -0
  3. data/README.md +46 -15
  4. data/exe/bootsnap +5 -0
  5. data/ext/bootsnap/bootsnap.c +255 -87
  6. data/ext/bootsnap/extconf.rb +20 -14
  7. data/lib/bootsnap.rb +89 -15
  8. data/lib/bootsnap/bundler.rb +1 -0
  9. data/lib/bootsnap/cli.rb +246 -0
  10. data/lib/bootsnap/cli/worker_pool.rb +131 -0
  11. data/lib/bootsnap/compile_cache.rb +3 -2
  12. data/lib/bootsnap/compile_cache/iseq.rb +22 -7
  13. data/lib/bootsnap/compile_cache/yaml.rb +110 -40
  14. data/lib/bootsnap/explicit_require.rb +1 -0
  15. data/lib/bootsnap/load_path_cache.rb +3 -16
  16. data/lib/bootsnap/load_path_cache/cache.rb +25 -8
  17. data/lib/bootsnap/load_path_cache/change_observer.rb +2 -1
  18. data/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb +18 -5
  19. data/lib/bootsnap/load_path_cache/core_ext/loaded_features.rb +1 -0
  20. data/lib/bootsnap/load_path_cache/loaded_features_index.rb +34 -11
  21. data/lib/bootsnap/load_path_cache/path.rb +3 -2
  22. data/lib/bootsnap/load_path_cache/path_scanner.rb +50 -26
  23. data/lib/bootsnap/load_path_cache/realpath_cache.rb +5 -5
  24. data/lib/bootsnap/load_path_cache/store.rb +15 -7
  25. data/lib/bootsnap/setup.rb +2 -36
  26. data/lib/bootsnap/version.rb +2 -1
  27. metadata +15 -29
  28. data/.github/CODEOWNERS +0 -2
  29. data/.github/probots.yml +0 -2
  30. data/.gitignore +0 -17
  31. data/.rubocop.yml +0 -20
  32. data/.travis.yml +0 -21
  33. data/CODE_OF_CONDUCT.md +0 -74
  34. data/CONTRIBUTING.md +0 -21
  35. data/Gemfile +0 -8
  36. data/README.jp.md +0 -231
  37. data/Rakefile +0 -12
  38. data/bin/ci +0 -10
  39. data/bin/console +0 -14
  40. data/bin/setup +0 -8
  41. data/bin/test-minimal-support +0 -7
  42. data/bin/testunit +0 -8
  43. data/bootsnap.gemspec +0 -45
  44. data/dev.yml +0 -10
  45. data/lib/bootsnap/load_path_cache/core_ext/active_support.rb +0 -106
  46. data/shipit.rubygems.yml +0 -0
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require_relative('path_scanner')
2
3
 
3
4
  module Bootsnap
@@ -20,7 +21,7 @@ module Bootsnap
20
21
  attr_reader(:path)
21
22
 
22
23
  def initialize(path)
23
- @path = path.to_s
24
+ @path = path.to_s.freeze
24
25
  end
25
26
 
26
27
  # True if the path exists, but represents a non-directory object
@@ -59,7 +60,7 @@ module Bootsnap
59
60
  end
60
61
 
61
62
  def expanded_path
62
- File.expand_path(path)
63
+ File.expand_path(path).freeze
63
64
  end
64
65
 
65
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,59 @@ 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 << os_path(relative_path)
37
+ !contains_bundle_path || !absolute_path.start_with?(BUNDLE_PATH)
38
+ elsif relative_path.end_with?(*REQUIRABLE_EXTENSIONS)
39
+ requirables << os_path(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 ? File.join(relative_dir_path, name) : name
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
60
+
61
+ if RUBY_VERSION >= '3.1'
62
+ def os_path(path)
63
+ path.freeze
64
+ end
65
+ else
66
+ def os_path(path)
67
+ path.force_encoding(Encoding::US_ASCII) if path.ascii_only?
68
+ path.freeze
69
+ end
70
+ end
47
71
  end
48
72
  end
49
73
  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
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require_relative('../explicit_require')
2
3
 
3
4
  Bootsnap::ExplicitRequire.with_gems('msgpack') { require('msgpack') }
@@ -11,8 +12,7 @@ module Bootsnap
11
12
 
12
13
  def initialize(store_path)
13
14
  @store_path = store_path
14
- # TODO: Remove conditional once Ruby 2.2 support is dropped.
15
- @txn_mutex = defined?(::Mutex) ? ::Mutex.new : ::Thread::Mutex.new
15
+ @txn_mutex = Mutex.new
16
16
  @dirty = false
17
17
  load_data
18
18
  end
@@ -62,12 +62,18 @@ module Bootsnap
62
62
 
63
63
  def load_data
64
64
  @data = begin
65
- MessagePack.load(File.binread(@store_path))
66
- # handle malformed data due to upgrade incompatability
65
+ File.open(@store_path, encoding: Encoding::BINARY) do |io|
66
+ MessagePack.load(io)
67
+ end
68
+ # handle malformed data due to upgrade incompatibility
67
69
  rescue Errno::ENOENT, MessagePack::MalformedFormatError, MessagePack::UnknownExtTypeError, EOFError
68
70
  {}
69
- rescue ArgumentError => e
70
- e.message =~ /negative array size/ ? {} : raise
71
+ rescue ArgumentError => error
72
+ if error.message =~ /negative array size/
73
+ {}
74
+ else
75
+ raise
76
+ end
71
77
  end
72
78
  end
73
79
 
@@ -79,7 +85,9 @@ module Bootsnap
79
85
  exclusive_write = File::Constants::CREAT | File::Constants::EXCL | File::Constants::WRONLY
80
86
  # `encoding:` looks redundant wrt `binwrite`, but necessary on windows
81
87
  # because binary is part of mode.
82
- File.binwrite(tmp, MessagePack.dump(@data), mode: exclusive_write, encoding: Encoding::BINARY)
88
+ File.open(tmp, mode: exclusive_write, encoding: Encoding::BINARY) do |io|
89
+ MessagePack.dump(@data, io, freeze: true)
90
+ end
83
91
  FileUtils.mv(tmp, @store_path)
84
92
  rescue Errno::EEXIST
85
93
  retry
@@ -1,38 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require_relative('../bootsnap')
2
3
 
3
- env = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || ENV['ENV']
4
- development_mode = ['', nil, 'development'].include?(env)
5
-
6
- cache_dir = ENV['BOOTSNAP_CACHE_DIR']
7
- unless cache_dir
8
- config_dir_frame = caller.detect do |line|
9
- line.include?('/config/')
10
- end
11
-
12
- unless config_dir_frame
13
- $stderr.puts("[bootsnap/setup] couldn't infer cache directory! Either:")
14
- $stderr.puts("[bootsnap/setup] 1. require bootsnap/setup from your application's config directory; or")
15
- $stderr.puts("[bootsnap/setup] 2. Define the environment variable BOOTSNAP_CACHE_DIR")
16
-
17
- raise("couldn't infer bootsnap cache directory")
18
- end
19
-
20
- path = config_dir_frame.split(/:\d+:/).first
21
- path = File.dirname(path) until File.basename(path) == 'config'
22
- app_root = File.dirname(path)
23
-
24
- cache_dir = File.join(app_root, 'tmp', 'cache')
25
- end
26
-
27
- ruby_version = Gem::Version.new(RUBY_VERSION)
28
- iseq_cache_enabled = ruby_version < Gem::Version.new('2.5.0') || ruby_version >= Gem::Version.new('2.6.0')
29
-
30
- Bootsnap.setup(
31
- cache_dir: cache_dir,
32
- development_mode: development_mode,
33
- load_path_cache: true,
34
- autoload_paths_cache: true, # assume rails. open to PRs to impl. detection
35
- disable_trace: false,
36
- compile_cache_iseq: iseq_cache_enabled,
37
- compile_cache_yaml: true,
38
- )
4
+ Bootsnap.default_setup
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Bootsnap
2
- VERSION = "1.4.5"
3
+ VERSION = "1.7.4"
3
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.5
4
+ version: 1.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Burke Libbey
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2019-08-28 00:00:00.000000000 Z
11
+ date: 2021-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
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
  name: rake-compiler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -97,36 +97,23 @@ dependencies:
97
97
  description: Boot large ruby/rails apps faster
98
98
  email:
99
99
  - burke.libbey@shopify.com
100
- executables: []
100
+ executables:
101
+ - bootsnap
101
102
  extensions:
102
103
  - ext/bootsnap/extconf.rb
103
104
  extra_rdoc_files: []
104
105
  files:
105
- - ".github/CODEOWNERS"
106
- - ".github/probots.yml"
107
- - ".gitignore"
108
- - ".rubocop.yml"
109
- - ".travis.yml"
110
106
  - CHANGELOG.md
111
- - CODE_OF_CONDUCT.md
112
- - CONTRIBUTING.md
113
- - Gemfile
114
107
  - LICENSE.txt
115
- - README.jp.md
116
108
  - 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
109
+ - exe/bootsnap
125
110
  - ext/bootsnap/bootsnap.c
126
111
  - ext/bootsnap/bootsnap.h
127
112
  - ext/bootsnap/extconf.rb
128
113
  - lib/bootsnap.rb
129
114
  - lib/bootsnap/bundler.rb
115
+ - lib/bootsnap/cli.rb
116
+ - lib/bootsnap/cli/worker_pool.rb
130
117
  - lib/bootsnap/compile_cache.rb
131
118
  - lib/bootsnap/compile_cache/iseq.rb
132
119
  - lib/bootsnap/compile_cache/yaml.rb
@@ -134,7 +121,6 @@ files:
134
121
  - lib/bootsnap/load_path_cache.rb
135
122
  - lib/bootsnap/load_path_cache/cache.rb
136
123
  - lib/bootsnap/load_path_cache/change_observer.rb
137
- - lib/bootsnap/load_path_cache/core_ext/active_support.rb
138
124
  - lib/bootsnap/load_path_cache/core_ext/kernel_require.rb
139
125
  - lib/bootsnap/load_path_cache/core_ext/loaded_features.rb
140
126
  - lib/bootsnap/load_path_cache/loaded_features_index.rb
@@ -144,7 +130,6 @@ files:
144
130
  - lib/bootsnap/load_path_cache/store.rb
145
131
  - lib/bootsnap/setup.rb
146
132
  - lib/bootsnap/version.rb
147
- - shipit.rubygems.yml
148
133
  homepage: https://github.com/Shopify/bootsnap
149
134
  licenses:
150
135
  - MIT
@@ -152,6 +137,7 @@ metadata:
152
137
  bug_tracker_uri: https://github.com/Shopify/bootsnap/issues
153
138
  changelog_uri: https://github.com/Shopify/bootsnap/blob/master/CHANGELOG.md
154
139
  source_code_uri: https://github.com/Shopify/bootsnap
140
+ allowed_push_host: https://rubygems.org
155
141
  post_install_message:
156
142
  rdoc_options: []
157
143
  require_paths:
@@ -160,14 +146,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
160
146
  requirements:
161
147
  - - ">="
162
148
  - !ruby/object:Gem::Version
163
- version: 2.0.0
149
+ version: 2.3.0
164
150
  required_rubygems_version: !ruby/object:Gem::Requirement
165
151
  requirements:
166
152
  - - ">="
167
153
  - !ruby/object:Gem::Version
168
154
  version: '0'
169
155
  requirements: []
170
- rubygems_version: 3.0.2
156
+ rubygems_version: 3.0.3
171
157
  signing_key:
172
158
  specification_version: 4
173
159
  summary: Boot large ruby/rails apps faster
data/.github/CODEOWNERS DELETED
@@ -1,2 +0,0 @@
1
- # mvm:maintainer
2
- * @burke
data/.github/probots.yml DELETED
@@ -1,2 +0,0 @@
1
- enabled:
2
- - cla
data/.gitignore DELETED
@@ -1,17 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
- *.bundle
11
- *.so
12
- *.o
13
- *.a
14
- *.gem
15
- *.db
16
- mkmf.log
17
- .rubocop-*
data/.rubocop.yml DELETED
@@ -1,20 +0,0 @@
1
- inherit_from:
2
- - http://shopify.github.io/ruby-style-guide/rubocop.yml
3
-
4
- AllCops:
5
- Exclude:
6
- - 'vendor/**/*'
7
- - 'tmp/**/*'
8
- TargetRubyVersion: '2.2'
9
-
10
- # This doesn't take into account retrying from an exception
11
- Lint/HandleExceptions:
12
- Enabled: false
13
-
14
- # allow String.new to create mutable strings
15
- Style/EmptyLiteral:
16
- Enabled: false
17
-
18
- # allow the use of globals which makes sense in a CLI app like this
19
- Style/GlobalVars:
20
- Enabled: false
data/.travis.yml DELETED
@@ -1,21 +0,0 @@
1
- language: ruby
2
- sudo: false
3
-
4
- os:
5
- - linux
6
- - osx
7
-
8
- rvm:
9
- - ruby-2.4
10
- - ruby-2.5
11
- - ruby-head
12
-
13
- matrix:
14
- allow_failures:
15
- - rvm: ruby-head
16
- include:
17
- - rvm: jruby
18
- os: linux
19
- env: MINIMAL_SUPPORT=1
20
-
21
- script: bin/ci
data/CODE_OF_CONDUCT.md DELETED
@@ -1,74 +0,0 @@
1
- # Contributor Covenant Code of Conduct
2
-
3
- ## Our Pledge
4
-
5
- In the interest of fostering an open and welcoming environment, we as
6
- contributors and maintainers pledge to making participation in our project and
7
- our community a harassment-free experience for everyone, regardless of age, body
8
- size, disability, ethnicity, gender identity and expression, level of experience,
9
- nationality, personal appearance, race, religion, or sexual identity and
10
- orientation.
11
-
12
- ## Our Standards
13
-
14
- Examples of behavior that contributes to creating a positive environment
15
- include:
16
-
17
- * Using welcoming and inclusive language
18
- * Being respectful of differing viewpoints and experiences
19
- * Gracefully accepting constructive criticism
20
- * Focusing on what is best for the community
21
- * Showing empathy towards other community members
22
-
23
- Examples of unacceptable behavior by participants include:
24
-
25
- * The use of sexualized language or imagery and unwelcome sexual attention or
26
- advances
27
- * Trolling, insulting/derogatory comments, and personal or political attacks
28
- * Public or private harassment
29
- * Publishing others' private information, such as a physical or electronic
30
- address, without explicit permission
31
- * Other conduct which could reasonably be considered inappropriate in a
32
- professional setting
33
-
34
- ## Our Responsibilities
35
-
36
- Project maintainers are responsible for clarifying the standards of acceptable
37
- behavior and are expected to take appropriate and fair corrective action in
38
- response to any instances of unacceptable behavior.
39
-
40
- Project maintainers have the right and responsibility to remove, edit, or
41
- reject comments, commits, code, wiki edits, issues, and other contributions
42
- that are not aligned to this Code of Conduct, or to ban temporarily or
43
- permanently any contributor for other behaviors that they deem inappropriate,
44
- threatening, offensive, or harmful.
45
-
46
- ## Scope
47
-
48
- This Code of Conduct applies both within project spaces and in public spaces
49
- when an individual is representing the project or its community. Examples of
50
- representing a project or community include using an official project e-mail
51
- address, posting via an official social media account, or acting as an appointed
52
- representative at an online or offline event. Representation of a project may be
53
- further defined and clarified by project maintainers.
54
-
55
- ## Enforcement
56
-
57
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
- reported by contacting the project team at burke@libbey.me. All
59
- complaints will be reviewed and investigated and will result in a response that
60
- is deemed necessary and appropriate to the circumstances. The project team is
61
- obligated to maintain confidentiality with regard to the reporter of an incident.
62
- Further details of specific enforcement policies may be posted separately.
63
-
64
- Project maintainers who do not follow or enforce the Code of Conduct in good
65
- faith may face temporary or permanent repercussions as determined by other
66
- members of the project's leadership.
67
-
68
- ## Attribution
69
-
70
- This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
- available at [http://contributor-covenant.org/version/1/4][version]
72
-
73
- [homepage]: http://contributor-covenant.org
74
- [version]: http://contributor-covenant.org/version/1/4/