gooddata 1.3.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.dockerignore +2 -0
- data/CHANGELOG.md +48 -0
- data/CONTRIBUTING.md +19 -12
- data/Dockerfile +37 -0
- data/Gemfile +0 -0
- data/README.md +1 -1
- data/Rakefile +17 -1
- data/bin/run_brick.rb +31 -0
- data/gooddata.gemspec +1 -0
- data/lib/gooddata/bricks/hello_world_brick.rb +21 -0
- data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +12 -0
- data/lib/gooddata/bricks/middleware/logger_middleware.rb +12 -0
- data/lib/gooddata/bricks/pipeline.rb +12 -0
- data/lib/gooddata/exceptions/filter_maqlization.rb +0 -6
- data/lib/gooddata/extensions/class.rb +4 -0
- data/lib/gooddata/extensions/enumerable.rb +0 -3
- data/lib/gooddata/extensions/extensions.rb +0 -3
- data/lib/gooddata/extensions/false.rb +8 -16
- data/lib/gooddata/extensions/hash.rb +10 -41
- data/lib/gooddata/extensions/integer.rb +9 -3
- data/lib/gooddata/extensions/nil.rb +5 -13
- data/lib/gooddata/extensions/object.rb +0 -11
- data/lib/gooddata/extensions/string.rb +11 -5
- data/lib/gooddata/extensions/true.rb +8 -16
- data/lib/gooddata/helpers/global_helpers.rb +12 -0
- data/lib/gooddata/helpers/global_helpers_params.rb +5 -3
- data/lib/gooddata/lcm/actions/apply_custom_maql.rb +6 -0
- data/lib/gooddata/lcm/actions/base_action.rb +8 -2
- data/lib/gooddata/lcm/actions/collect_multiple_projects_column.rb +46 -0
- data/lib/gooddata/lcm/actions/collect_users_brick_users.rb +9 -2
- data/lib/gooddata/lcm/actions/execute_schedules.rb +0 -2
- data/lib/gooddata/lcm/actions/hello_world.rb +1 -1
- data/lib/gooddata/lcm/actions/synchronize_cas.rb +6 -0
- data/lib/gooddata/lcm/actions/synchronize_ldm.rb +6 -0
- data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +70 -107
- data/lib/gooddata/lcm/actions/synchronize_users.rb +1 -13
- data/lib/gooddata/lcm/brick_logger.rb +26 -0
- data/lib/gooddata/lcm/lcm2.rb +46 -7
- data/lib/gooddata/lcm/types/base_type.rb +4 -0
- data/lib/gooddata/lcm/types/class/class.rb +2 -0
- data/lib/gooddata/lcm/types/complex/complex.rb +2 -0
- data/lib/gooddata/lcm/types/special/array.rb +2 -0
- data/lib/gooddata/models/blueprint/project_blueprint.rb +5 -5
- data/lib/gooddata/models/blueprint/to_manifest.rb +0 -2
- data/lib/gooddata/models/domain.rb +1 -0
- data/lib/gooddata/models/from_wire.rb +0 -2
- data/lib/gooddata/models/profile.rb +1 -1
- data/lib/gooddata/models/project.rb +5 -0
- data/lib/gooddata/models/user_filters/user_filter_builder.rb +49 -32
- data/lib/gooddata/models/user_group.rb +3 -0
- data/lib/gooddata/rest/client.rb +4 -4
- data/lib/gooddata/rest/object.rb +2 -0
- data/lib/gooddata/version.rb +1 -1
- metadata +23 -5
- data/lib/gooddata/extensions/big_decimal.rb +0 -17
- data/lib/gooddata/extensions/numeric.rb +0 -15
- data/lib/gooddata/extensions/symbol.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78388b62f10692bc8416395774aad6f3d4020b39
|
4
|
+
data.tar.gz: 925461dba225f4b742734c96a423fec33fca818a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c50cccdecccfd33eb03bbd40e9d129e413d2a02a3ba5ee96f4a0e76c16f4007747fa697e6065480875d283f5f5169b3d21ccd920ca0880049d50fbd27030baf
|
7
|
+
data.tar.gz: ec7eb3f19ed6cad1915eb30133305ea2c97f052d5dfd1bd8a6f9897ebbd069c565d68d250cf518ee35ac6450edf283e33cd76811e4fd59ba94670bcf8bcfd2c4
|
data/.dockerignore
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,52 @@
|
|
1
1
|
# GoodData Ruby SDK Changelog
|
2
|
+
## 1.3.1
|
3
|
+
- FEATURE: TMA-1030 Raise jruby version used in K8s docker image (#1284)
|
4
|
+
- Update README.md
|
5
|
+
- TRIVIAL: Correct dockerfile maintainer
|
6
|
+
- TMA-1033: show reason of filter composition failure (#1282)
|
7
|
+
- TMA-483 && TMA-963 Paralel ufb bug final fix
|
8
|
+
- TMA-963 && TMA-483: UFB and UB performance (#1234)
|
9
|
+
- TMA-1002 fixed broken tests
|
10
|
+
- no vcr (#1277)
|
11
|
+
- TMA-1005: Automate rotating credentials
|
12
|
+
- TMA-925: Optimize polling intervals
|
13
|
+
- Add info about running tests to CONTRIBUTING.md (#1262)
|
14
|
+
- Fix rubocop issue
|
15
|
+
- Add empty lines between licenses and modules
|
16
|
+
- SETI-2180 Updated base image namespace
|
17
|
+
- FEATURE: TMA-1030 Dockerize LCM bricks
|
18
|
+
- FEATURE: TMA-1030 Write brick outputs to files
|
19
|
+
- FEATURE: TMA-1030 Add Hello World brick
|
20
|
+
- REFACTOR: TMA-1030 Non functional changes
|
21
|
+
- BUGFIX: TMA-1040 Add nil result if action fails
|
22
|
+
- TEST: TMA-1040 Add tests for "perform" method in LCM2 module
|
23
|
+
- Require ActiveSupport where it's needed
|
24
|
+
- Revert Array refinement to Enumerable opening
|
25
|
+
- Revert class to reopening
|
26
|
+
- Use duplicable? from ActiveSupport
|
27
|
+
- Remove object.blank? as ActiveSupport already do it
|
28
|
+
- Revert Object to reopening
|
29
|
+
- Increase the scope of monkey patchs
|
30
|
+
- Fixes tests in CI
|
31
|
+
- Patch all places that use '.to_b' with all extensions that implements it
|
32
|
+
- Isolate Symbol monkeypatch in SymbolExtensions module
|
33
|
+
- Code :lipstick: Insert license header in files where it was missing
|
34
|
+
- Isolate String monkeypatch in StringExtensions module
|
35
|
+
- Add TrueExtensions and FalseExtensions in missing places
|
36
|
+
- Isolate Object monkeypatch in ObjectExtensions module
|
37
|
+
- Isolate Numeric monkeypatch in NumericExtensions module
|
38
|
+
- Isolate BigDecimal monkeypatch in BigDecimalExtensions module
|
39
|
+
- Adds Extensions to Globalhelper, it's the only one calls `duplicable?`
|
40
|
+
- Isolate Nil monkeypatch in NilExtensions module
|
41
|
+
- Isolate Integer monkeypatch in IntegerExtensions module
|
42
|
+
- Isolate Hash monkeypatch in HashExtensions module
|
43
|
+
- Isolate True/False monkey patchs in respectives modules
|
44
|
+
- Is a good practice to explicit the error in rescue block
|
45
|
+
- Isolate Enumerable monkey patch in EnumerableExtensions module
|
46
|
+
- Isolate Class monkeypatch in ClassExtensions module
|
47
|
+
- TMA-927: handle uppercase email inputs
|
48
|
+
- TMA-648 tests not deleting ads instances fixed
|
49
|
+
|
2
50
|
## 1.3.0
|
3
51
|
- Add changelog for 1.2.1
|
4
52
|
- Automate bumping version (#1243)
|
data/CONTRIBUTING.md
CHANGED
@@ -1,5 +1,24 @@
|
|
1
1
|
# Contributing
|
2
2
|
|
3
|
+
## Tests
|
4
|
+
### Unit tests
|
5
|
+
`bundle exec rake test:unit`
|
6
|
+
### Integration tests
|
7
|
+
Currently only GoodData employees can run integration tests for security reasons.
|
8
|
+
|
9
|
+
`GD_SPEC_PASSWORD=*** bundle exec rake test:integration`
|
10
|
+
|
11
|
+
[Integration tests](spec/integration) can be run against different GoodData [environments](spec/environment) or with
|
12
|
+
[VCR](https://relishapp.com/vcr/vcr/docs).
|
13
|
+
|
14
|
+
#### VCR test setup
|
15
|
+
When adding new integration test, always set `:vcr` metadata.
|
16
|
+
```ruby
|
17
|
+
describe 'New integration test', :vcr
|
18
|
+
```
|
19
|
+
The VCR `record` mode can be set via `VCR_RECORD_MODE` environment variable. Set it to `all` to make a new recording.
|
20
|
+
Please check the recorded payloads for possible sensitive data before submitting to github.
|
21
|
+
|
3
22
|
## Static analysis
|
4
23
|
We use [Pronto](https://github.com/prontolabs/pronto) to detect code smells using static analysis. Comments are automatically created on pull requests when code smells are found.
|
5
24
|
|
@@ -35,16 +54,4 @@ We use [Pronto](https://github.com/prontolabs/pronto) to detect code smells usin
|
|
35
54
|
[license](/LICENSE).
|
36
55
|
1. Use `GoodData.logger` for logging instead of `puts`.
|
37
56
|
|
38
|
-
## Integration tests
|
39
|
-
[Integration tests](spec/integration) can be run against different GoodData [environments](spec/environment) or with
|
40
|
-
[VCR](https://relishapp.com/vcr/vcr/docs).
|
41
|
-
|
42
|
-
### VCR test setup
|
43
|
-
When adding new integration test, always set `:vcr` metadata.
|
44
|
-
```ruby
|
45
|
-
describe 'New integration test', :vcr
|
46
|
-
```
|
47
|
-
The VCR `record` mode can be set via `VCR_RECORD_MODE` environment variable. Set it to `all` to make a new recording.
|
48
|
-
Please check the recorded payloads for possible sensitive data before submitting to github.
|
49
|
-
|
50
57
|
_Based on [GitLab's contribution guide](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md)._
|
data/Dockerfile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
FROM harbor.intgdc.com/tools/gdc-java-8-jre:b057b53
|
2
|
+
|
3
|
+
MAINTAINER LCM <lcm@gooddata.com>
|
4
|
+
|
5
|
+
LABEL image_name="GDC LCM Bricks"
|
6
|
+
LABEL maintainer="LCM <lcm@gooddata.com>"
|
7
|
+
LABEL git_repostiory_url="https://github.com/gooddata/gooddata-ruby/"
|
8
|
+
LABEL parent_image="harbor.intgdc.com/tools/gdc-java-8-jre:b057b53"
|
9
|
+
|
10
|
+
# which is required by RVM
|
11
|
+
RUN yum install -y curl which \
|
12
|
+
&& yum clean all \
|
13
|
+
&& rm -rf /var/cache/yum
|
14
|
+
|
15
|
+
RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
|
16
|
+
RUN curl -sSL https://get.rvm.io | bash -s stable --ruby=jruby-9.1.14
|
17
|
+
|
18
|
+
# Switch to directory with sources
|
19
|
+
WORKDIR /src
|
20
|
+
|
21
|
+
# login shell is required by rvm
|
22
|
+
RUN /bin/bash -l -c ". /usr/local/rvm/scripts/rvm && gem update --system \
|
23
|
+
&& gem install bundler rake"
|
24
|
+
|
25
|
+
ARG SOURCE_COMMIT
|
26
|
+
ENV GOODDATA_RUBY_COMMIT=$SOURCE_COMMIT
|
27
|
+
|
28
|
+
ADD ./bin ./bin
|
29
|
+
ADD ./lib ./lib
|
30
|
+
ADD ./Gemfile .
|
31
|
+
ADD ./gooddata.gemspec .
|
32
|
+
|
33
|
+
RUN /bin/bash -l -c ". /usr/local/rvm/scripts/rvm && bundle install"
|
34
|
+
|
35
|
+
ENTRYPOINT ["/bin/bash", "-l", "-c"]
|
36
|
+
|
37
|
+
CMD [ ". /usr/local/rvm/scripts/rvm && bundle exec ./bin/run_brick.rb" ]
|
data/Gemfile
CHANGED
File without changes
|
data/README.md
CHANGED
@@ -78,4 +78,4 @@ For full contributor info see [contributors page](https://github.com/gooddata/go
|
|
78
78
|
|
79
79
|
## Copyright
|
80
80
|
|
81
|
-
Copyright (c) 2010 -
|
81
|
+
Copyright (c) 2010 - 2018 GoodData Corporation and Thomas Watson Steen. See [LICENSE](/LICENSE) for details.
|
data/Rakefile
CHANGED
@@ -5,10 +5,11 @@ require 'rubygems'
|
|
5
5
|
require 'bundler/setup'
|
6
6
|
require 'bundler/cli'
|
7
7
|
require 'bundler/gem_tasks'
|
8
|
-
|
8
|
+
require 'gooddata'
|
9
9
|
require 'rake/testtask'
|
10
10
|
require 'rspec/core/rake_task'
|
11
11
|
|
12
|
+
require 'yaml'
|
12
13
|
require 'yard'
|
13
14
|
|
14
15
|
require 'rubocop/rake_task'
|
@@ -224,3 +225,18 @@ namespace :gitflow do
|
|
224
225
|
system(file_path) || fail('Initializing git-flow failed!')
|
225
226
|
end
|
226
227
|
end
|
228
|
+
|
229
|
+
namespace :password do
|
230
|
+
task :rotate, [:value, :encryption_key] do |_, args|
|
231
|
+
key = 'password'
|
232
|
+
value = args[:value]
|
233
|
+
encryption_key = args[:encryption_key]
|
234
|
+
encrypted_value = GoodData::Helpers.encrypt(value, encryption_key).strip
|
235
|
+
secrets_path = File.join(File.dirname(__FILE__), 'spec/environment/secrets.yaml')
|
236
|
+
secrets = YAML.load_file(secrets_path)
|
237
|
+
secrets.each_value do |env|
|
238
|
+
env[key].replace(encrypted_value) if env.key?(key)
|
239
|
+
end
|
240
|
+
File.write(secrets_path, secrets.to_yaml)
|
241
|
+
end
|
242
|
+
end
|
data/bin/run_brick.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'remote_syslog_logger'
|
4
|
+
require_relative '../lib/gooddata'
|
5
|
+
|
6
|
+
DEFAULT_BRICK = 'hello_world_brick'
|
7
|
+
|
8
|
+
brick_type = ENV['BRICK_TYPE'] || DEFAULT_BRICK
|
9
|
+
|
10
|
+
syslog_node = ENV['NODE_NAME']
|
11
|
+
log = RemoteSyslogLogger.new(syslog_node, 514, :program => brick_type)
|
12
|
+
|
13
|
+
log.info "action=#{brick_type}_execution status=start"
|
14
|
+
|
15
|
+
begin
|
16
|
+
brick_pipeline = GoodData::Bricks::Pipeline.send("#{brick_type}_pipeline")
|
17
|
+
params_json = ENV['BRICK_PARAMS_JSON']
|
18
|
+
params = params_json.nil? ? {} : JSON.parse(params_json)
|
19
|
+
|
20
|
+
params['gooddata_ruby_commit'] = ENV['GOODDATA_RUBY_COMMIT'] || '<unknown>'
|
21
|
+
params['log_directory'] = ENV['LOG_DIRECTORY'] || '/tmp/'
|
22
|
+
|
23
|
+
@brick_result = brick_pipeline.call(params)
|
24
|
+
log.info "action=#{brick_type}_execution status=finished"
|
25
|
+
rescue NoMethodError => e
|
26
|
+
log.info "action=#{brick_type}_execution status=error Invalid brick type '#{brick_type}', #{e.message}"
|
27
|
+
raise e
|
28
|
+
rescue => e
|
29
|
+
log.info "action=#{brick_type}_execution status=error #{e.message}"
|
30
|
+
raise e
|
31
|
+
end
|
data/gooddata.gemspec
CHANGED
@@ -60,6 +60,7 @@ Gem::Specification.new do |s|
|
|
60
60
|
s.add_dependency 'multi_json', '~> 1.12'
|
61
61
|
s.add_dependency 'parseconfig', '~> 1.0'
|
62
62
|
s.add_dependency 'pmap', '~> 1.1'
|
63
|
+
s.add_dependency 'remote_syslog_logger', '~> 1.0.3'
|
63
64
|
s.add_dependency 'restforce', '~> 2.4'
|
64
65
|
s.add_dependency 'rest-client', '~> 2.0'
|
65
66
|
s.add_dependency 'rubyzip', '~> 1.2', '>= 1.2.1'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative 'brick'
|
2
|
+
|
3
|
+
module GoodData
|
4
|
+
module Bricks
|
5
|
+
# Simple brick used for testing and debug purposes
|
6
|
+
class HelloWorldBrick < GoodData::Bricks::Brick
|
7
|
+
def version
|
8
|
+
'0.0.1'
|
9
|
+
end
|
10
|
+
|
11
|
+
# HelloWorld brick entry-point
|
12
|
+
#
|
13
|
+
# @param [Hash] params Parameters
|
14
|
+
# @option [String] 'message' text to be returned in result, if nill - nothing is returned
|
15
|
+
# :reek:UtilityFunction
|
16
|
+
def call(params)
|
17
|
+
GoodData::LCM2.perform('hello_world', params)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -6,6 +6,18 @@
|
|
6
6
|
|
7
7
|
require_relative 'base_middleware'
|
8
8
|
|
9
|
+
require 'gooddata/extensions/true'
|
10
|
+
require 'gooddata/extensions/false'
|
11
|
+
require 'gooddata/extensions/integer'
|
12
|
+
require 'gooddata/extensions/string'
|
13
|
+
require 'gooddata/extensions/nil'
|
14
|
+
|
15
|
+
using TrueExtensions
|
16
|
+
using FalseExtensions
|
17
|
+
using IntegerExtensions
|
18
|
+
using StringExtensions
|
19
|
+
using NilExtensions
|
20
|
+
|
9
21
|
module GoodData
|
10
22
|
module Bricks
|
11
23
|
# Connects to platform and enriches parameters with GoodData::Client
|
@@ -6,6 +6,18 @@
|
|
6
6
|
|
7
7
|
require 'logger'
|
8
8
|
|
9
|
+
require 'gooddata/extensions/true'
|
10
|
+
require 'gooddata/extensions/false'
|
11
|
+
require 'gooddata/extensions/integer'
|
12
|
+
require 'gooddata/extensions/string'
|
13
|
+
require 'gooddata/extensions/nil'
|
14
|
+
|
15
|
+
using TrueExtensions
|
16
|
+
using FalseExtensions
|
17
|
+
using IntegerExtensions
|
18
|
+
using StringExtensions
|
19
|
+
using NilExtensions
|
20
|
+
|
9
21
|
require_relative 'base_middleware'
|
10
22
|
|
11
23
|
module GoodData
|
@@ -9,6 +9,7 @@ require_relative 'user_filters_brick'
|
|
9
9
|
require_relative 'release_brick'
|
10
10
|
require_relative 'provisioning_brick'
|
11
11
|
require_relative 'rollout_brick'
|
12
|
+
require_relative 'hello_world_brick'
|
12
13
|
|
13
14
|
module GoodData
|
14
15
|
module Bricks
|
@@ -87,6 +88,17 @@ module GoodData
|
|
87
88
|
RolloutBrick
|
88
89
|
])
|
89
90
|
end
|
91
|
+
|
92
|
+
def self.hello_world_brick_pipeline
|
93
|
+
prepare(
|
94
|
+
[
|
95
|
+
DecodeParamsMiddleware,
|
96
|
+
LoggerMiddleware,
|
97
|
+
BenchMiddleware,
|
98
|
+
HelloWorldBrick
|
99
|
+
]
|
100
|
+
)
|
101
|
+
end
|
90
102
|
end
|
91
103
|
end
|
92
104
|
end
|
@@ -1,9 +1,6 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
#
|
3
1
|
# Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
|
4
2
|
# This source code is licensed under the BSD-style license found in the
|
5
3
|
# LICENSE file in the root directory of this source tree.
|
6
|
-
|
7
4
|
module Enumerable
|
8
5
|
def mapcat(initial = [], &block)
|
9
6
|
reduce(initial) do |a, e|
|
@@ -1,9 +1,6 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
#
|
3
1
|
# Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
|
4
2
|
# This source code is licensed under the BSD-style license found in the
|
5
3
|
# LICENSE file in the root directory of this source tree.
|
6
|
-
|
7
4
|
base = Pathname(__FILE__).dirname.expand_path
|
8
5
|
Dir.glob(base + '*.rb').each do |file|
|
9
6
|
require_relative file
|
@@ -1,23 +1,15 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
#
|
3
1
|
# Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
|
4
2
|
# This source code is licensed under the BSD-style license found in the
|
5
3
|
# LICENSE file in the root directory of this source tree.
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
def duplicable?
|
13
|
-
false
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_b
|
17
|
-
false
|
18
|
-
end
|
5
|
+
module FalseExtensions
|
6
|
+
refine FalseClass do
|
7
|
+
def to_b
|
8
|
+
false
|
9
|
+
end
|
19
10
|
|
20
|
-
|
21
|
-
|
11
|
+
def to_i
|
12
|
+
0
|
13
|
+
end
|
22
14
|
end
|
23
15
|
end
|
@@ -1,48 +1,17 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
#
|
3
1
|
# Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
|
4
2
|
# This source code is licensed under the BSD-style license found in the
|
5
3
|
# LICENSE file in the root directory of this source tree.
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
# {:a => 1}.with_indifferent_access.except(:a) # => {}
|
18
|
-
# {:a => 1}.with_indifferent_access.except("a") # => {}
|
19
|
-
#
|
20
|
-
def except(*keys)
|
21
|
-
dup.except!(*keys)
|
22
|
-
end
|
23
|
-
|
24
|
-
# Replaces the hash without the given keys.
|
25
|
-
def except!(*keys)
|
26
|
-
keys.each { |key| delete(key) }
|
27
|
-
self
|
28
|
-
end
|
29
|
-
|
30
|
-
def slice(*keys)
|
31
|
-
keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
|
32
|
-
keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if key?(k) }
|
33
|
-
end
|
34
|
-
|
35
|
-
def compact
|
36
|
-
select { |_, value| !value.nil? }
|
37
|
-
end
|
38
|
-
|
39
|
-
def deep_merge(hash)
|
40
|
-
hash = hash.to_hash
|
41
|
-
merge(hash) do |_key, old_val, new_val|
|
42
|
-
if old_val.is_a?(Hash) && new_val.is_a?(Hash)
|
43
|
-
old_val.deep_merge(new_val)
|
44
|
-
else
|
45
|
-
new_val
|
5
|
+
module HashExtensions
|
6
|
+
refine Hash do
|
7
|
+
def deep_merge(hash)
|
8
|
+
hash = hash.to_hash
|
9
|
+
merge(hash) do |_key, old_val, new_val|
|
10
|
+
if old_val.is_a?(Hash) && new_val.is_a?(Hash)
|
11
|
+
old_val.deep_merge(new_val)
|
12
|
+
else
|
13
|
+
new_val
|
14
|
+
end
|
46
15
|
end
|
47
16
|
end
|
48
17
|
end
|