qonfig 0.19.1 → 0.20.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +168 -29
- data/lib/qonfig/commands/definition/re_define_option.rb +60 -0
- data/lib/qonfig/commands/definition.rb +1 -0
- data/lib/qonfig/data_set/class_builder.rb +2 -0
- data/lib/qonfig/data_set.rb +5 -5
- data/lib/qonfig/dsl.rb +101 -9
- data/lib/qonfig/errors.rb +14 -8
- data/lib/qonfig/plugins/toml/commands/{expose_toml.rb → definition/expose_toml.rb} +5 -1
- data/lib/qonfig/plugins/toml/commands/{load_from_toml.rb → definition/load_from_toml.rb} +5 -1
- data/lib/qonfig/plugins/toml/dsl.rb +8 -2
- data/lib/qonfig/plugins/toml.rb +2 -2
- data/lib/qonfig/settings.rb +4 -2
- data/lib/qonfig/{validator/builder → validation/building/instance_builder}/attribute_consistency.rb +14 -14
- data/lib/qonfig/{validator/builder.rb → validation/building/instance_builder.rb} +55 -30
- data/lib/qonfig/validation/building/predefined_builder.rb +86 -0
- data/lib/qonfig/validation/building.rb +8 -0
- data/lib/qonfig/{validator/collection.rb → validation/collections/instance_collection.rb} +16 -14
- data/lib/qonfig/validation/collections/predefined_registry.rb +145 -0
- data/lib/qonfig/validation/collections.rb +8 -0
- data/lib/qonfig/validation/predefinition_mixin.rb +15 -0
- data/lib/qonfig/{validator → validation/validators}/basic.rb +9 -9
- data/lib/qonfig/{validator.rb → validation/validators/composite.rb} +8 -16
- data/lib/qonfig/{validator → validation/validators}/method_based.rb +6 -6
- data/lib/qonfig/{validator/predefined/common.rb → validation/validators/predefined.rb} +7 -7
- data/lib/qonfig/{validator → validation/validators}/proc_based.rb +6 -6
- data/lib/qonfig/validation/validators.rb +11 -0
- data/lib/qonfig/validation.rb +10 -0
- data/lib/qonfig/version.rb +1 -1
- data/lib/qonfig.rb +34 -1
- data/qonfig.gemspec +1 -1
- metadata +23 -26
- data/lib/qonfig/validator/dsl.rb +0 -59
- data/lib/qonfig/validator/predefined/registry.rb +0 -81
- data/lib/qonfig/validator/predefined/registry_control_mixin.rb +0 -44
- data/lib/qonfig/validator/predefined.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0c47867d48b4170e321a53b70e527817db87b4dec1b7a4b464d352590501478
|
4
|
+
data.tar.gz: ddaa44855f051262fac8477a7ff736d43c896ade3c1c75ee4efa9a89d58ac555
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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, '
|
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, '
|
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.
|
137
|
-
config.settings.vendor_api.
|
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][:
|
149
|
-
config.settings[:vendor_api][:
|
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']['
|
155
|
-
config.settings['vendor_api']['
|
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.
|
169
|
-
config.settings['vendor_api.
|
181
|
+
config.settings['vendor_api.domain'] # => 'app.service.com'
|
182
|
+
config.settings['vendor_api.login'] # => 'test_user'
|
170
183
|
|
171
|
-
config['vendor_api.
|
172
|
-
config['vendor_api.
|
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, :
|
182
|
-
config.dig(:vendor_api, :
|
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.
|
189
|
-
config.dig('vendor_api.
|
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' => { '
|
199
|
-
config.slice(:vendor_api, :
|
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.
|
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) # => { '
|
221
|
-
config.slice_value(:vendor_api, :
|
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.
|
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' => { '
|
255
|
+
# => { 'vendor_api' => { 'login' => ..., 'domain' => ... }, 'enable_graphql' => false }
|
243
256
|
|
244
|
-
config.subset(:project_id, [:vendor_api, :
|
245
|
-
# => { 'project_id' => nil, '
|
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.
|
252
|
-
# => { 'project_id' => nil, '
|
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
|
data/lib/qonfig/data_set.rb
CHANGED
@@ -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::
|
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::
|
452
|
+
@validator = Qonfig::Validation::Validators::Composite.new(self)
|
453
453
|
end
|
454
454
|
|
455
455
|
# @param settings_map [Hash]
|