lib/bootsnap/compile_cache/yaml.rb in bootsnap-1.5.1-java vs lib/bootsnap/compile_cache/yaml.rb in bootsnap-1.6.0

- old
+ new

@@ -5,51 +5,72 @@ module CompileCache module YAML class << self attr_accessor(:msgpack_factory, :cache_dir, :supported_options) - def input_to_storage(contents, _, kwargs) + def input_to_storage(contents, _) raise(Uncompilable) if contents.index("!ruby/object") - obj = ::YAML.load(contents, **(kwargs || {})) + obj = ::YAML.load(contents) msgpack_factory.dump(obj) rescue NoMethodError, RangeError - # if the object included things that we can't serialize, fall back to - # Marshal. It's a bit slower, but can encode anything yaml can. - # NoMethodError is unexpected types; RangeError is Bignums - Marshal.dump(obj) + # The object included things that we can't serialize + raise(Uncompilable) end def storage_to_output(data, kwargs) - # This could have a meaning in messagepack, and we're being a little lazy - # about it. -- but a leading 0x04 would indicate the contents of the YAML - # is a positive integer, which is rare, to say the least. - if data[0] == 0x04.chr && data[1] == 0x08.chr - Marshal.load(data) - else - msgpack_factory.load(data, **(kwargs || {})) + if kwargs && kwargs.key?(:symbolize_names) + kwargs[:symbolize_keys] = kwargs.delete(:symbolize_names) end + msgpack_factory.load(data, kwargs) end def input_to_output(data, kwargs) ::YAML.load(data, **(kwargs || {})) end + def precompile(path, cache_dir: YAML.cache_dir) + Bootsnap::CompileCache::Native.precompile( + cache_dir, + path.to_s, + Bootsnap::CompileCache::YAML, + ) + end + def install!(cache_dir) self.cache_dir = cache_dir init! ::YAML.singleton_class.prepend(Patch) end def init! require('yaml') require('msgpack') + require('date') # MessagePack serializes symbols as strings by default. # We want them to roundtrip cleanly, so we use a custom factory. # see: https://github.com/msgpack/msgpack-ruby/pull/122 factory = MessagePack::Factory.new factory.register_type(0x00, Symbol) + factory.register_type( + MessagePack::Timestamp::TYPE, # or just -1 + Time, + packer: MessagePack::Time::Packer, + unpacker: MessagePack::Time::Unpacker + ) + + marshal_fallback = { + packer: ->(value) { Marshal.dump(value) }, + unpacker: ->(payload) { Marshal.load(payload) }, + } + { + Date => 0x01, + Regexp => 0x02, + }.each do |type, code| + factory.register_type(code, type, marshal_fallback) + end + self.msgpack_factory = factory self.supported_options = [] params = ::YAML.method(:load).parameters if params.include?([:key, :symbolize_names]) @@ -63,12 +84,10 @@ self.supported_options.freeze end end module Patch - extend self - def load_file(path, *args) return super if args.size > 1 if kwargs = args.first return super unless kwargs.is_a?(Hash) return super unless (kwargs.keys - ::Bootsnap::CompileCache::YAML.supported_options).empty? @@ -83,9 +102,11 @@ ) rescue Errno::EACCES ::Bootsnap::CompileCache.permission_error(path) end end + + ruby2_keywords :load_file if respond_to?(:ruby2_keywords, true) end end end end