diff options
-rw-r--r-- | lib/chef/mixin/deep_merge.rb | 18 | ||||
-rw-r--r-- | lib/chef/node/attribute.rb | 4 | ||||
-rw-r--r-- | lib/chef/node/immutable_collections.rb | 4 |
3 files changed, 20 insertions, 6 deletions
diff --git a/lib/chef/mixin/deep_merge.rb b/lib/chef/mixin/deep_merge.rb index 3d4690bb57..825406a93e 100644 --- a/lib/chef/mixin/deep_merge.rb +++ b/lib/chef/mixin/deep_merge.rb @@ -105,11 +105,19 @@ class Chef # If there are two Hashes, recursively merge. if merge_onto.kind_of?(Hash) && merge_with.kind_of?(Hash) merge_with.each do |key, merge_with_value| - merge_onto[key] = if merge_onto.has_key?(key) - hash_only_merge(merge_onto[key], merge_with_value) - else - merge_with_value - end + value = + if merge_onto.has_key?(key) + hash_only_merge(merge_onto[key], merge_with_value) + else + merge_with_value + end + + if merge_onto.respond_to?(:public_method_that_only_deep_merge_should_use) + # we can't call ImmutableMash#[]= because its immutable, but we need to mutate it to build it in-place + merge_onto.public_method_that_only_deep_merge_should_use(key, value) + else + merge_onto[key] = value + end end merge_onto diff --git a/lib/chef/node/attribute.rb b/lib/chef/node/attribute.rb index 6c41e230ee..3c48f653eb 100644 --- a/lib/chef/node/attribute.rb +++ b/lib/chef/node/attribute.rb @@ -545,7 +545,9 @@ class Chef safe_dup(component) end - components.inject(ImmutableMash.new) do |merged, component| + return nil if components.compact.empty? + + components.inject(ImmutableMash.new({})) do |merged, component| Chef::Mixin::DeepMerge.hash_only_merge!(merged, component) end end diff --git a/lib/chef/node/immutable_collections.rb b/lib/chef/node/immutable_collections.rb index af04ef26d4..56b8fed3b7 100644 --- a/lib/chef/node/immutable_collections.rb +++ b/lib/chef/node/immutable_collections.rb @@ -155,6 +155,10 @@ class Chef end end + def public_method_that_only_deep_merge_should_use(key, value) + internal_set(key, immutablize(value)) + end + alias :attribute? :has_key? # Redefine all of the methods that mutate a Hash to raise an error when called. |