Skip to content

Commit

Permalink
Make deep_merge a soft-requirement
Browse files Browse the repository at this point in the history
The goal here is to remove deep_merge and rely entirely on
ActiveSupport's `Hash#deep_merge` implementation.

This does mean that if you want to keep the existing behavior, or rely
on DeepMerge's specific options, you need to add the following to your
Gemfile:

```ruby
gem 'deep_merge', '~> 1.2', '>= 1.2.1'
```
  • Loading branch information
zzak committed Nov 13, 2024
1 parent 25bc414 commit 85d692e
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 20 deletions.
1 change: 0 additions & 1 deletion config.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ Gem::Specification.new do |s|
s.require_paths = ['lib']
s.required_ruby_version = '>= 2.6.0'

s.add_dependency 'deep_merge', '~> 1.2', '>= 1.2.1'
s.add_dependency 'ostruct'

s.add_development_dependency 'dry-validation', *Config::DryValidationRequirements::VERSIONS
Expand Down
1 change: 1 addition & 0 deletions gemfiles/sinatra.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
source "https://rubygems.org"

gem "sinatra", "2.0.8.1"
gem "deep_merge", "~> 1.2", ">= 1.2.1"

gemspec path: "../"
13 changes: 12 additions & 1 deletion lib/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,18 @@
require 'config/sources/hash_source'
require 'config/sources/env_source'
require 'config/validation/schema'
require 'deep_merge/core'

begin
gem 'deep_merge', '~> 1.2', '>= 1.2.1'
require 'deep_merge/core'
rescue LoadError
warn <<~WARNING
The `deep_merge` gem is not available. Trying to use ActiveSupport's Hash#deep_merge instead.
If you want to continue using 'deep_merge' gem, please add it to your Gemfile:
gem 'deep_merge', '~> 1.2', '>= 1.2.1'
WARNING
require 'active_support/core_ext/hash/deep_merge'
end

module Config
extend Config::Validation::Schema
Expand Down
44 changes: 26 additions & 18 deletions lib/config/options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,19 @@ def reload!
if conf.empty?
conf = source_conf
else
DeepMerge.deep_merge!(
source_conf,
conf,
preserve_unmergeables: false,
knockout_prefix: Config.knockout_prefix,
overwrite_arrays: Config.overwrite_arrays,
merge_nil_values: Config.merge_nil_values,
merge_hash_arrays: Config.merge_hash_arrays
)
if defined?(DeepMerge)
DeepMerge.deep_merge!(
source_conf,
conf,
preserve_unmergeables: false,
knockout_prefix: Config.knockout_prefix,
overwrite_arrays: Config.overwrite_arrays,
merge_nil_values: Config.merge_nil_values,
merge_hash_arrays: Config.merge_hash_arrays
)
else
conf = conf.deep_merge!(source_conf)
end
end
end

Expand Down Expand Up @@ -98,15 +102,19 @@ def as_json(options = nil)

def merge!(hash)
current = to_hash
DeepMerge.deep_merge!(
hash.dup,
current,
preserve_unmergeables: false,
knockout_prefix: Config.knockout_prefix,
overwrite_arrays: Config.overwrite_arrays,
merge_nil_values: Config.merge_nil_values,
merge_hash_arrays: Config.merge_hash_arrays
)
if defined?(DeepMerge)
DeepMerge.deep_merge!(
hash.dup,
current,
preserve_unmergeables: false,
knockout_prefix: Config.knockout_prefix,
overwrite_arrays: Config.overwrite_arrays,
merge_nil_values: Config.merge_nil_values,
merge_hash_arrays: Config.merge_hash_arrays
)
else
current.deep_merge!(hash)
end
marshal_load(__convert(current).marshal_dump)
self
end
Expand Down
15 changes: 15 additions & 0 deletions spec/config_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,11 @@
end

it 'should not overwrite values with nil' do
unless defined?(DeepMerge)
skip <<~REASON
DeepMerge is not available in the current context. This test only applies when the `deep_merge` gem is available.
REASON
end
old_value = config.inner.something1
config.merge!(hash_with_nil)
expect(config.inner.something1).to eq(old_value)
Expand Down Expand Up @@ -418,6 +423,11 @@
end

it 'should remove elements from settings' do
unless defined?(DeepMerge)
skip <<~REASON
DeepMerge is not available in the current context. This test only applies when the `deep_merge` gem is available.
REASON
end
expect(config.array1).to eq(['item4', 'item5', 'item6'])
expect(config.array2.inner).to eq(['item4', 'item5', 'item6'])
expect(config.array3).to eq('')
Expand Down Expand Up @@ -474,6 +484,11 @@
end

it 'should merge arrays from multiple configs' do
unless defined?(DeepMerge)
skip <<~REASON
DeepMerge is not available in the current context. This test only applies when the `deep_merge` gem is available.
REASON
end
expect(config.arraylist1.size).to eq(6)
expect(config.arraylist2.inner.size).to eq(6)
end
Expand Down
35 changes: 35 additions & 0 deletions spec/options_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@
end

it 'should overwrite the previous values' do
unless defined?(DeepMerge)
skip <<~REASON
DeepMerge is not available in the current context. This test only applies when the `deep_merge` gem is available.
REASON
end
expect(config['tvrage']['service_url']).to eq('http://url2')
end

Expand All @@ -124,6 +129,11 @@
end

it 'should overwrite the previous values' do
unless defined?(DeepMerge)
skip <<~REASON
DeepMerge is not available in the current context. This test only applies when the `deep_merge` gem is available.
REASON
end
expect(config['tvrage']['service_url']).to eq('http://url3')
end
end
Expand All @@ -144,6 +154,11 @@
end

it 'should add keys from the added file' do
unless defined?(DeepMerge)
skip <<~REASON
DeepMerge is not available in the current context. This test only applies when the `deep_merge` gem is available.
REASON
end
expect(config['tvrage']['service_url']).to eq('http://services.tvrage.com')
end

Expand All @@ -154,6 +169,11 @@
end

it 'should overwrite the previous values' do
unless defined?(DeepMerge)
skip <<~REASON
DeepMerge is not available in the current context. This test only applies when the `deep_merge` gem is available.
REASON
end
expect(config['tvrage']['service_url']).to eq('http://services.tvrage.com')
end
end
Expand All @@ -168,6 +188,11 @@
end

it 'should be overwritten by the following values' do
unless defined?(DeepMerge)
skip <<~REASON
DeepMerge is not available in the current context. This test only applies when the `deep_merge` gem is available.
REASON
end
expect(config['tvrage']['service_url']).to eq('http://services.tvrage.com')
end

Expand Down Expand Up @@ -246,6 +271,11 @@
} }

it 'should merge the arrays' do
unless defined?(DeepMerge)
skip <<~REASON
DeepMerge is not available in the current context. This test only applies when the `deep_merge` gem is available.
REASON
end
config = Config.load_files("#{fixture_path}/deep_merge3/config1.yml", "#{fixture_path}/deep_merge3/config2.yml")

expect(config.array.length).to eq(1)
Expand All @@ -261,6 +291,11 @@
} }

it 'should merge the arrays' do
unless defined?(DeepMerge)
skip <<~REASON
DeepMerge is not available in the current context. This test only applies when the `deep_merge` gem is available.
REASON
end
config = Config.load_files("#{fixture_path}/deep_merge3/config1.yml", "#{fixture_path}/deep_merge3/config2.yml")

expect(config.array.length).to eq(2)
Expand Down

0 comments on commit 85d692e

Please sign in to comment.