qonfig 0.28.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -2
  3. data/Gemfile.lock +2 -1
  4. data/README.md +23 -3
  5. data/lib/qonfig/commands/definition/expose_json.rb +20 -8
  6. data/lib/qonfig/commands/definition/expose_self.rb +15 -2
  7. data/lib/qonfig/commands/definition/expose_yaml.rb +19 -7
  8. data/lib/qonfig/commands/definition/load_from_json.rb +13 -2
  9. data/lib/qonfig/commands/definition/load_from_self.rb +13 -2
  10. data/lib/qonfig/commands/definition/load_from_yaml.rb +13 -2
  11. data/lib/qonfig/dsl.rb +31 -17
  12. data/lib/qonfig/plugins/toml/commands/definition/expose_toml.rb +19 -8
  13. data/lib/qonfig/plugins/toml/commands/definition/load_from_toml.rb +13 -3
  14. data/lib/qonfig/plugins/toml/dsl.rb +10 -7
  15. data/lib/qonfig/plugins/vault/commands/definition/expose_vault.rb +19 -8
  16. data/lib/qonfig/plugins/vault/commands/definition/load_from_vault.rb +13 -2
  17. data/lib/qonfig/plugins/vault/dsl.rb +10 -5
  18. data/lib/qonfig/settings.rb +4 -2
  19. data/lib/qonfig/version.rb +1 -1
  20. data/spec/features/expose_json_spec.rb +26 -0
  21. data/spec/features/expose_yaml_spec.rb +26 -0
  22. data/spec/features/load_from_json_spec.rb +24 -4
  23. data/spec/features/load_from_yaml_spec.rb +22 -2
  24. data/spec/features/plugins/toml/expose_toml_spec.rb +23 -0
  25. data/spec/features/plugins/toml/load_from_toml_spec.rb +28 -5
  26. data/spec/features/plugins/vault/expose_vault_spec.rb +48 -0
  27. data/spec/features/plugins/vault/load_from_vault_spec.rb +41 -0
  28. data/spec/fixtures/conflicting_settings/expose_json_1.json +9 -0
  29. data/spec/fixtures/conflicting_settings/expose_json_2.json +8 -0
  30. data/spec/fixtures/conflicting_settings/expose_yaml_1.yml +5 -0
  31. data/spec/fixtures/conflicting_settings/expose_yaml_2.yml +4 -0
  32. data/spec/fixtures/conflicting_settings/json_1.json +7 -0
  33. data/spec/fixtures/conflicting_settings/json_2.json +6 -0
  34. data/spec/fixtures/conflicting_settings/yaml_1.yml +4 -0
  35. data/spec/fixtures/conflicting_settings/yaml_2.yml +3 -0
  36. data/spec/fixtures/plugins/toml/conflicting_settings/expose_toml_1.toml +6 -0
  37. data/spec/fixtures/plugins/toml/conflicting_settings/expose_toml_2.toml +5 -0
  38. data/spec/fixtures/plugins/toml/conflicting_settings/toml_1.toml +5 -0
  39. data/spec/fixtures/plugins/toml/conflicting_settings/toml_2.toml +4 -0
  40. metadata +15 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 218eb4aa48a675227a5548f404040988e28e900d8099789ad3569adf10bdf11a
4
- data.tar.gz: b008b73ceede53055f136c686ada92be85d309ead704f1328785e5f2ae4d12f8
3
+ metadata.gz: e9b55fb2c5f21d55b75ee61a82898e5b7c00edeb28b11f652d717bbde6dbdc77
4
+ data.tar.gz: 1ed16479237bfeb2d373561c075dce564c98bac9b70380b677918450b9050e0b
5
5
  SHA512:
6
- metadata.gz: 15da249e905655b1a749fabc6b4b62cdaeb63f0ad04be8ad4e7ae1dc6ff7a949ef34c2900aa9f423abd6be1e381940c4539cc2d89a2a1ce3e4c358afc013a49c
7
- data.tar.gz: '00949bf3bb13ed5cf32d47ed6a608627828284217b6549fb4eb239562274336b99a7469ca6bc613eaebe0865d7a8c9f7a2dbe3cb90922cd8dcf19b0c5893d54d'
6
+ metadata.gz: dae870ef416e6ab02f9321c6b57a4383aa98b9fb99d82e47bef73a94d139b3c4d07b3b38c70a275d76fecae966bd254dbec33609e54f8db3fb3f02d30099e106
7
+ data.tar.gz: f593bbc8e6a4c5ced747181c10c11e061f45f4a6ac679636b98c9c9abe02d0b6d95d4eb9454211930e47c7a0f927b5a8055cfcd57e7c1820a2da1af23e6071a5
data/CHANGELOG.md CHANGED
@@ -1,11 +1,15 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
- ## [0.28.0]
4
+ ## [0.29.0] - 2024-05-06
5
+ ### Added
6
+ - `replace_on_merge` option for load_from, expose-like methods that allows to configure behaviour on the conflicting key: deep merge (by default) or replacing.
7
+
8
+ ## [0.28.0] - 2022-06-12
5
9
  ### Changed
6
10
  - Support for the new `toml-rb` release (`2.1`);
7
11
  - Updated dev-dependencies;
8
- - Adopt the code to the new rubocop cops;
12
+ - Existing code base was adopted to the new rubocop ruleset;
9
13
 
10
14
  ## [0.27.0] - 2022-01-12
11
15
  ### Changed
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- qonfig (0.27.0)
4
+ qonfig (0.29.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -123,6 +123,7 @@ GEM
123
123
 
124
124
  PLATFORMS
125
125
  arm64-darwin-21
126
+ arm64-darwin-23
126
127
 
127
128
  DEPENDENCIES
128
129
  activesupport (~> 6.0)
data/README.md CHANGED
@@ -1,8 +1,21 @@
1
- # Qonfig · [![Gem Version](https://badge.fury.io/rb/qonfig.svg)](https://badge.fury.io/rb/qonfig) [![Build Status](https://travis-ci.org/0exp/qonfig.svg?branch=master)](https://travis-ci.org/0exp/qonfig) [![Coverage Status](https://coveralls.io/repos/github/0exp/qonfig/badge.svg?branch=master)](https://coveralls.io/github/0exp/qonfig?branch=master)
1
+ # Qonfig · [![Gem Version](https://badge.fury.io/rb/qonfig.svg)](https://badge.fury.io/rb/qonfig) [![Coverage Status](https://coveralls.io/repos/github/0exp/qonfig/badge.svg?branch=master)](https://coveralls.io/github/0exp/qonfig?branch=master)
2
+
3
+ Powerful configuration Ruby-framework with a support for many commonly used config formats with a multi-functional API, developer-friendly DSL and object-oriented behavior.
4
+
5
+ - Support for: **YAML**, **TOML**, **JSON**, **ENV**, **\_\_END\_\_**-instructions;
6
+ - Fully thread-safe;
7
+ - Object-oriented behavior (config as an object, inhertance, composition, etc), with an abilities of lazy-instantiation;
8
+ - Pluggable and extendable multi-functional API;
9
+ - Developer-friendly DSL :)
10
+
11
+ ```
12
+ # in the past...:
2
13
 
3
14
  Config. Defined as a class. Used as an instance. Support for inheritance and composition.
4
- Lazy instantiation. Thread-safe. Command-style DSL. Validation layer. **Dot-notation**) And pretty-print :) Support for **YAML**, **TOML**, **JSON**, **\_\_END\_\_**, **ENV**.
15
+ Lazy instantiation. Thread-safe. Command-style DSL. Validation layer. **Dot-notation**)
16
+ And pretty-print :) Support for **YAML**, **TOML**, **JSON**, **\_\_END\_\_**, **ENV**.
5
17
  Extremely simple to define. Extremely simple to use. That's all? **Not** :)
18
+ ```
6
19
 
7
20
  ## Installation
8
21
 
@@ -2058,6 +2071,7 @@ end
2058
2071
  - `:strict` mode (fail behaviour when the required yaml file doesnt exist):
2059
2072
  - `true` (by default) - causes `Qonfig::FileNotFoundError`;
2060
2073
  - `false` - do nothing, ignore current command;
2074
+ - `:replace_on_merge` - whether the setting should be replaced on the key conflict, otherwise, it will be deep merged (default);
2061
2075
 
2062
2076
  ```yaml
2063
2077
  # travis.yml
@@ -2154,6 +2168,7 @@ Config.new.to_h # => { "nonexistent_yaml" => {}, "another_key" => nil }
2154
2168
  - `false`:
2155
2169
  - file is not required;
2156
2170
  - root key with `:env` name is not required (if `via: :env_key` is used);
2171
+ - `:replace_on_merge` - whether the setting should be replaced on the key conflict, otherwise, it will be deep merged (default);
2157
2172
 
2158
2173
  #### Environment is defined as a root key of YAML file
2159
2174
 
@@ -2244,6 +2259,7 @@ config.settings.web.password # => staging_password (from sidekiq.staging.yml)
2244
2259
  - `:strict` mode (fail behaviour when the required yaml file doesnt exist):
2245
2260
  - `true` (by default) - causes `Qonfig::FileNotFoundError`;
2246
2261
  - `false` - do nothing, ignore current command;
2262
+ - `:replace_on_merge` - whether the setting should be replaced on the key conflict, otherwise, it will be deep merged (default);
2247
2263
 
2248
2264
  ```json
2249
2265
  // options.json
@@ -2319,6 +2335,7 @@ Config.new.to_h # => { "nonexistent_json" => {}, "another_key" => nil }
2319
2335
  - `false`:
2320
2336
  - file is not required;
2321
2337
  - root key with `:env` name is not required (if `via: :env_key` is used);
2338
+ - `:replace_on_merge` - whether the setting should be replaced on the key conflict, otherwise, it will be deep merged (default);
2322
2339
 
2323
2340
  #### Environment is defined as a root key of JSON file
2324
2341
 
@@ -2489,6 +2506,7 @@ config.settings['RUN_CI'] # => '1'
2489
2506
  - `format: :yaml` - **YAML** format;
2490
2507
  - `format: :json` - **JSON** format;
2491
2508
  - `format: :toml` - **TOML** format (via `toml`-plugin);
2509
+ - `:replace_on_merge` - whether the setting should be replaced on the key conflict, otherwise, it will be deep merged (default);
2492
2510
 
2493
2511
  ```ruby
2494
2512
  class Config < Qonfig::DataSet
@@ -2537,6 +2555,7 @@ connection_timeout:
2537
2555
  - `format: :yaml` - **YAML** format;
2538
2556
  - `format: :json` - **JSON** format;
2539
2557
  - `format: :toml` - **TOML** format (via `toml`-plugin);
2558
+ - `:replace_on_merge` - whether the setting should be replaced on the key conflict, otherwise, it will be deep merged (default);
2540
2559
 
2541
2560
  ```ruby
2542
2561
  class Config < Qonfig::DataSet
@@ -3326,7 +3345,8 @@ Qonfig.plugin(:vault)
3326
3345
  - Setting value changement trace (in `anyway_config` manner);
3327
3346
  - Instantiation and reloading callbacks;
3328
3347
  - File geneartors (.rb-files with a pre-filled code (and (maybe) with a pre-generated yaml/json/etc files));
3329
-
3348
+ - Setting value changement subscriptions and callbacks;
3349
+
3330
3350
  ## Build
3331
3351
 
3332
3352
  ```shell
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.14.0
5
+ # @version 0.29.0
5
6
  class Qonfig::Commands::Definition::ExposeJSON < Qonfig::Commands::Base
6
7
  # @since 0.19.0
7
8
  self.inheritable = true
@@ -42,14 +43,22 @@ class Qonfig::Commands::Definition::ExposeJSON < Qonfig::Commands::Base
42
43
  # @since 0.14.0
43
44
  attr_reader :env
44
45
 
46
+ # @return [Boolean]
47
+ #
48
+ # @api private
49
+ # @since 0.29.0
50
+ attr_reader :replace_on_merge
51
+
45
52
  # @param file_path [String, Pathname]
46
- # @option strict [Boolean]
47
53
  # @option via [Symbol]
48
54
  # @option env [String, Symbol]
55
+ # @option strict [Boolean]
56
+ # @option replace_on_merge [Boolean]
49
57
  #
50
58
  # @api private
51
59
  # @since 0.14.0
52
- def initialize(file_path, strict: true, via:, env:)
60
+ # @version 0.29.0
61
+ def initialize(file_path, via:, env:, strict: true, replace_on_merge: false)
53
62
  unless env.is_a?(Symbol) || env.is_a?(String) || env.is_a?(Numeric)
54
63
  raise Qonfig::ArgumentError, ':env should be a string or a symbol'
55
64
  end
@@ -58,9 +67,10 @@ class Qonfig::Commands::Definition::ExposeJSON < Qonfig::Commands::Base
58
67
  raise Qonfig::ArgumentError, 'used :via is unsupported' unless EXPOSERS.key?(via)
59
68
 
60
69
  @file_path = file_path
61
- @strict = strict
62
- @via = via
63
- @env = env
70
+ @via = via
71
+ @env = env
72
+ @strict = strict
73
+ @replace_on_merge = replace_on_merge
64
74
  end
65
75
 
66
76
  # @param data_set [Qonfig::DataSet]
@@ -85,6 +95,7 @@ class Qonfig::Commands::Definition::ExposeJSON < Qonfig::Commands::Base
85
95
  #
86
96
  # @api private
87
97
  # @since 0.14.0
98
+ # @version 0.29.0
88
99
  # rubocop:disable Metrics/AbcSize
89
100
  def expose_file_name!(settings)
90
101
  # NOTE: transform file name (insert environment name into the file name)
@@ -102,7 +113,7 @@ class Qonfig::Commands::Definition::ExposeJSON < Qonfig::Commands::Base
102
113
  json_data = load_json_data(realfile)
103
114
  json_based_settings = build_data_set_klass(json_data).new.settings
104
115
 
105
- settings.__append_settings__(json_based_settings)
116
+ settings.__append_settings__(json_based_settings, with_redefinition: replace_on_merge)
106
117
  end
107
118
  # rubocop:enable Metrics/AbcSize
108
119
 
@@ -114,9 +125,10 @@ class Qonfig::Commands::Definition::ExposeJSON < Qonfig::Commands::Base
114
125
  #
115
126
  # @api private
116
127
  # @since 0.14.0
128
+ # @version 0.29.0
117
129
  # rubocop:disable Metrics/AbcSize
118
130
  def expose_env_key!(settings)
119
- json_data = load_json_data(file_path)
131
+ json_data = load_json_data(file_path)
120
132
  json_data_slice = json_data[env] || json_data[env.to_s] || json_data[env.to_sym]
121
133
  json_data_slice = EMPTY_JSON_DATA.dup if json_data_slice.nil? && !strict
122
134
 
@@ -132,7 +144,7 @@ class Qonfig::Commands::Definition::ExposeJSON < Qonfig::Commands::Base
132
144
 
133
145
  json_based_settings = build_data_set_klass(json_data_slice).new.settings
134
146
 
135
- settings.__append_settings__(json_based_settings)
147
+ settings.__append_settings__(json_based_settings, with_redefinition: replace_on_merge)
136
148
  end
137
149
  # rubocop:enable Metrics/AbcSize
138
150
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.14.0
5
+ # @version 0.29.0
5
6
  class Qonfig::Commands::Definition::ExposeSelf < Qonfig::Commands::Base
6
7
  # @since 0.19.0
7
8
  self.inheritable = true
@@ -24,13 +25,21 @@ class Qonfig::Commands::Definition::ExposeSelf < Qonfig::Commands::Base
24
25
  # @since 0.14.0
25
26
  attr_reader :env
26
27
 
28
+ # @return [Boolean]
29
+ #
30
+ # @api private
31
+ # @since 0.29.0
32
+ attr_reader :replace_on_merge
33
+
27
34
  # @param caller_location [String]
28
35
  # @option env [String, Symbol]
29
36
  # @option format [String, Symbol]
37
+ # @option replace_on_merge [Boolean]
30
38
  #
31
39
  # @api private
32
40
  # @since 0.14.0
33
- def initialize(caller_location, env:, format:)
41
+ # @version 0.29.0
42
+ def initialize(caller_location, env:, format:, replace_on_merge: false)
34
43
  unless env.is_a?(Symbol) || env.is_a?(String)
35
44
  raise Qonfig::ArgumentError, ':env should be a string or a symbol'
36
45
  end
@@ -44,6 +53,7 @@ class Qonfig::Commands::Definition::ExposeSelf < Qonfig::Commands::Base
44
53
  @caller_location = caller_location
45
54
  @env = env
46
55
  @format = format.tap { Qonfig::Loaders.resolve(format) }
56
+ @replace_on_merge = replace_on_merge
47
57
  end
48
58
 
49
59
  # @param data_set [Qonfig::DataSet]
@@ -52,6 +62,8 @@ class Qonfig::Commands::Definition::ExposeSelf < Qonfig::Commands::Base
52
62
  #
53
63
  # @api private
54
64
  # @since 0.14.0
65
+ # @version 0.29.0
66
+ # rubocop:disable Metrics/AbcSize
55
67
  def call(data_set, settings)
56
68
  self_placed_data = load_self_placed_end_data
57
69
  env_based_data_slice =
@@ -68,8 +80,9 @@ class Qonfig::Commands::Definition::ExposeSelf < Qonfig::Commands::Base
68
80
  ) unless env_based_data_slice.is_a?(Hash)
69
81
 
70
82
  self_placed_settings = build_data_set_klass(env_based_data_slice).new.settings
71
- settings.__append_settings__(self_placed_settings)
83
+ settings.__append_settings__(self_placed_settings, with_redefinition: replace_on_merge)
72
84
  end
85
+ # rubocop:enable Metrics/AbcSize
73
86
 
74
87
  private
75
88
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.7.0
5
+ # @version 0.29.0
5
6
  class Qonfig::Commands::Definition::ExposeYAML < Qonfig::Commands::Base
6
7
  # @since 0.19.0
7
8
  self.inheritable = true
@@ -42,14 +43,22 @@ class Qonfig::Commands::Definition::ExposeYAML < Qonfig::Commands::Base
42
43
  # @since 0.7.0
43
44
  attr_reader :env
44
45
 
46
+ # @return [Boolean]
47
+ #
48
+ # @api private
49
+ # @since 0.29.0
50
+ attr_reader :replace_on_merge
51
+
45
52
  # @param file_path [String, Pathname]
46
- # @option strict [Boolean]
47
53
  # @option via [Symbol]
48
54
  # @option env [String, Symbol]
55
+ # @option strict [Boolean]
56
+ # @option replace_on_merge [Boolean]
49
57
  #
50
58
  # @api private
51
59
  # @since 0.7.0
52
- def initialize(file_path, strict: true, via:, env:)
60
+ # @version 0.29.0
61
+ def initialize(file_path, via:, env:, strict: true, replace_on_merge: false)
53
62
  unless env.is_a?(Symbol) || env.is_a?(String) || env.is_a?(Numeric)
54
63
  raise Qonfig::ArgumentError, ':env should be a string or a symbol'
55
64
  end
@@ -58,9 +67,10 @@ class Qonfig::Commands::Definition::ExposeYAML < Qonfig::Commands::Base
58
67
  raise Qonfig::ArgumentError, 'used :via is unsupported' unless EXPOSERS.key?(via)
59
68
 
60
69
  @file_path = file_path
61
- @strict = strict
62
- @via = via
63
- @env = env
70
+ @strict = strict
71
+ @via = via
72
+ @env = env
73
+ @replace_on_merge = replace_on_merge
64
74
  end
65
75
 
66
76
  # @param data_set [Qonfig::DataSet]
@@ -85,6 +95,7 @@ class Qonfig::Commands::Definition::ExposeYAML < Qonfig::Commands::Base
85
95
  #
86
96
  # @api private
87
97
  # @since 0.7.0
98
+ # @version 0.29.0
88
99
  # rubocop:disable Metrics/AbcSize
89
100
  def expose_file_name!(settings)
90
101
  # NOTE: transform file name (insert environment name into the file name)
@@ -102,7 +113,7 @@ class Qonfig::Commands::Definition::ExposeYAML < Qonfig::Commands::Base
102
113
  yaml_data = load_yaml_data(realfile)
103
114
  yaml_based_settings = build_data_set_klass(yaml_data).new.settings
104
115
 
105
- settings.__append_settings__(yaml_based_settings)
116
+ settings.__append_settings__(yaml_based_settings, with_redefinition: replace_on_merge)
106
117
  end
107
118
  # rubocop:enable Metrics/AbcSize
108
119
 
@@ -114,6 +125,7 @@ class Qonfig::Commands::Definition::ExposeYAML < Qonfig::Commands::Base
114
125
  #
115
126
  # @api private
116
127
  # @since 0.7.0
128
+ # @version 0.29.0
117
129
  # rubocop:disable Metrics/AbcSize
118
130
  def expose_env_key!(settings)
119
131
  yaml_data = load_yaml_data(file_path)
@@ -132,7 +144,7 @@ class Qonfig::Commands::Definition::ExposeYAML < Qonfig::Commands::Base
132
144
 
133
145
  yaml_based_settings = build_data_set_klass(yaml_data_slice).new.settings
134
146
 
135
- settings.__append_settings__(yaml_based_settings)
147
+ settings.__append_settings__(yaml_based_settings, with_redefinition: replace_on_merge)
136
148
  end
137
149
  # rubocop:enable Metrics/AbcSize
138
150
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.5.0
5
+ # @version 0.29.0
5
6
  class Qonfig::Commands::Definition::LoadFromJSON < Qonfig::Commands::Base
6
7
  # @since 0.19.0
7
8
  self.inheritable = true
@@ -18,14 +19,23 @@ class Qonfig::Commands::Definition::LoadFromJSON < Qonfig::Commands::Base
18
19
  # @sicne 0.5.0
19
20
  attr_reader :strict
20
21
 
22
+ # @return [Boolean]
23
+ #
24
+ # @api private
25
+ # @since 0.29.0
26
+ attr_reader :replace_on_merge
27
+
21
28
  # @param file_path [String, Pathname]
22
29
  # @option strict [Boolean]
30
+ # @option replace_on_merge [Boolean]
23
31
  #
24
32
  # @api private
25
33
  # @since 0.5.0
26
- def initialize(file_path, strict: true)
34
+ # @version 0.29.0
35
+ def initialize(file_path, strict: true, replace_on_merge: false)
27
36
  @file_path = file_path
28
37
  @strict = strict
38
+ @replace_on_merge = replace_on_merge
29
39
  end
30
40
 
31
41
  # @param data_set [Qonfig::DataSet]
@@ -34,6 +44,7 @@ class Qonfig::Commands::Definition::LoadFromJSON < Qonfig::Commands::Base
34
44
  #
35
45
  # @api private
36
46
  # @since 0.5.0
47
+ # @version 0.29.0
37
48
  def call(data_set, settings)
38
49
  json_data = Qonfig::Loaders::JSON.load_file(file_path, fail_on_unexist: strict)
39
50
 
@@ -43,7 +54,7 @@ class Qonfig::Commands::Definition::LoadFromJSON < Qonfig::Commands::Base
43
54
  ) unless json_data.is_a?(Hash)
44
55
 
45
56
  json_based_settings = build_data_set_klass(json_data).new.settings
46
- settings.__append_settings__(json_based_settings)
57
+ settings.__append_settings__(json_based_settings, with_redefinition: replace_on_merge)
47
58
  end
48
59
 
49
60
  private
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.2.0
5
+ # @version 0.29.0
5
6
  class Qonfig::Commands::Definition::LoadFromSelf < Qonfig::Commands::Base
6
7
  # @since 0.19.0
7
8
  self.inheritable = true
@@ -18,18 +19,27 @@ class Qonfig::Commands::Definition::LoadFromSelf < Qonfig::Commands::Base
18
19
  # @since 0.2.0
19
20
  attr_reader :caller_location
20
21
 
22
+ # @return [Boolean]
23
+ #
24
+ # @api private
25
+ # @since 0.29.0
26
+ attr_reader :replace_on_merge
27
+
21
28
  # @param caller_location [String]
22
29
  # @option format [String, Symbol]
30
+ # @option replace_on_merge [Boolean]
23
31
  #
24
32
  # @api private
25
33
  # @since 0.2.0
26
- def initialize(caller_location, format:)
34
+ # @version 0.29.0
35
+ def initialize(caller_location, format:, replace_on_merge: false)
27
36
  unless format.is_a?(String) || format.is_a?(Symbol)
28
37
  raise Qonfig::ArgumentError, 'Format should be a symbol or a string'
29
38
  end
30
39
 
31
40
  @caller_location = caller_location
32
41
  @format = format.tap { Qonfig::Loaders.resolve(format) }
42
+ @replace_on_merge = replace_on_merge
33
43
  end
34
44
 
35
45
  # @param data_set [Qonfig::DataSet]
@@ -38,11 +48,12 @@ class Qonfig::Commands::Definition::LoadFromSelf < Qonfig::Commands::Base
38
48
  #
39
49
  # @api private
40
50
  # @since 0.2.0
51
+ # @version 0.29.0
41
52
  def call(data_set, settings)
42
53
  self_placed_end_data = load_self_placed_end_data
43
54
  self_placed_settings = build_data_set_klass(self_placed_end_data).new.settings
44
55
 
45
- settings.__append_settings__(self_placed_settings)
56
+ settings.__append_settings__(self_placed_settings, with_redefinition: replace_on_merge)
46
57
  end
47
58
 
48
59
  private
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.2.0
5
+ # @version 0.29.0
5
6
  class Qonfig::Commands::Definition::LoadFromYAML < Qonfig::Commands::Base
6
7
  # @since 0.19.0
7
8
  self.inheritable = true
@@ -18,14 +19,23 @@ class Qonfig::Commands::Definition::LoadFromYAML < Qonfig::Commands::Base
18
19
  # @since 0.2.0
19
20
  attr_reader :strict
20
21
 
22
+ # @return [Boolean]
23
+ #
24
+ # @api private
25
+ # @since 0.29.0
26
+ attr_reader :replace_on_merge
27
+
21
28
  # @param file_path [String, Pathname]
22
29
  # @option strict [Boolean]
30
+ # @option replace_on_merge [Boolean]
23
31
  #
24
32
  # @api private
25
33
  # @since 0.2.0
26
- def initialize(file_path, strict: true)
34
+ # @version 0.29.0
35
+ def initialize(file_path, strict: true, replace_on_merge: false)
27
36
  @file_path = file_path
28
37
  @strict = strict
38
+ @replace_on_merge = replace_on_merge
29
39
  end
30
40
 
31
41
  # @param data_set [Qonfig::DataSet]
@@ -36,6 +46,7 @@ class Qonfig::Commands::Definition::LoadFromYAML < Qonfig::Commands::Base
36
46
  #
37
47
  # @api private
38
48
  # @since 0.2.0
49
+ # @version 0.29.0
39
50
  def call(data_set, settings)
40
51
  yaml_data = Qonfig::Loaders::YAML.load_file(file_path, fail_on_unexist: strict)
41
52
 
@@ -45,7 +56,7 @@ class Qonfig::Commands::Definition::LoadFromYAML < Qonfig::Commands::Base
45
56
  ) unless yaml_data.is_a?(Hash)
46
57
 
47
58
  yaml_based_settings = build_data_set_klass(yaml_data).new.settings
48
- settings.__append_settings__(yaml_based_settings)
59
+ settings.__append_settings__(yaml_based_settings, with_redefinition: replace_on_merge)
49
60
  end
50
61
 
51
62
  private
data/lib/qonfig/dsl.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.1.0
5
- # @version 0.20.0
5
+ # @version 0.29.0
6
6
  module Qonfig::DSL # rubocop:disable Metrics/ModuleLength
7
7
  require_relative 'dsl/inheritance'
8
8
 
@@ -156,42 +156,47 @@ module Qonfig::DSL # rubocop:disable Metrics/ModuleLength
156
156
 
157
157
  # @param file_path [String, Pathname]
158
158
  # @option strict [Boolean]
159
+ # @option replace_on_merge [Boolean]
159
160
  # @return [void]
160
161
  #
161
162
  # @see Qonfig::Commands::Definition::LoadFromYAML
162
163
  #
163
164
  # @api public
164
165
  # @since 0.2.0
165
- def load_from_yaml(file_path, strict: true)
166
+ # @version 0.29.0
167
+ def load_from_yaml(file_path, strict: true, replace_on_merge: false)
166
168
  definition_commands << Qonfig::Commands::Definition::LoadFromYAML.new(
167
- file_path, strict: strict
169
+ file_path, strict: strict, replace_on_merge: replace_on_merge
168
170
  )
169
171
  end
170
172
 
171
173
  # @option format [Symbol, String]
174
+ # @option replace_on_merge [Boolean]
172
175
  # @return [void]
173
176
  #
174
177
  # @see Qonfig::Commands::Definition::LoadFromSelf
175
178
  #
176
179
  # @api public
177
180
  # @since 0.2.0
178
- # @version 0.21.0
179
- def load_from_self(format: :dynamic)
181
+ # @version 0.29.0
182
+ def load_from_self(format: :dynamic, replace_on_merge: false)
180
183
  caller_location = ::Kernel.caller(1, 1).first
181
184
 
182
185
  definition_commands << Qonfig::Commands::Definition::LoadFromSelf.new(
183
- caller_location, format: format
186
+ caller_location, format: format, replace_on_merge: replace_on_merge
184
187
  )
185
188
  end
186
189
 
187
190
  # @option convert_values [Boolean]
188
191
  # @option prefix [NilClass, String, Regexp]
192
+ # @option replace_on_merge [Boolean]
189
193
  # @return [void]
190
194
  #
191
195
  # @see Qonfig::Commands::Definition::LoadFromENV
192
196
  #
193
197
  # @api public
194
198
  # @since 0.2.0
199
+ # @version 0.29.0
195
200
  def load_from_env(convert_values: false, prefix: nil, trim_prefix: false)
196
201
  definition_commands << Qonfig::Commands::Definition::LoadFromENV.new(
197
202
  convert_values: convert_values,
@@ -202,62 +207,71 @@ module Qonfig::DSL # rubocop:disable Metrics/ModuleLength
202
207
 
203
208
  # @param file_path [String, Pathname]
204
209
  # @option strict [Boolean]
210
+ # @option replace_on_merge [Boolean]
205
211
  # @return [void]
206
212
  #
207
213
  # @see Qonfig::Commands::Definition::LoadFromJSON
208
214
  #
209
215
  # @api public
210
216
  # @since 0.5.0
211
- def load_from_json(file_path, strict: true)
212
- definition_commands << Qonfig::Commands::Definition::LoadFromJSON.new(file_path, strict: strict)
217
+ # @version 0.29.0
218
+ def load_from_json(file_path, strict: true, replace_on_merge: false)
219
+ definition_commands << Qonfig::Commands::Definition::LoadFromJSON.new(
220
+ file_path, strict: strict, replace_on_merge: replace_on_merge
221
+ )
213
222
  end
214
223
 
215
224
  # @param file_path [String, Pathname]
216
- # @option strict [Boolean]
217
225
  # @option via [Symbol]
218
226
  # @option env [Symbol, String]
227
+ # @option strict [Boolean]
228
+ # @option replace_on_merge [Boolean]
219
229
  # @return [void]
220
230
  #
221
231
  # @see Qonfig::Commands::Definition::ExposeYAML
222
232
  #
223
233
  # @api public
224
234
  # @since 0.7.0
225
- def expose_yaml(file_path, strict: true, via:, env:)
235
+ # @version 0.29.0
236
+ def expose_yaml(file_path, via:, env:, strict: true, replace_on_merge: false)
226
237
  definition_commands << Qonfig::Commands::Definition::ExposeYAML.new(
227
- file_path, strict: strict, via: via, env: env
238
+ file_path, via: via, env: env, strict: strict, replace_on_merge: replace_on_merge
228
239
  )
229
240
  end
230
241
 
231
242
  # @param file_path [String, Pathname]
232
- # @option strict [Boolean]
233
243
  # @option via [Symbol]
234
244
  # @option env [Symbol, String]
245
+ # @option strict [Boolean]
246
+ # @option replace_on_merge [Boolean]
235
247
  # @return [void]
236
248
  #
237
249
  # @see Qonfig::Commands::Definition::ExposeJSON
238
250
  #
239
251
  # @api public
240
252
  # @since 0.14.0
241
- def expose_json(file_path, strict: true, via:, env:)
253
+ # @version 0.29.0
254
+ def expose_json(file_path, via:, env:, strict: true, replace_on_merge: false)
242
255
  definition_commands << Qonfig::Commands::Definition::ExposeJSON.new(
243
- file_path, strict: strict, via: via, env: env
256
+ file_path, via: via, env: env, strict: strict, replace_on_merge: replace_on_merge
244
257
  )
245
258
  end
246
259
 
247
260
  # @option env [Symbol, String]
248
261
  # @option format [Symbol, String]
262
+ # @option replace_on_merge [Boolean]
249
263
  # @return [void]
250
264
  #
251
265
  # @see Qonfig::Commands::Definition::ExposeSelf
252
266
  #
253
267
  # @api public
254
268
  # @since 0.14.0
255
- # @version 0.21.0
256
- def expose_self(env:, format: :dynamic)
269
+ # @version 0.29.0
270
+ def expose_self(env:, format: :dynamic, replace_on_merge: false)
257
271
  caller_location = ::Kernel.caller(1, 1).first
258
272
 
259
273
  definition_commands << Qonfig::Commands::Definition::ExposeSelf.new(
260
- caller_location, env: env, format: format
274
+ caller_location, env: env, format: format, replace_on_merge: replace_on_merge
261
275
  )
262
276
  end
263
277