diff options
Diffstat (limited to 'lib/leap_cli/config/object.rb')
-rw-r--r-- | lib/leap_cli/config/object.rb | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/lib/leap_cli/config/object.rb b/lib/leap_cli/config/object.rb index 4f5afe1..55f54b2 100644 --- a/lib/leap_cli/config/object.rb +++ b/lib/leap_cli/config/object.rb @@ -106,11 +106,19 @@ module LeapCli ## # - # a deep (recursive) merge with another Config::Object. + # A deep (recursive) merge with another Config::Object. # - # if prefer_self is set to true, the value from self will be picked when there is a conflict + # If prefer_self is set to true, the value from self will be picked when there is a conflict # that cannot be merged. # + # Merging rules: + # + # - If a value is a hash, we recursively merge it. + # - If the value is simple, like a string, the new one overwrites the value. + # - If the value is an array: + # - If both old and new values are arrays, the new one replaces the old. + # - If one of the values is simple but the other is an array, the simple is added to the array. + # def deep_merge!(object, prefer_self=false) object.each do |key,new_value| old_value = self.fetch key, nil @@ -127,19 +135,18 @@ module LeapCli old_value.is_a?(Hash) ? value.deep_merge!(old_value) : (value[key] = old_value if !old_value.nil?) new_value.is_a?(Hash) ? value.deep_merge!(new_value, prefer_self) : (value[key] = new_value if !new_value.nil?) - # merge arrays - elsif old_value.is_a?(Array) || new_value.is_a?(Array) - value = [] - old_value.is_a?(Array) ? value += old_value : value << old_value - new_value.is_a?(Array) ? value += new_value : value << new_value - value = value.compact.uniq - # merge nil elsif new_value.nil? value = old_value elsif old_value.nil? value = new_value + # merge arrays when one value is not an array + elsif old_value.is_a?(Array) && !new_value.is_a?(Array) + value = (old_value.dup << new_value).compact.uniq + elsif new_value.is_a?(Array) && !old_value.is_a?(Array) + value = (new_value.dup << old_value).compact.uniq + # catch errors elsif type_mismatch?(old_value, new_value) raise 'Type mismatch. Cannot merge %s (%s) with %s (%s). Key is "%s", name is "%s".' % [ @@ -148,7 +155,7 @@ module LeapCli key, self.class ] - # merge strings and numbers + # merge strings, numbers, and sometimes arrays else if prefer_self value = old_value |