qonfig 0.19.1 → 0.20.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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +168 -29
  4. data/lib/qonfig/commands/definition/re_define_option.rb +60 -0
  5. data/lib/qonfig/commands/definition.rb +1 -0
  6. data/lib/qonfig/data_set/class_builder.rb +2 -0
  7. data/lib/qonfig/data_set.rb +5 -5
  8. data/lib/qonfig/dsl.rb +101 -9
  9. data/lib/qonfig/errors.rb +14 -8
  10. data/lib/qonfig/plugins/toml/commands/{expose_toml.rb → definition/expose_toml.rb} +5 -1
  11. data/lib/qonfig/plugins/toml/commands/{load_from_toml.rb → definition/load_from_toml.rb} +5 -1
  12. data/lib/qonfig/plugins/toml/dsl.rb +8 -2
  13. data/lib/qonfig/plugins/toml.rb +2 -2
  14. data/lib/qonfig/settings.rb +4 -2
  15. data/lib/qonfig/{validator/builder → validation/building/instance_builder}/attribute_consistency.rb +14 -14
  16. data/lib/qonfig/{validator/builder.rb → validation/building/instance_builder.rb} +55 -30
  17. data/lib/qonfig/validation/building/predefined_builder.rb +86 -0
  18. data/lib/qonfig/validation/building.rb +8 -0
  19. data/lib/qonfig/{validator/collection.rb → validation/collections/instance_collection.rb} +16 -14
  20. data/lib/qonfig/validation/collections/predefined_registry.rb +145 -0
  21. data/lib/qonfig/validation/collections.rb +8 -0
  22. data/lib/qonfig/validation/predefinition_mixin.rb +15 -0
  23. data/lib/qonfig/{validator → validation/validators}/basic.rb +9 -9
  24. data/lib/qonfig/{validator.rb → validation/validators/composite.rb} +8 -16
  25. data/lib/qonfig/{validator → validation/validators}/method_based.rb +6 -6
  26. data/lib/qonfig/{validator/predefined/common.rb → validation/validators/predefined.rb} +7 -7
  27. data/lib/qonfig/{validator → validation/validators}/proc_based.rb +6 -6
  28. data/lib/qonfig/validation/validators.rb +11 -0
  29. data/lib/qonfig/validation.rb +10 -0
  30. data/lib/qonfig/version.rb +1 -1
  31. data/lib/qonfig.rb +34 -1
  32. data/qonfig.gemspec +1 -1
  33. metadata +23 -26
  34. data/lib/qonfig/validator/dsl.rb +0 -59
  35. data/lib/qonfig/validator/predefined/registry.rb +0 -81
  36. data/lib/qonfig/validator/predefined/registry_control_mixin.rb +0 -44
  37. data/lib/qonfig/validator/predefined.rb +0 -41
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dab3b453c59fc8f9431ddeb3e0fb3cccd067947bf2275e94d2b75f8862e66c70
4
- data.tar.gz: 7fb3387c500b3d9f738710ed5db17b3d594fffef048b06895498b8710b224257
3
+ metadata.gz: c0c47867d48b4170e321a53b70e527817db87b4dec1b7a4b464d352590501478
4
+ data.tar.gz: ddaa44855f051262fac8477a7ff736d43c896ade3c1c75ee4efa9a89d58ac555
5
5
  SHA512:
6
- metadata.gz: 8317ded309d56239bbf763a4e72f6b0364981f6a2c87831f0dab396f9c9c2de61b8a062ec22f45b58a942731f46f0d171983e0f25cce2d07e2291f98049d8987
7
- data.tar.gz: a06e95e78176a44c7de83548ee5e57f614442ecca6a42b681429cd26f4ef0489cf89ddfec716bf59b96bbd30d7a044a718a020bb9db98fcd5ee8d6f9a9629b86
6
+ metadata.gz: 220ba3ccc61ce56a09ef245b07c36a8a7e695688e57e98039882ecb8917fa83bca7fe5e075fd5b68d671639a04d7fe92ad600587c9a20717296675c6ecb8053b
7
+ data.tar.gz: 05cf1fcac1bdff9c4414530ab1561057b52cfc0903fd64c1af0962b49bd91702e662d2f0467494862ad0bda633842a05e3665d68a91fe61316760c97adbf8a31
data/CHANGELOG.md CHANGED
@@ -1,6 +1,11 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [0.20.0] - 2019-12-01
5
+ ### Added
6
+ - Extended **Validation API**: you can define your own predefined validators via `.define_validator(name, &validation)` directive;
7
+ - `re_setting` - a special DSL command method that fully redefines existing settings (redefines existing settings instead of reopening them);
8
+
4
9
  ## [0.19.1] - 2019-11-29
5
10
  ### Changed
6
11
  - Support for Ruby 2.3 has ended.
data/README.md CHANGED
@@ -60,6 +60,7 @@ require 'qonfig'
60
60
  - [Proc-based validation](#proc-based-validation)
61
61
  - [Method-based validation](#method-based-validation)
62
62
  - [Predefined validations](#predefined-validations)
63
+ - [Custom predefined validators](#custom-predefined-validators)
63
64
  - [Validation of potential setting values](#validation-of-potential-setting-values)
64
65
  - [Work with files](#work-with-files)
65
66
  - **Setting keys definition**
@@ -98,6 +99,12 @@ require 'qonfig'
98
99
 
99
100
  ### Definition and Access
100
101
 
102
+ - `setting(name, value)` - define setting with corresponding name and value;
103
+ - `setting(name) { setting(name, value); ... }` - define nested settings OR reopen existing nested setting and define some new nested settings;
104
+ - `re_setting(name, value)`, `re_setting(name) { ... }` - re-define existing setting (or define new if the original does not exist);
105
+ - accessing: [access via method](#access-via-method), [access via index-method \[\]](#access-via-index-method-),
106
+ [.dig](#dig), [.slice](#slice), [.slice_value](#slice_value), [.subset](#subset);
107
+
101
108
  ```ruby
102
109
  # --- definition ---
103
110
  class Config < Qonfig::DataSet
@@ -106,14 +113,20 @@ class Config < Qonfig::DataSet
106
113
 
107
114
  # nested setting
108
115
  setting :vendor_api do
109
- setting :host, 'app.service.com'
116
+ setting :host, 'vendor.service.com'
110
117
  end
111
118
 
112
119
  setting :enable_graphql, false
113
120
 
114
121
  # nested setting reopening
115
122
  setting :vendor_api do
116
- setting :user, 'test_user'
123
+ setting :user, 'simple_user'
124
+ end
125
+
126
+ # re-definition of existing setting (drop the old - make the new)
127
+ re_setting :vendor_api do
128
+ setting :domain, 'api.service.com'
129
+ setting :login, 'test_user'
117
130
  end
118
131
 
119
132
  # deep nesting
@@ -133,8 +146,8 @@ config = Config.new # your configuration object instance
133
146
  ```ruby
134
147
  # get option value via method
135
148
  config.settings.project_id # => nil
136
- config.settings.vendor_api.host # => 'app.service.com'
137
- config.settings.vendor_api.user # => 'test_user'
149
+ config.settings.vendor_api.domain # => 'app.service.com'
150
+ config.settings.vendor_api.login # => 'test_user'
138
151
  config.settings.enable_graphql # => false
139
152
  ```
140
153
 
@@ -145,14 +158,14 @@ config.settings.enable_graphql # => false
145
158
  ```ruby
146
159
  # get option value via index (with indifferent (string / symbol / mixed) access)
147
160
  config.settings[:project_id] # => nil
148
- config.settings[:vendor_api][:host] # => 'app.service.com'
149
- config.settings[:vendor_api][:user] # => 'test_user'
161
+ config.settings[:vendor_api][:domain] # => 'app.service.com'
162
+ config.settings[:vendor_api][:login] # => 'test_user'
150
163
  config.settings[:enable_graphql] # => false
151
164
 
152
165
  # get option value via index (with indifferent (string / symbol / mixed) access)
153
166
  config.settings['project_id'] # => nil
154
- config.settings['vendor_api']['host'] # => 'app.service.com'
155
- config.settings['vendor_api']['user'] # => 'test_user'
167
+ config.settings['vendor_api']['domain'] # => 'app.service.com'
168
+ config.settings['vendor_api']['login'] # => 'test_user'
156
169
  config.settings['enable_graphql'] # => false
157
170
 
158
171
  # get option value directly via index (with indifferent access)
@@ -165,11 +178,11 @@ config[:enable_graphql] # => false
165
178
  - with dot-notation:
166
179
 
167
180
  ```ruby
168
- config.settings['vendor_api.host'] # => 'app.service.com'
169
- config.settings['vendor_api.user'] # => 'test_user'
181
+ config.settings['vendor_api.domain'] # => 'app.service.com'
182
+ config.settings['vendor_api.login'] # => 'test_user'
170
183
 
171
- config['vendor_api.host'] # => 'app.service.com'
172
- config['vendor_api.user'] # => 'test_user'
184
+ config['vendor_api.domain'] # => 'app.service.com'
185
+ config['vendor_api.login'] # => 'test_user'
173
186
  ```
174
187
 
175
188
  #### .dig
@@ -178,15 +191,15 @@ config['vendor_api.user'] # => 'test_user'
178
191
 
179
192
  ```ruby
180
193
  # get option value in Hash#dig manner (and fail when the required key does not exist);
181
- config.dig(:vendor_api, :host) # => 'app.service.com' # (key exists)
182
- config.dig(:vendor_api, :port) # => Qonfig::UnknownSettingError # (key does not exist)
194
+ config.dig(:vendor_api, :domain) # => 'app.service.com' # (key exists)
195
+ config.dig(:vendor_api, :login) # => Qonfig::UnknownSettingError # (key does not exist)
183
196
  ```
184
197
 
185
198
  - with dot-notation:
186
199
 
187
200
  ```ruby
188
- config.dig('vendor_api.host') # => 'app.service.com' # (key exists)
189
- config.dig('vendor_api.port') # => Qonfig::UnknownSettingError # (key does not exist)
201
+ config.dig('vendor_api.domain') # => 'app.service.com' # (key exists)
202
+ config.dig('vendor_api.login') # => Qonfig::UnknownSettingError # (key does not exist)
190
203
  ```
191
204
 
192
205
  #### .slice
@@ -195,8 +208,8 @@ config.dig('vendor_api.port') # => Qonfig::UnknownSettingError # (key does not e
195
208
 
196
209
  ```ruby
197
210
  # get a hash slice of setting options (and fail when the required key does not exist);
198
- config.slice(:vendor_api) # => { 'vendor_api' => { 'host' => 'app_service', 'user' => 'test_user' } }
199
- config.slice(:vendor_api, :user) # => { 'user' => 'test_user' }
211
+ config.slice(:vendor_api) # => { 'vendor_api' => { 'domain' => 'app_service', 'login' => 'test_user' } }
212
+ config.slice(:vendor_api, :login) # => { 'login' => 'test_user' }
200
213
  config.slice(:project_api) # => Qonfig::UnknownSettingError # (key does not exist)
201
214
  config.slice(:vendor_api, :port) # => Qonfig::UnknownSettingError # (key does not exist)
202
215
  ```
@@ -204,7 +217,7 @@ config.slice(:vendor_api, :port) # => Qonfig::UnknownSettingError # (key does no
204
217
  - with dot-notation:
205
218
 
206
219
  ```ruby
207
- config.slice('vendor_api.user') # => { 'user' => 'test_user' }
220
+ config.slice('vendor_api.login') # => { 'loign' => 'test_user' }
208
221
  config.slice('vendor_api.port') # => Qonfig::UnknownSettingError # (key does not exist)
209
222
  ```
210
223
 
@@ -217,8 +230,8 @@ config.slice('vendor_api.port') # => Qonfig::UnknownSettingError # (key does not
217
230
  # get value from the slice of setting options using the given key set
218
231
  # (and fail when the required key does not exist) (works in slice manner);
219
232
 
220
- config.slice_value(:vendor_api) # => { 'host' => 'app_service', 'user' => 'test_user' }
221
- config.slice_value(:vendor_api, :user) # => 'test_user'
233
+ config.slice_value(:vendor_api) # => { 'domain' => 'app_service', 'login' => 'test_user' }
234
+ config.slice_value(:vendor_api, :login) # => 'test_user'
222
235
  config.slice_value(:project_api) # => Qonfig::UnknownSettingError # (key does not exist)
223
236
  config.slice_value(:vendor_api, :port) # => Qonfig::UnknownSettingError # (key does not exist)
224
237
  ```
@@ -226,7 +239,7 @@ config.slice_value(:vendor_api, :port) # => Qonfig::UnknownSettingError # (key d
226
239
  - with dot-notation:
227
240
 
228
241
  ```ruby
229
- config.slice_value('vendor_api.user') # => 'test_user'
242
+ config.slice_value('vendor_api.login') # => 'test_user'
230
243
  config.slice_value('vendor_api.port') # => Qonfig::UnknownSettingError # (key does not exist)
231
244
  ```
232
245
 
@@ -239,17 +252,17 @@ config.slice_value('vendor_api.port') # => Qonfig::UnknownSettingError # (key do
239
252
  # - each key (or key set) represents a requirement of a certain setting key;
240
253
 
241
254
  config.subet(:vendor_api, :enable_graphql)
242
- # => { 'vendor_api' => { 'user' => ..., 'host' => ... }, 'enable_graphql' => false }
255
+ # => { 'vendor_api' => { 'login' => ..., 'domain' => ... }, 'enable_graphql' => false }
243
256
 
244
- config.subset(:project_id, [:vendor_api, :host], [:credentials, :user, :login])
245
- # => { 'project_id' => nil, 'host' => 'app.service.com', 'login' => 'D@iVeR' }
257
+ config.subset(:project_id, [:vendor_api, :domain], [:credentials, :user, :login])
258
+ # => { 'project_id' => nil, 'domain' => 'app.service.com', 'login' => 'D@iVeR' }
246
259
  ```
247
260
 
248
261
  - with dot-notation:
249
262
 
250
263
  ```ruby
251
- config.subset('project_id', 'vendor_api.host', 'credentials.user.login')
252
- # => { 'project_id' => nil, 'host' => 'app.service.com', 'login' => 'D@iVeR' }
264
+ config.subset('project_id', 'vendor_api.domain', 'credentials.user.login')
265
+ # => { 'project_id' => nil, 'domain' => 'app.service.com', 'login' => 'D@iVeR' }
253
266
  ```
254
267
 
255
268
  ---
@@ -1024,6 +1037,19 @@ Sometimes the nesting of configs in your project is quite high, and it makes you
1024
1037
  such code by methods or variables. In order to make developer's life easer `Qonfig` provides a special Import API simplifies the config importing
1025
1038
  (gives you `.import_settings` DSL) and gives an ability to instant config setting export from a config object (gives you `#export_settings` config's method).
1026
1039
 
1040
+ You can use RabbitMQ-like pattern matching in setting key names:
1041
+ - if the setting key name at the current nesting level does not matter - use `*`;
1042
+ - if both the setting key name and nesting level does not matter - use `#`
1043
+ - examples:
1044
+ - `db.settings.user` - matches to `db.settings.user` setting;
1045
+ - `db.settings.*` - matches to all setting keys inside `db.settings` group of settings;
1046
+ - `db.*.user` - matches to all `user` setting keys at the first level of `db` group of settings;
1047
+ - `#.user` - matches to all `user` setting keys;
1048
+ - `service.#.password` - matches to all `password` setting keys at all levels of `service` group of settings;
1049
+ - `#` - matches to ALL setting keys;
1050
+ - `*` - matches to all setting keys at the root level;
1051
+ - and etc;
1052
+
1027
1053
  ---
1028
1054
 
1029
1055
  ### Import config settings
@@ -1055,6 +1081,8 @@ AppConfig = Qonfig::DataSet.build do
1055
1081
  end
1056
1082
  end
1057
1083
  end
1084
+
1085
+ setting :graphql_api, false
1058
1086
  end
1059
1087
  ```
1060
1088
 
@@ -1153,6 +1181,47 @@ service = ServiceObject.new
1153
1181
  service.credentials # => { "account" => { "login" => "D@iVeR", "auth_token" => "IAdkoa0@()1239uA"} }
1154
1182
  ```
1155
1183
 
1184
+ #### Immport with pattern-matching
1185
+
1186
+ - import root keys only: `import_settings(config_object, '*')`;
1187
+ - import all keys: `import_settings(config_object, '#')`;
1188
+ - import the subset of keys: `import_settings(config_object, 'group.*.group.#')` (pattern-mathcing usage);
1189
+
1190
+ ```ruby
1191
+ class ServiceObject
1192
+ include Qonfig::Imports
1193
+
1194
+ # import all settings from web_api.credentials subset
1195
+ import_settings(AppConfig, 'web_api.credentials.#')
1196
+ # generated instance methods:
1197
+ # => service.account
1198
+ # => service.login
1199
+ # => service.auth_token
1200
+
1201
+ # import only the root keys from web_api.credentials.account subset
1202
+ import_settings(AppConfig, 'web_api.credentials.account.*')
1203
+ # generated instance methods:
1204
+ # => service.login
1205
+ # => service.auth_token
1206
+
1207
+ # import only the root keys
1208
+ import_settings(AppConfig, '*')
1209
+ # generated instance methods:
1210
+ # => service.web_api
1211
+ # => service.graphql_api
1212
+
1213
+ # import ALL keys
1214
+ import_Settings(AppConfig, '#')
1215
+ # generated instance methods:
1216
+ # => service.web_api
1217
+ # => service.credentials
1218
+ # => service.account
1219
+ # => service.login
1220
+ # => service.auth_token
1221
+ # => service.graphql_api
1222
+ end
1223
+ ```
1224
+
1156
1225
  ---
1157
1226
 
1158
1227
  ### Export config settings
@@ -1179,6 +1248,8 @@ class Config < Qonfig::DataSet
1179
1248
  end
1180
1249
  end
1181
1250
  end
1251
+
1252
+ setting :graphql_api, false
1182
1253
  end
1183
1254
 
1184
1255
  class ServiceObject; end
@@ -1192,6 +1263,12 @@ service.config_account # => NoMethodError
1192
1263
  config.export_settings(service, 'web_api.credentials.account', prefix: 'config_')
1193
1264
 
1194
1265
  service.config_account # => { "login" => "D@iVeR", "auth_token" => "IAdkoa0@()1239uA" }
1266
+
1267
+ # NOTE: export settings with pattern matching
1268
+ config.export_settings(service, '*') # export root settings
1269
+
1270
+ service.web_api # => { 'credentials' => { 'account' => { ... } }, 'graphql_api' => false }
1271
+ service.graphql_api # => false
1195
1272
  ```
1196
1273
 
1197
1274
  ---
@@ -1203,6 +1280,7 @@ service.config_account # => { "login" => "D@iVeR", "auth_token" => "IAdkoa0@()12
1203
1280
  - [Proc-based validation](#proc-based-validation)
1204
1281
  - [Method-based validation](#method-based-validation)
1205
1282
  - [Predefined validations](#predefined-validations)
1283
+ - [Custom predefined validators](#custom-predefined-validators)
1206
1284
  - [Validation of potential setting values](#validation-of-potential-setting-values)
1207
1285
 
1208
1286
  ---
@@ -1224,7 +1302,7 @@ If you want to check the config object completely you can define a custom valida
1224
1302
  - `strict: false` ignores validations for settings with `nil` (allows `nil` value);
1225
1303
  - `strict: true` does not ignores validations for settings with `nil`;
1226
1304
  - `strict: false` is used by default;
1227
- - provides special [key search pattern](#key-search-pattern) for matching setting key names;
1305
+ - provides a special [key search pattern](#key-search-pattern) for matching setting key names;
1228
1306
  - you can validate potential setting values without any assignment ([documentation](#validation-of-potential-setting-values))
1229
1307
  - uses the [key search pattern](#key-search-pattern) for definging what the setting key should be validated;
1230
1308
  - you can define your own custom validation logic and validate dataset instance completely;
@@ -1261,6 +1339,7 @@ If you want to check the config object completely you can define a custom valida
1261
1339
  - provides a **set of standard validations** ([documentation](#predefined-validations)):
1262
1340
  - DSL: `validate 'key.pattern', :predefned_validator`;
1263
1341
  - supports `strict` behavior;
1342
+ - you can define your own predefined validators (class-related and global-related) ([documentation](#custom-predefined-validators));
1264
1343
 
1265
1344
  ---
1266
1345
 
@@ -1477,6 +1556,67 @@ config.settings.ignorance = nil # => Qonfig::ValidationError (cant be nil)
1477
1556
 
1478
1557
  ---
1479
1558
 
1559
+ ### Custom predefined validators
1560
+
1561
+ - DSL: `.define_validator(name, &validation) { |value| ... }` - create your own predefined validator;
1562
+ - **class-level**: define validators related only to the concrete config class;
1563
+ - **global-level**: define validators related to all config classes (`Qonfig::DataSet.define_validator`);
1564
+ - you can re-define any global and inherited validator (at class level);
1565
+ - you can re-define any already registered global validator on `Qonfig::DataSet` (at global-level);
1566
+
1567
+ #### Define your own class-level validator
1568
+
1569
+ ```ruby
1570
+ class Config < Qonfig::DataSet
1571
+ # NOTE: definition
1572
+ define_validator(:user_type) { |value| value.is_a?(User) }
1573
+
1574
+ setting :admin # some key
1575
+
1576
+ validate :admin, :user_type # NOTE: useage
1577
+ end
1578
+ ```
1579
+
1580
+ #### Defin new global validator
1581
+
1582
+ ```ruby
1583
+ Qonfig::DataSet.define_validator(:secured_value) do |value|
1584
+ value == '***'
1585
+ end
1586
+
1587
+ class Config < Qonfig::DataSet
1588
+ setting :password
1589
+ validate :password, :secured_value
1590
+ end
1591
+ ```
1592
+
1593
+ #### Re-definition of existing validators in child classes
1594
+
1595
+ ```ruby
1596
+ class Config < Qonfig::DataSet
1597
+ # NOTE: redefine existing :text validator only in Config class
1598
+ define_validator(:text) { |value| value.is_a?(String) }
1599
+
1600
+ # NOTE: some custom validator that can be redefined in child classes
1601
+ define_validator(:user) { |value| value.is_a?(User) }
1602
+ end
1603
+
1604
+ class SubConfig < Qonfig
1605
+ define_validator(:user) { |value| value.is_a?(AdminUser) } # NOTE: redefine inherited :user validator
1606
+ end
1607
+ ```
1608
+
1609
+ #### Re-definition of existing global validators
1610
+
1611
+ ```ruby
1612
+ # NOTE: redefine already existing :numeric validator
1613
+ Qonfig::DataSet.define_validator(:numeric) do |value|
1614
+ value.is_a?(Numeric) || (value.is_a?(String) && value.match?(/\A\d+\.*\d+\z/))
1615
+ end
1616
+ ```
1617
+
1618
+ ---
1619
+
1480
1620
  ### Validation of potential setting values
1481
1621
 
1482
1622
  - (**instance-level**) `#valid_with?(configurations = {})` - check that current config instalce will be valid with passed configurations;
@@ -2776,7 +2916,6 @@ config = Config.new
2776
2916
  - support for persistent data storages (we want to store configs in multiple databases and files);
2777
2917
  - Rails reload plugin;
2778
2918
  - **Minor**:
2779
- - custom global (and class-level) validators (with a special Validator Definition DSL);
2780
2919
 
2781
2920
  ## Contributing
2782
2921
 
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.20.0
5
+ class Qonfig::Commands::Definition::ReDefineOption < Qonfig::Commands::Base
6
+ # @since 0.20.0
7
+ self.inheritable = true
8
+
9
+ # @return [Symbol, String]
10
+ #
11
+ # @api private
12
+ # @since 0.20.0
13
+ attr_reader :key
14
+
15
+ # @return [Object]
16
+ #
17
+ # @api private
18
+ # @since 0.20.0
19
+ attr_reader :value
20
+
21
+ # @return [Proc, NilClass]
22
+ #
23
+ # @api private
24
+ # @since 0.20.0
25
+ attr_reader :nested_data_set_klass
26
+
27
+ # @param key [Symbol, String]
28
+ # @param value [Object]
29
+ #
30
+ # @raise [Qonfig::ArgumentError]
31
+ # @raise [Qonfig::CoreMethodIntersectionError]
32
+ #
33
+ # @api private
34
+ # @since 0.20.0
35
+ def initialize(key, value, nested_definitions)
36
+ Qonfig::Settings::KeyGuard.prevent_incomparabilities!(key)
37
+
38
+ @key = key
39
+ @value = value
40
+ @nested_data_set_klass = Class.new(Qonfig::DataSet).tap do |data_set|
41
+ data_set.instance_eval(&nested_definitions)
42
+ end if nested_definitions
43
+ end
44
+
45
+ # @param data_set [Qonfig::DataSet]
46
+ # @param settings [Qonfig::Settings]
47
+ # @return [void]
48
+ #
49
+ # @api private
50
+ # @since 0.20.0
51
+ def call(data_set, settings)
52
+ if nested_data_set_klass
53
+ nested_settings = nested_data_set_klass.new.settings
54
+ nested_settings.__mutation_callbacks__.add(settings.__mutation_callbacks__)
55
+ settings.__define_setting__(key, nested_settings, with_redefinition: true)
56
+ else
57
+ settings.__define_setting__(key, value, with_redefinition: true)
58
+ end
59
+ end
60
+ end
@@ -5,6 +5,7 @@
5
5
  module Qonfig::Commands::Definition
6
6
  require_relative 'definition/add_option'
7
7
  require_relative 'definition/add_nested_option'
8
+ require_relative 'definition/re_define_option'
8
9
  require_relative 'definition/compose'
9
10
  require_relative 'definition/load_from_yaml'
10
11
  require_relative 'definition/load_from_json'
@@ -33,6 +33,8 @@ module Qonfig::DataSet::ClassBuilder
33
33
  def inherit(base_klass:, child_klass:)
34
34
  child_klass.definition_commands.concat(base_klass.definition_commands)
35
35
  child_klass.instance_commands.concat(base_klass.instance_commands, &:inheritable?)
36
+ child_klass.predefined_validators.merge(base_klass.predefined_validators)
37
+ child_klass.validators.concat(base_klass.validators)
36
38
  end
37
39
  end
38
40
  end
@@ -7,11 +7,9 @@ class Qonfig::DataSet # rubocop:disable Metrics/ClassLength
7
7
  require_relative 'data_set/lock'
8
8
 
9
9
  # @since 0.1.0
10
+ # @version 0.20.0
10
11
  extend Qonfig::DSL
11
12
 
12
- # @since 0.13.0
13
- extend Qonfig::Validator::DSL
14
-
15
13
  class << self
16
14
  # @param base_dataset_klass [Class<Qonfig::DataSet>]
17
15
  # @param config_klass_definitions [Proc]
@@ -427,10 +425,11 @@ class Qonfig::DataSet # rubocop:disable Metrics/ClassLength
427
425
 
428
426
  private
429
427
 
430
- # @return [Qonfig::Validator]
428
+ # @return [Qonfig::Validation::Validators::Composite]
431
429
  #
432
430
  # @api private
433
431
  # @since 0.13.0
432
+ # @version 0.20.0
434
433
  attr_reader :validator
435
434
 
436
435
  # @return [void]
@@ -448,8 +447,9 @@ class Qonfig::DataSet # rubocop:disable Metrics/ClassLength
448
447
  #
449
448
  # @api private
450
449
  # @since 0.13.0
450
+ # @version 0.20.0
451
451
  def build_validator
452
- @validator = Qonfig::Validator.new(self)
452
+ @validator = Qonfig::Validation::Validators::Composite.new(self)
453
453
  end
454
454
 
455
455
  # @param settings_map [Hash]