Skip to content

Commit

Permalink
Merge pull request chef#1540 from opscode/lcg/ffi-yajl-gem
Browse files Browse the repository at this point in the history
replace ruby-yajl with ffi-yajl gem
  • Loading branch information
lamont-granquist committed Jun 24, 2014
2 parents d111e82 + f382c51 commit 9f42bee
Show file tree
Hide file tree
Showing 9 changed files with 19 additions and 29 deletions.
3 changes: 1 addition & 2 deletions chef.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ Gem::Specification.new do |s|
s.add_dependency "mime-types", "~> 1.16"

# The JSON gem reliably releases breaking changes as a patch release
s.add_dependency "json", ">= 1.4.4", "<= 1.8.1"
s.add_dependency "yajl-ruby", "~> 1.1"
s.add_dependency "ffi-yajl"
s.add_dependency "net-ssh", "~> 2.6"
s.add_dependency "net-ssh-multi", "~> 1.1"
# CHEF-3027: The knife-cloud plugins require newer features from highline, core chef should not.
Expand Down
2 changes: 1 addition & 1 deletion lib/chef/config_fetcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def fetch_json
config_data = read_config
begin
Chef::JSONCompat.from_json(config_data)
rescue JSON::ParserError => error
rescue FFI_Yajl::ParseError => error
Chef::Application.fatal!("Could not parse the provided JSON file (#{config_location}): " + error.message, 2)
end
end
Expand Down
6 changes: 3 additions & 3 deletions lib/chef/encrypted_data_bag_item/decryptor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#

require 'yaml'
require 'yajl'
require 'ffi_yajl'
require 'openssl'
require 'base64'
require 'digest/sha2'
Expand Down Expand Up @@ -121,8 +121,8 @@ def initialize(encrypted_data, key)
end

def for_decrypted_item
Yajl::Parser.parse(decrypted_data)["json_wrapper"]
rescue Yajl::ParseError
FFI_Yajl::Parser.parse(decrypted_data)["json_wrapper"]
rescue FFI_Yajl::ParseError
# convert to a DecryptionFailure error because the most likely scenario
# here is that the decryption step was unsuccessful but returned bad
# data rather than raising an error.
Expand Down
4 changes: 2 additions & 2 deletions lib/chef/encrypted_data_bag_item/encryptor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
require 'base64'
require 'digest/sha2'
require 'openssl'
require 'yajl'
require 'ffi_yajl'
require 'chef/encrypted_data_bag_item'
require 'chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format'

Expand Down Expand Up @@ -111,7 +111,7 @@ def encrypted_data
# Strings) that do not produce valid JSON when serialized without the
# wrapper.
def serialized_data
Yajl::Encoder.encode(:json_wrapper => plaintext_data)
FFI_Yajl::Encoder.encode(:json_wrapper => plaintext_data)
end
end

Expand Down
21 changes: 5 additions & 16 deletions lib/chef/json_compat.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

# Wrapper class for interacting with JSON.

require 'json'
require 'yajl'
require 'ffi_yajl'
require 'ffi_yajl/json_gem' # XXX: parts of chef require JSON gem's Hash#to_json monkeypatch

class Chef
class JSONCompat
Expand All @@ -40,20 +40,9 @@ class JSONCompat

class <<self

# See CHEF-1292/PL-538. Increase the max nesting for JSON, which defaults
# to 19, and isn't enough for some (for example, a Node within a Node)
# structures.
def opts_add_max_nesting(opts)
if opts.nil? || !opts.has_key?(:max_nesting)
opts = opts.nil? ? Hash.new : opts.clone
opts[:max_nesting] = JSON_MAX_NESTING
end
opts
end

# Just call the JSON gem's parse method with a modified :max_nesting field
def from_json(source, opts = {})
obj = ::Yajl::Parser.parse(source)
obj = ::FFI_Yajl::Parser.parse(source)

# JSON gem requires top level object to be a Hash or Array (otherwise
# you get the "must contain two octets" error). Yajl doesn't impose the
Expand Down Expand Up @@ -99,11 +88,11 @@ def map_hash_to_rb_obj(json_hash)
end

def to_json(obj, opts = nil)
obj.to_json(opts_add_max_nesting(opts))
obj.to_json(opts)
end

def to_json_pretty(obj, opts = nil)
::JSON.pretty_generate(obj, opts_add_max_nesting(opts))
::JSON.pretty_generate(obj, opts)
end


Expand Down
4 changes: 3 additions & 1 deletion lib/chef/knife/core/object_loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
# limitations under the License.
#

require 'ffi_yajl'

class Chef
class Knife
module Core
Expand Down Expand Up @@ -83,7 +85,7 @@ def find_all_object_dirs(path)
def object_from_file(filename)
case filename
when /\.(js|json)$/
r = Yajl::Parser.parse(IO.read(filename))
r = FFI_Yajl::Parser.parse(IO.read(filename))

# Chef::DataBagItem doesn't work well with the json_create method
if @klass == Chef::DataBagItem
Expand Down
2 changes: 1 addition & 1 deletion lib/chef/provider/remote_file/cache_control_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def apply(previous_cc_data)

def load_data
Chef::JSONCompat.from_json(load_json_data)
rescue Chef::Exceptions::FileNotFound, Yajl::ParseError, JSON::ParserError
rescue Chef::Exceptions::FileNotFound, FFI_Yajl::ParseError, JSON::ParserError
false
end

Expand Down
4 changes: 2 additions & 2 deletions spec/unit/knife/bootstrap_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@
@knife.instance_variable_set("@template_file", @knife.config[:template_file])
template_string = @knife.read_template
@knife.parse_options(["-j", '{"foo":{"bar":"baz"}}'])
expected_hash = Yajl::Parser.new.parse('{"foo":{"bar":"baz"},"run_list":[]}')
actual_hash = Yajl::Parser.new.parse(@knife.render_template(template_string))
expected_hash = FFI_Yajl::Parser.new.parse('{"foo":{"bar":"baz"},"run_list":[]}')
actual_hash = FFI_Yajl::Parser.new.parse(@knife.render_template(template_string))
actual_hash.should == expected_hash
end

Expand Down
2 changes: 1 addition & 1 deletion spec/unit/provider/remote_file/cache_control_data_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@
it "truncates the file cache path to 102 characters" do
normalized_cache_path = cache_control_data.send('sanitized_cache_file_basename')

Chef::FileCache.should_receive(:store).with("remote_file/" + normalized_cache_path, cache_control_data.json_data)
Chef::FileCache.should_receive(:store).with("remote_file/" + normalized_cache_path, cache_control_data.json_data)

cache_control_data.save

Expand Down

0 comments on commit 9f42bee

Please sign in to comment.