bootsnap 0.2.9 → 0.3.0

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.
@@ -1,8 +1,6 @@
1
1
  #ifndef BOOTSNAP_H
2
2
  #define BOOTSNAP_H 1
3
3
 
4
- #include <stdint.h>
5
- #include <sys/types.h>
6
- #include "ruby.h"
4
+ /* doesn't expose anything */
7
5
 
8
6
  #endif /* BOOTSNAP_H */
@@ -1,6 +1,17 @@
1
1
  require "mkmf"
2
- $CFLAGS << ' -O3 -std=c99'
3
- $CFLAGS << ' -Wall -Wextra -Wpedantic -Werror'
4
- $CFLAGS << ' -Wno-unused-parameter' # VALUE self has to be there but we don't care what it is.
5
- $CFLAGS << ' -Wno-keyword-macro' # hiding return
2
+ $CFLAGS << ' -O3 '
3
+ $CFLAGS << ' -std=c99'
4
+
5
+ # ruby.h has some -Wpedantic fails in some cases
6
+ # (e.g. https://github.com/Shopify/bootsnap/issues/15)
7
+ unless ['0', '', nil].include?(ENV['BOOTSNAP_PEDANTIC'])
8
+ $CFLAGS << ' -Wall'
9
+ $CFLAGS << ' -Werror'
10
+ $CFLAGS << ' -Wextra'
11
+ $CFLAGS << ' -Wpedantic'
12
+
13
+ $CFLAGS << ' -Wno-unused-parameter' # VALUE self has to be there but we don't care what it is.
14
+ $CFLAGS << ' -Wno-keyword-macro' # hiding return
15
+ end
16
+
6
17
  create_makefile("bootsnap/bootsnap")
@@ -4,6 +4,10 @@ require 'zlib'
4
4
  module Bootsnap
5
5
  module CompileCache
6
6
  module ISeq
7
+ class << self
8
+ attr_accessor :cache_dir
9
+ end
10
+
7
11
  def self.input_to_storage(_, path)
8
12
  RubyVM::InstructionSequence.compile_file(path).to_binary
9
13
  rescue SyntaxError
@@ -28,6 +32,7 @@ module Bootsnap
28
32
  module InstructionSequenceMixin
29
33
  def load_iseq(path)
30
34
  Bootsnap::CompileCache::Native.fetch(
35
+ Bootsnap::CompileCache::ISeq.cache_dir,
31
36
  path.to_s,
32
37
  Bootsnap::CompileCache::ISeq
33
38
  )
@@ -62,7 +67,8 @@ module Bootsnap
62
67
  Bootsnap::CompileCache::Native.compile_option_crc32 = crc
63
68
  end
64
69
 
65
- def self.install!
70
+ def self.install!(cache_dir)
71
+ Bootsnap::CompileCache::ISeq.cache_dir = cache_dir
66
72
  Bootsnap::CompileCache::ISeq.compile_option_updated
67
73
  class << RubyVM::InstructionSequence
68
74
  prepend InstructionSequenceMixin
@@ -30,7 +30,7 @@ module Bootsnap
30
30
  ::YAML.load(data)
31
31
  end
32
32
 
33
- def self.install!
33
+ def self.install!(cache_dir)
34
34
  require 'yaml'
35
35
  require 'msgpack'
36
36
 
@@ -44,6 +44,7 @@ module Bootsnap
44
44
  klass = class << ::YAML; self; end
45
45
  klass.send(:define_method, :load_file) do |path|
46
46
  Bootsnap::CompileCache::Native.fetch(
47
+ cache_dir,
47
48
  path.to_s,
48
49
  Bootsnap::CompileCache::YAML
49
50
  )
@@ -3,13 +3,13 @@ require_relative 'compile_cache/yaml'
3
3
 
4
4
  module Bootsnap
5
5
  module CompileCache
6
- def self.setup(iseq:, yaml:)
6
+ def self.setup(cache_dir:, iseq:, yaml:)
7
7
  if iseq
8
- Bootsnap::CompileCache::ISeq.install!
8
+ Bootsnap::CompileCache::ISeq.install!(cache_dir)
9
9
  end
10
10
 
11
11
  if yaml
12
- Bootsnap::CompileCache::YAML.install!
12
+ Bootsnap::CompileCache::YAML.install!(cache_dir)
13
13
  end
14
14
  end
15
15
  end
@@ -54,22 +54,20 @@ module Bootsnap
54
54
  x = search_index(feature)
55
55
  return x if x
56
56
 
57
+ # Ruby has some built-in features that require lies about.
58
+ # For example, 'enumerator' is built in. If you require it, ruby
59
+ # returns false as if it were already loaded; however, there is no
60
+ # file to find on disk. We've pre-built a list of these, and we
61
+ # return false if any of them is loaded.
62
+ raise LoadPathCache::ReturnFalse if BUILTIN_FEATURES.key?(feature)
63
+
57
64
  # The feature wasn't found on our preliminary search through the index.
58
65
  # We resolve this differently depending on what the extension was.
59
66
  case File.extname(feature)
60
67
  # If the extension was one of the ones we explicitly cache (.rb and the
61
68
  # native dynamic extension, e.g. .bundle or .so), we know it was a
62
69
  # failure and there's nothing more we can do to find the file.
63
- when *CACHED_EXTENSIONS # .rb, .bundle or .so
64
- nil
65
- # If no extension was specified, it's the same situation, since we
66
- # try appending both cachable extensions in search_index. However,
67
- # there's a special-case for 'enumerator'. Before ruby 1.9, you had
68
- # to `require 'enumerator'` to use it. In 1.9+, it's pre-loaded, but
69
- # doesn't correspond to any entry on the filesystem. Ruby lies. So we
70
- # lie too, forcing our monkeypatch to return false like ruby would.
71
- when ""
72
- raise LoadPathCache::ReturnFalse if BUILTIN_FEATURES.key?(feature)
70
+ when '', *CACHED_EXTENSIONS # no extension, .rb, (.bundle or .so)
73
71
  nil
74
72
  # Ruby allows specifying native extensions as '.so' even when DLEXT
75
73
  # is '.bundle'. This is where we handle that case.
@@ -122,6 +120,7 @@ module Bootsnap
122
120
  @store.transaction do
123
121
  paths.map(&:to_s).each do |path|
124
122
  p = Path.new(path)
123
+ next if p.non_directory?
125
124
  entries, dirs = p.entries_and_dirs(@store)
126
125
  # push -> low precedence -> set only if unset
127
126
  dirs.each { |dir| @dirs[dir] ||= true }
@@ -134,6 +133,7 @@ module Bootsnap
134
133
  @store.transaction do
135
134
  paths.map(&:to_s).reverse.each do |path|
136
135
  p = Path.new(path)
136
+ next if p.non_directory?
137
137
  entries, dirs = p.entries_and_dirs(@store)
138
138
  # unshift -> high precedence -> unconditional set
139
139
  dirs.each { |dir| @dirs[dir] = true }
@@ -4,7 +4,10 @@ module Bootsnap
4
4
  module ActiveSupport
5
5
  def self.with_bootsnap_fallback(error)
6
6
  yield
7
- rescue error
7
+ rescue error => e
8
+ # NoMethodError is a NameError, but we only want to handle actual
9
+ # NameError instances.
10
+ raise unless e.class == error
8
11
  without_bootsnap_cache { yield }
9
12
  end
10
13
 
@@ -50,7 +53,9 @@ module Bootsnap
50
53
  CoreExt::ActiveSupport.with_bootsnap_fallback(NameError) { super }
51
54
  end
52
55
 
53
- def depend_on(file_name, message = "No such file to load -- %s.rb")
56
+ # Signature has changed a few times over the years; easiest to not
57
+ # reiterate it with version polymorphism here...
58
+ def depend_on(*)
54
59
  CoreExt::ActiveSupport.with_bootsnap_fallback(LoadError) { super }
55
60
  end
56
61
  end
@@ -23,6 +23,13 @@ module Bootsnap
23
23
  @path = path.to_s
24
24
  end
25
25
 
26
+ # True if the path exists, but represents a non-directory object
27
+ def non_directory?
28
+ !File.stat(path).directory?
29
+ rescue Errno::ENOENT
30
+ false
31
+ end
32
+
26
33
  # Return a list of all the requirable files and all of the subdirectories
27
34
  # of this +Path+.
28
35
  def entries_and_dirs(store)
@@ -1,6 +1,5 @@
1
1
  require_relative '../explicit_require'
2
2
 
3
- Bootsnap::ExplicitRequire.with_gems('snappy') { require 'snappy' }
4
3
  Bootsnap::ExplicitRequire.with_gems('msgpack') { require 'msgpack' }
5
4
  Bootsnap::ExplicitRequire.from_rubylibdir('fileutils')
6
5
 
@@ -58,8 +57,9 @@ module Bootsnap
58
57
 
59
58
  def load_data
60
59
  @data = begin
61
- MessagePack.load(Snappy.inflate(File.binread(@store_path)))
62
- rescue Errno::ENOENT, Snappy::Error
60
+ MessagePack.load(File.binread(@store_path))
61
+ # handle malformed data due to upgrade incompatability
62
+ rescue Errno::ENOENT, MessagePack::MalformedFormatError, MessagePack::UnknownExtTypeError
63
63
  {}
64
64
  end
65
65
  end
@@ -69,7 +69,7 @@ module Bootsnap
69
69
  # caches if they read at an inopportune time.
70
70
  tmp = "#{@store_path}.#{(rand * 100000).to_i}.tmp"
71
71
  FileUtils.mkpath(File.dirname(tmp))
72
- File.binwrite(tmp, Snappy.deflate(MessagePack.dump(@data)))
72
+ File.binwrite(tmp, MessagePack.dump(@data))
73
73
  FileUtils.mv(tmp, @store_path)
74
74
  end
75
75
  end
@@ -1,3 +1,3 @@
1
1
  module Bootsnap
2
- VERSION = "0.2.9"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/bootsnap.rb CHANGED
@@ -27,6 +27,7 @@ module Bootsnap
27
27
  ) if load_path_cache
28
28
 
29
29
  Bootsnap::CompileCache.setup(
30
+ cache_dir: cache_dir + '/bootsnap-compile-cache',
30
31
  iseq: compile_cache_iseq,
31
32
  yaml: compile_cache_yaml
32
33
  )
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: 0.2.9
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Burke Libbey
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-04-25 00:00:00.000000000 Z
11
+ date: 2017-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -81,33 +81,33 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.2'
83
83
  - !ruby/object:Gem::Dependency
84
- name: msgpack
84
+ name: ffi-xattr
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '1.0'
90
- type: :runtime
89
+ version: 0.1.2
90
+ type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '1.0'
96
+ version: 0.1.2
97
97
  - !ruby/object:Gem::Dependency
98
- name: snappy
98
+ name: msgpack
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 0.0.15
103
+ version: '1.0'
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 0.0.15
110
+ version: '1.0'
111
111
  description: wip.
112
112
  email:
113
113
  - burke.libbey@shopify.com
@@ -118,6 +118,8 @@ extra_rdoc_files: []
118
118
  files:
119
119
  - ".gitignore"
120
120
  - ".rubocop.yml"
121
+ - ".travis.yml"
122
+ - CHANGELOG.md
121
123
  - CONTRIBUTING.md
122
124
  - Gemfile
123
125
  - LICENSE
@@ -157,7 +159,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
157
159
  requirements:
158
160
  - - ">="
159
161
  - !ruby/object:Gem::Version
160
- version: '0'
162
+ version: 2.3.0
161
163
  required_rubygems_version: !ruby/object:Gem::Requirement
162
164
  requirements:
163
165
  - - ">="