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.
- 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]
|