qonfig 0.18.1 → 0.19.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/.rubocop.yml +1 -0
- data/CHANGELOG.md +14 -0
- data/README.md +233 -34
- data/Rakefile +4 -2
- data/lib/qonfig/command_set.rb +14 -3
- data/lib/qonfig/commands/base.rb +37 -0
- data/lib/qonfig/commands/definition/add_nested_option.rb +3 -0
- data/lib/qonfig/commands/definition/add_option.rb +3 -0
- data/lib/qonfig/commands/definition/compose.rb +3 -0
- data/lib/qonfig/commands/definition/expose_json.rb +3 -0
- data/lib/qonfig/commands/definition/expose_self.rb +3 -0
- data/lib/qonfig/commands/definition/expose_yaml.rb +3 -0
- data/lib/qonfig/commands/definition/load_from_env.rb +3 -0
- data/lib/qonfig/commands/definition/load_from_json.rb +3 -0
- data/lib/qonfig/commands/definition/load_from_self.rb +3 -0
- data/lib/qonfig/commands/definition/load_from_yaml.rb +3 -0
- data/lib/qonfig/commands/instantiation/freeze_state.rb +18 -0
- data/lib/qonfig/commands/instantiation/values_file.rb +3 -0
- data/lib/qonfig/commands/instantiation.rb +1 -0
- data/lib/qonfig/data_set/class_builder.rb +11 -0
- data/lib/qonfig/data_set.rb +44 -16
- data/lib/qonfig/dsl.rb +10 -3
- data/lib/qonfig/errors.rb +24 -5
- data/lib/qonfig/plugins/abstract.rb +30 -1
- data/lib/qonfig/plugins/access_mixin.rb +11 -0
- data/lib/qonfig/plugins/pretty_print/data_set.rb +9 -0
- data/lib/qonfig/plugins/pretty_print/mixin.rb +24 -0
- data/lib/qonfig/plugins/pretty_print.rb +16 -0
- data/lib/qonfig/plugins/registry.rb +21 -0
- data/lib/qonfig/plugins/toml.rb +2 -2
- data/lib/qonfig/plugins.rb +15 -0
- data/lib/qonfig/settings/builder.rb +13 -2
- data/lib/qonfig/settings.rb +75 -8
- data/lib/qonfig/version.rb +1 -1
- data/lib/qonfig.rb +2 -0
- data/qonfig.gemspec +1 -1
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a79da0cb673ac91a97924b8b6c1a0a6ae193eb3e0529d784debe2b281827f130
|
4
|
+
data.tar.gz: f2280966ff22e8ef1bfbe55d62641be2c1edd0f5a7bfca208d832903f7ef85ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86521c09f933f5e8deb88fb1a8cecb59e6a050006a76a0b3b18502c900e8cbafcca6fd46bd8b6d45c2caf4e7c007cda319b267951a7a09733f9ef8f4fd22cdd3
|
7
|
+
data.tar.gz: 8d180bf77e2a3082843a3a05b5ea36f88de70997100cf829c1824515c9c6c8e23cbcf58ff8f2b908a18efee26563def86bcaf92700ee19b8402b14a0c83f7c73
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,20 @@
|
|
1
1
|
# Changelog
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## [0.19.0] - 2019-11-26
|
5
|
+
### Added
|
6
|
+
- **FINALY**: support for dot-notation in `#key?`, `#option?`, `#setting?`, `#dig`, `#subset`, `#slice`, `#slice_value`, `[]`;
|
7
|
+
- `freeze_state!` DSL directive (all your configs becomes frozen after being instantiated immediately);
|
8
|
+
- Global `Qonfig::FrozenError` error for `frozen`-based exceptions;
|
9
|
+
- explicit validation of potential setting values:
|
10
|
+
- `#valid_with?(configurations = {})` - check that current config instalce will be valid with passed configurations;
|
11
|
+
- `.valid_with?(configurations = {})` - check that potential config instancess will be valid with passed configurations;
|
12
|
+
- `#pretty_print` plugin :) (`Qonfig.plugin(:pretty_print)`);
|
13
|
+
- `Qonfig.loaded_plugins`/`Qonfig.enabled_plugins` - show loaded plugins;
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
- `Qonfig::FrozenSettingsError` now inherits `Qonfig::FrozenError` type;
|
17
|
+
|
4
18
|
## [0.18.1] - 2019-11-05
|
5
19
|
### Added
|
6
20
|
- New `yield_all:` attribute for `#deep_each_setting` method (`#deep_each_setting(yield_all: false, &block)`))
|
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# Qonfig · [](https://badge.fury.io/rb/qonfig) [](https://travis-ci.org/0exp/qonfig) [](https://coveralls.io/github/0exp/qonfig?branch=master)
|
2
2
|
|
3
3
|
Config. Defined as a class. Used as an instance. Support for inheritance and composition.
|
4
|
-
Lazy instantiation. Thread-safe. Command-style DSL. Validation layer.
|
4
|
+
Lazy instantiation. Thread-safe. Command-style DSL. Validation layer. **DOT-NOTATION**!
|
5
|
+
Support for **YAML**, **TOML**, **JSON**, **\_\_END\_\_**, **ENV**.
|
5
6
|
Extremely simple to define. Extremely simple to use. That's all? **NOT** :)
|
6
7
|
|
7
8
|
## Installation
|
@@ -47,7 +48,7 @@ require 'qonfig'
|
|
47
48
|
- [List of config keys](#list-of-config-keys) (`#keys`, `#root_keys`)
|
48
49
|
- [Config reloading](#config-reloading) (reload config definitions and option values)
|
49
50
|
- [Clear options](#clear-options) (set to `nil`)
|
50
|
-
- [
|
51
|
+
- [Frozen state](#frozen-state) (`.freeze_state!`, `#freeze!`, `#frozen?`)
|
51
52
|
- [Settings as Predicates](#settings-as-predicates)
|
52
53
|
- [Setting key existence](#setting-key-existence) (`#key?`/`#option?`/`#setting?`)
|
53
54
|
- [Run arbitrary code with temporary settings](#run-arbitrary-code-with-temporary-settings) (`#with(configs = {}, &arbitrary_code)`)
|
@@ -60,6 +61,7 @@ require 'qonfig'
|
|
60
61
|
- [Proc-based validation](#proc-based-validation)
|
61
62
|
- [Method-based validation](#method-based-validation)
|
62
63
|
- [Predefined validations](#predefined-validations)
|
64
|
+
- [Validation of potential setting values](#validation-of-potential-setting-values)
|
63
65
|
- [Work with files](#work-with-files)
|
64
66
|
- **Setting keys definition**
|
65
67
|
- [Load from YAML file](#load-from-yaml-file)
|
@@ -80,6 +82,7 @@ require 'qonfig'
|
|
80
82
|
- [Save to YAML file](#save-to-yaml-file) (`#save_to_yaml`)
|
81
83
|
- [Plugins](#plugins)
|
82
84
|
- [toml](#plugins-toml) (support for `TOML` format)
|
85
|
+
- [pretty_print](#plugins-pretty_print) (beautified/prettified console output)
|
83
86
|
- [Roadmap](#roadmap)
|
84
87
|
---
|
85
88
|
|
@@ -138,6 +141,8 @@ config.settings.enable_graphql # => false
|
|
138
141
|
|
139
142
|
#### access via index-method []
|
140
143
|
|
144
|
+
- without dot-notation:
|
145
|
+
|
141
146
|
```ruby
|
142
147
|
# get option value via index (with indifferent (string / symbol / mixed) access)
|
143
148
|
config.settings[:project_id] # => nil
|
@@ -158,16 +163,37 @@ config[:project_id] # => nil
|
|
158
163
|
config[:enable_graphql] # => false
|
159
164
|
```
|
160
165
|
|
166
|
+
- with dot-notation:
|
167
|
+
|
168
|
+
```ruby
|
169
|
+
config.settings['vendor_api.host'] # => 'app.service.com'
|
170
|
+
config.settings['vendor_api.user'] # => 'test_user'
|
171
|
+
|
172
|
+
config['vendor_api.host'] # => 'app.service.com'
|
173
|
+
config['vendor_api.user'] # => 'test_user'
|
174
|
+
```
|
175
|
+
|
161
176
|
#### .dig
|
162
177
|
|
178
|
+
- without dot-notation:
|
179
|
+
|
163
180
|
```ruby
|
164
181
|
# get option value in Hash#dig manner (and fail when the required key does not exist);
|
165
182
|
config.dig(:vendor_api, :host) # => 'app.service.com' # (key exists)
|
166
183
|
config.dig(:vendor_api, :port) # => Qonfig::UnknownSettingError # (key does not exist)
|
167
184
|
```
|
168
185
|
|
186
|
+
- with dot-notation:
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
config.dig('vendor_api.host') # => 'app.service.com' # (key exists)
|
190
|
+
config.dig('vendor_api.port') # => Qonfig::UnknownSettingError # (key does not exist)
|
191
|
+
```
|
192
|
+
|
169
193
|
#### .slice
|
170
194
|
|
195
|
+
- without dot-notation:
|
196
|
+
|
171
197
|
```ruby
|
172
198
|
# get a hash slice of setting options (and fail when the required key does not exist);
|
173
199
|
config.slice(:vendor_api) # => { 'vendor_api' => { 'host' => 'app_service', 'user' => 'test_user' } }
|
@@ -176,8 +202,18 @@ config.slice(:project_api) # => Qonfig::UnknownSettingError # (key does not exis
|
|
176
202
|
config.slice(:vendor_api, :port) # => Qonfig::UnknownSettingError # (key does not exist)
|
177
203
|
```
|
178
204
|
|
205
|
+
- with dot-notation:
|
206
|
+
|
207
|
+
```ruby
|
208
|
+
config.slice('vendor_api.user') # => { 'user' => 'test_user' }
|
209
|
+
config.slice('vendor_api.port') # => Qonfig::UnknownSettingError # (key does not exist)
|
210
|
+
```
|
211
|
+
|
212
|
+
|
179
213
|
#### .slice_value
|
180
214
|
|
215
|
+
- without dot-notaiton:
|
216
|
+
|
181
217
|
```ruby
|
182
218
|
# get value from the slice of setting options using the given key set
|
183
219
|
# (and fail when the required key does not exist) (works in slice manner);
|
@@ -188,8 +224,17 @@ config.slice_value(:project_api) # => Qonfig::UnknownSettingError # (key does no
|
|
188
224
|
config.slice_value(:vendor_api, :port) # => Qonfig::UnknownSettingError # (key does not exist)
|
189
225
|
```
|
190
226
|
|
227
|
+
- with dot-notation:
|
228
|
+
|
229
|
+
```ruby
|
230
|
+
config.slice_value('vendor_api.user') # => 'test_user'
|
231
|
+
config.slice_value('vendor_api.port') # => Qonfig::UnknownSettingError # (key does not exist)
|
232
|
+
```
|
233
|
+
|
191
234
|
#### .subset
|
192
235
|
|
236
|
+
- without dot-notation:
|
237
|
+
|
193
238
|
```ruby
|
194
239
|
# - get a subset (a set of sets) of config settings represented as a hash;
|
195
240
|
# - each key (or key set) represents a requirement of a certain setting key;
|
@@ -201,6 +246,13 @@ config.subset(:project_id, [:vendor_api, :host], [:credentials, :user, :login])
|
|
201
246
|
# => { 'project_id' => nil, 'host' => 'app.service.com', 'login' => 'D@iVeR' }
|
202
247
|
```
|
203
248
|
|
249
|
+
- with dot-notation:
|
250
|
+
|
251
|
+
```ruby
|
252
|
+
config.subset('project_id', 'vendor_api.host', 'credentials.user.login')
|
253
|
+
# => { 'project_id' => nil, 'host' => 'app.service.com', 'login' => 'D@iVeR' }
|
254
|
+
```
|
255
|
+
|
204
256
|
---
|
205
257
|
|
206
258
|
### Configuration
|
@@ -541,7 +593,7 @@ config.settings.web_api # => "api.google.com"
|
|
541
593
|
- [List of config keys](#list-of-config-keys) (`#keys`, `#root_keys`)
|
542
594
|
- [Config reloading](#config-reloading) (reload config definitions and option values)
|
543
595
|
- [Clear options](#clear-options) (set to `nil`)
|
544
|
-
- [
|
596
|
+
- [Frozen state](#frozen-state) (`.freeze_state!`, `#freeze!`, `#frozen?`)
|
545
597
|
- [Settings as Predicates](#settings-as-predicates)
|
546
598
|
- [Setting key existence](#setting-key-existence) (`#key?`/`#option?`/`#setting?`)
|
547
599
|
- [Run arbitrary code with temporary settings](#run-arbitrary-code-with-temporary-settings)
|
@@ -787,7 +839,9 @@ config.settings.web_api.endpoint # => nil
|
|
787
839
|
|
788
840
|
---
|
789
841
|
|
790
|
-
###
|
842
|
+
### Frozen state
|
843
|
+
|
844
|
+
#### Instance-level
|
791
845
|
|
792
846
|
- method signature: `#freeze!`;
|
793
847
|
|
@@ -811,6 +865,32 @@ config.reload! # => Qonfig::FrozenSettingsError
|
|
811
865
|
config.clear! # => Qonfig::FrozenSettingsError
|
812
866
|
```
|
813
867
|
|
868
|
+
#### Definition-level
|
869
|
+
|
870
|
+
- DSL-method signature: `freeze_state!`
|
871
|
+
- indicaes that all your config instances should be frozen;
|
872
|
+
- `freeze_state!` DSL command is not inherited (your child and composed config classes will not have this declaration);
|
873
|
+
|
874
|
+
```ruby
|
875
|
+
# --- base class ---
|
876
|
+
class Config < Qonfig::DataSet
|
877
|
+
setting :test, true
|
878
|
+
freeze_state!
|
879
|
+
end
|
880
|
+
|
881
|
+
config = Config.new
|
882
|
+
config.frozen? # => true
|
883
|
+
config.settings.test = false # => Qonfig::FrozenSettingsError
|
884
|
+
|
885
|
+
# --- child class ---
|
886
|
+
class InheritedConfig < Config
|
887
|
+
end
|
888
|
+
|
889
|
+
inherited_config = InheritedConfig.new
|
890
|
+
config.frozen? # => false
|
891
|
+
config.settings.test = false # ok :)
|
892
|
+
```
|
893
|
+
|
814
894
|
---
|
815
895
|
|
816
896
|
### Settings as Predicates
|
@@ -1100,7 +1180,7 @@ service.config_account # => NoMethodError
|
|
1100
1180
|
# NOTE: export settings as access methods to config's settings
|
1101
1181
|
config.export(service, 'web_api.credentials.account', prefix: 'config_')
|
1102
1182
|
|
1103
|
-
service.
|
1183
|
+
service.config_account # => { "login" => "D@iVeR", "auth_token" => "IAdkoa0@()1239uA" }
|
1104
1184
|
```
|
1105
1185
|
|
1106
1186
|
---
|
@@ -1112,6 +1192,7 @@ service.account # => { "login" => "D@iVeR", "auth_token" => "IAdkoa0@()1239uA" }
|
|
1112
1192
|
- [Proc-based validation](#proc-based-validation)
|
1113
1193
|
- [Method-based validation](#method-based-validation)
|
1114
1194
|
- [Predefined validations](#predefined-validations)
|
1195
|
+
- [Validation of potential setting values](#validation-of-potential-setting-values)
|
1115
1196
|
|
1116
1197
|
---
|
1117
1198
|
|
@@ -1133,11 +1214,12 @@ If you want to check the config object completely you can define a custom valida
|
|
1133
1214
|
- `strict: true` does not ignores validations for settings with `nil`;
|
1134
1215
|
- `strict: false` is used by default;
|
1135
1216
|
- provides special [key search pattern](#key-search-pattern) for matching setting key names;
|
1217
|
+
- you can validate potential setting values without any assignment ([documentation](#validation-of-potential-setting-values))
|
1136
1218
|
- uses the [key search pattern](#key-search-pattern) for definging what the setting key should be validated;
|
1137
1219
|
- you can define your own custom validation logic and validate dataset instance completely;
|
1138
1220
|
- validation logic should return **truthy** or **falsy** value;
|
1139
|
-
- supprots two validation techniques (**proc-based** ([
|
1140
|
-
- **proc-based** (`setting validation`) ([
|
1221
|
+
- supprots two validation techniques (**proc-based** ([documentation](#proc-based-validation)) and **dataset-method-based** ([documentation](#method-based-validation))):
|
1222
|
+
- **proc-based** (`setting validation`) ([documentation](#proc-based-validation))
|
1141
1223
|
```ruby
|
1142
1224
|
validate('db.user', strict: true) do |value|
|
1143
1225
|
value.is_a?(String)
|
@@ -1149,7 +1231,7 @@ If you want to check the config object completely you can define a custom valida
|
|
1149
1231
|
settings.user == User[1]
|
1150
1232
|
end
|
1151
1233
|
```
|
1152
|
-
- **dataset-method-based** (`setting validation`) ([
|
1234
|
+
- **dataset-method-based** (`setting validation`) ([documentation](#method-based-validation))
|
1153
1235
|
```ruby
|
1154
1236
|
validate 'db.user', by: :check_user, strict: true
|
1155
1237
|
|
@@ -1157,7 +1239,7 @@ If you want to check the config object completely you can define a custom valida
|
|
1157
1239
|
value.is_a?(String)
|
1158
1240
|
end
|
1159
1241
|
```
|
1160
|
-
- **dataset-method-based** (`dataset validation`) ([
|
1242
|
+
- **dataset-method-based** (`dataset validation`) ([documentation](#method-based-validation))
|
1161
1243
|
```ruby
|
1162
1244
|
validate by: :check_config, strict: false
|
1163
1245
|
|
@@ -1165,24 +1247,9 @@ If you want to check the config object completely you can define a custom valida
|
|
1165
1247
|
settings.user == User[1]
|
1166
1248
|
end
|
1167
1249
|
```
|
1168
|
-
- provides a **set of standard validations** ([
|
1250
|
+
- provides a **set of standard validations** ([documentation](#predefined-validations)):
|
1169
1251
|
- DSL: `validate 'key.pattern', :predefned_validator`;
|
1170
1252
|
- supports `strict` behavior;
|
1171
|
-
- realized validators:
|
1172
|
-
- `integer`
|
1173
|
-
- `float`
|
1174
|
-
- `numeric`
|
1175
|
-
- `big_decimal`
|
1176
|
-
- `boolean`
|
1177
|
-
- `string`
|
1178
|
-
- `symbol`
|
1179
|
-
- `text` (string or symbol)
|
1180
|
-
- `array`
|
1181
|
-
- `hash`
|
1182
|
-
- `proc`
|
1183
|
-
- `class`
|
1184
|
-
- `module`
|
1185
|
-
- `not_nil`
|
1186
1253
|
|
1187
1254
|
---
|
1188
1255
|
|
@@ -1399,6 +1466,52 @@ config.settings.ignorance = nil # => Qonfig::ValidationError (cant be nil)
|
|
1399
1466
|
|
1400
1467
|
---
|
1401
1468
|
|
1469
|
+
### Validation of potential setting values
|
1470
|
+
|
1471
|
+
- (**instance-level**) `#valid_with?(configurations = {})` - check that current config instalce will be valid with passed configurations;
|
1472
|
+
- (**class-level**) `.valid_with?(configurations = {})` - check that potential config instancess will be valid with passed configurations;
|
1473
|
+
- makes no assignments;
|
1474
|
+
|
1475
|
+
#### #valid_with? (instance-level)
|
1476
|
+
|
1477
|
+
```ruby
|
1478
|
+
class Config < Qonfig::DataSet
|
1479
|
+
setting :enabled, false
|
1480
|
+
setting :queue do
|
1481
|
+
setting :adapter, 'sidekiq'
|
1482
|
+
end
|
1483
|
+
|
1484
|
+
validate :enabled, :boolean
|
1485
|
+
validate 'queue.adapter', :string
|
1486
|
+
end
|
1487
|
+
|
1488
|
+
config = Config.new
|
1489
|
+
|
1490
|
+
config.valid_with?(enabled: true, queue: { adapter: 'que' }) # => true
|
1491
|
+
config.valid_with?(enabled: 123) # => false (should be a type of boolean)
|
1492
|
+
config.valid_with?(enabled: true, queue: { adapter: Sidekiq }) # => false (queue.adapter should be a type of string)
|
1493
|
+
```
|
1494
|
+
|
1495
|
+
#### .valid_with? (class-level)
|
1496
|
+
|
1497
|
+
```ruby
|
1498
|
+
class Config < Qonfig::DataSet
|
1499
|
+
setting :enabled, false
|
1500
|
+
setting :queue do
|
1501
|
+
setting :adapter, 'sidekiq'
|
1502
|
+
end
|
1503
|
+
|
1504
|
+
validate :enabled, :boolean
|
1505
|
+
validate 'queue.adapter', :string
|
1506
|
+
end
|
1507
|
+
|
1508
|
+
Config.valid_with?(enabled: true, queue: { adapter: 'que' }) # => true
|
1509
|
+
Config.valid_with?(enabled: 123) # => false (should be a type of boolean)
|
1510
|
+
Config.valid_with?(enabled: true, queue: { adapter: Sidekiq }) # => false (queue.adapter should be a type of string)
|
1511
|
+
```
|
1512
|
+
|
1513
|
+
---
|
1514
|
+
|
1402
1515
|
## Work with files
|
1403
1516
|
|
1404
1517
|
- **Setting keys definition**
|
@@ -2519,17 +2632,36 @@ dynamic: 10
|
|
2519
2632
|
|
2520
2633
|
### Plugins
|
2521
2634
|
|
2635
|
+
- [toml](#plugins-toml) (provides `load_from_toml`, `save_to_toml`, `expose_toml`);
|
2636
|
+
- [pretty_print](#plugins-pretty_print) (beautified/prettified console output);
|
2637
|
+
|
2638
|
+
---
|
2639
|
+
|
2640
|
+
#### Usage
|
2641
|
+
|
2642
|
+
- show available plugins:
|
2643
|
+
|
2522
2644
|
```ruby
|
2523
|
-
#
|
2524
|
-
|
2645
|
+
Qonfig.plugins # => ["pretty_print", "toml", ..., ...]
|
2646
|
+
```
|
2647
|
+
|
2648
|
+
- load specific plugin:
|
2525
2649
|
|
2526
|
-
|
2527
|
-
Qonfig.plugin(:
|
2650
|
+
```ruby
|
2651
|
+
Qonfig.plugin(:pretty_print) # or Qonfig.plugin('pretty_print')
|
2652
|
+
# -- or --
|
2653
|
+
Qonfig.enable(:pretty_print) # or Qonfig.enable('pretty_print')
|
2654
|
+
# -- or --
|
2655
|
+
Qonfig.load(:pretty_print) # or Qonfig.load('pretty_print')
|
2528
2656
|
```
|
2529
2657
|
|
2530
|
-
|
2658
|
+
- show load plugins:
|
2531
2659
|
|
2532
|
-
|
2660
|
+
```ruby
|
2661
|
+
Qonfig.loaded_plugins # => ["pretty_print"]
|
2662
|
+
# -- or --
|
2663
|
+
Qonfig.enabled_plugins # => ["pretty_print"]
|
2664
|
+
```
|
2533
2665
|
|
2534
2666
|
---
|
2535
2667
|
|
@@ -2551,8 +2683,77 @@ require 'toml-rb'
|
|
2551
2683
|
# 2) enable plugin
|
2552
2684
|
Qonfig.plugin(:toml)
|
2553
2685
|
|
2554
|
-
# 3) use :)
|
2686
|
+
# 3) use toml :)
|
2555
2687
|
```
|
2688
|
+
|
2689
|
+
---
|
2690
|
+
|
2691
|
+
### Plugins: pretty_print
|
2692
|
+
|
2693
|
+
- `Qonfig.plugin(:pretty_print)`
|
2694
|
+
- gives you really comfortable and beautiful console output;
|
2695
|
+
- represents all setting keys in dot-notation format;
|
2696
|
+
|
2697
|
+
#### Example:
|
2698
|
+
|
2699
|
+
```ruby
|
2700
|
+
class Config < Qonfig::DataSet
|
2701
|
+
setting :api do
|
2702
|
+
setting :domain, 'google.ru'
|
2703
|
+
setting :creds do
|
2704
|
+
setting :account, 'D@iVeR'
|
2705
|
+
setting :password, 'test123'
|
2706
|
+
end
|
2707
|
+
end
|
2708
|
+
|
2709
|
+
setting :log_requests, true
|
2710
|
+
setting :use_proxy, true
|
2711
|
+
end
|
2712
|
+
|
2713
|
+
config = Config.new
|
2714
|
+
```
|
2715
|
+
|
2716
|
+
- before:
|
2717
|
+
|
2718
|
+
```shell
|
2719
|
+
=> #<Config:0x00007f9b6c01dab0
|
2720
|
+
@__lock__=
|
2721
|
+
#<Qonfig::DataSet::Lock:0x00007f9b6c01da60
|
2722
|
+
@access_lock=#<Thread::Mutex:0x00007f9b6c01da38>,
|
2723
|
+
@arbitary_lock=#<Thread::Mutex:0x00007f9b6c01d9e8>,
|
2724
|
+
@definition_lock=#<Thread::Mutex:0x00007f9b6c01da10>>,
|
2725
|
+
@settings=
|
2726
|
+
#<Qonfig::Settings:0x00007f9b6c01d858
|
2727
|
+
@__lock__=
|
2728
|
+
#<Qonfig::Settings::Lock:0x00007f9b6c01d808
|
2729
|
+
@access_lock=#<Thread::Mutex:0x00007f9b6c01d7b8>,
|
2730
|
+
@definition_lock=#<Thread::Mutex:0x00007f9b6c01d7e0>,
|
2731
|
+
@merge_lock=#<Thread::Mutex:0x00007f9b6c01d790>>,
|
2732
|
+
@__mutation_callbacks__=
|
2733
|
+
#<Qonfig::Settings::Callbacks:0x00007f9b6c01d8d0
|
2734
|
+
@callbacks=[#<Proc:0x00007f9b6c01d8f8@/Users/daiver/Projects/qonfig/lib/qonfig/settings/builder.rb:39>],
|
2735
|
+
@lock=#<Thread::Mutex:0x00007f9b6c01d880>>,
|
2736
|
+
@__options__=
|
2737
|
+
{"api"=>
|
2738
|
+
#<Qonfig::Settings:0x00007f9b6c01d498
|
2739
|
+
# ... and etc
|
2740
|
+
```
|
2741
|
+
|
2742
|
+
- after:
|
2743
|
+
|
2744
|
+
```shell
|
2745
|
+
=> #<Config:0x00007f9b6c01dab0
|
2746
|
+
api.domain: "google.ru",
|
2747
|
+
api.creds.account: "D@iVeR",
|
2748
|
+
api.creds.password: "test123",
|
2749
|
+
log_requests: true,
|
2750
|
+
use_proxy: true>
|
2751
|
+
|
2752
|
+
# -- or --
|
2753
|
+
|
2754
|
+
=> #<Config:0x00007f9b6c01dab0 api.domain: "google.ru", api.creds.account: "D@iVeR", api.creds.password: "test123", log_requests: true, use_proxy: true>
|
2755
|
+
```
|
2756
|
+
|
2556
2757
|
---
|
2557
2758
|
|
2558
2759
|
## Roadmap
|
@@ -2565,8 +2766,6 @@ Qonfig.plugin(:toml)
|
|
2565
2766
|
- Rails reload plugin;
|
2566
2767
|
- **Minor**:
|
2567
2768
|
- custom global (and class-level) validators (with a special Validator Definition DSL);
|
2568
|
-
- support for "dot notation" in `#key?`, `#option?`, `#setting?`, `#dig`, `#subset`, `#slice`, `#slice_value`;
|
2569
|
-
- pretty print :)));
|
2570
2769
|
|
2571
2770
|
## Contributing
|
2572
2771
|
|
data/Rakefile
CHANGED
@@ -3,16 +3,18 @@
|
|
3
3
|
require 'bundler/gem_tasks'
|
4
4
|
require 'rspec/core/rake_task'
|
5
5
|
require 'rubocop'
|
6
|
-
require 'rubocop-
|
6
|
+
require 'rubocop-rails'
|
7
7
|
require 'rubocop-performance'
|
8
|
+
require 'rubocop-rspec'
|
9
|
+
require 'rubocop-rake'
|
8
10
|
require 'rubocop/rake_task'
|
9
11
|
|
10
12
|
RuboCop::RakeTask.new(:rubocop) do |t|
|
11
13
|
config_path = File.expand_path(File.join('.rubocop.yml'), __dir__)
|
12
|
-
|
13
14
|
t.options = ['--config', config_path]
|
14
15
|
t.requires << 'rubocop-rspec'
|
15
16
|
t.requires << 'rubocop-performance'
|
17
|
+
t.requires << 'rubocop-rake'
|
16
18
|
end
|
17
19
|
|
18
20
|
RSpec::Core::RakeTask.new(:rspec)
|
data/lib/qonfig/command_set.rb
CHANGED
@@ -42,12 +42,22 @@ class Qonfig::CommandSet
|
|
42
42
|
end
|
43
43
|
|
44
44
|
# @param command_set [Qonfig::CommandSet]
|
45
|
+
# @param concat_condition [Block]
|
46
|
+
# @yield [command]
|
47
|
+
# @yieldparam command [Qonfig::Commands::Base]
|
45
48
|
# @return [void]
|
46
49
|
#
|
47
50
|
# @api private
|
48
51
|
# @since 0.1.0
|
49
|
-
|
50
|
-
|
52
|
+
# @version 0.19.0
|
53
|
+
def concat(command_set, &concant_condition)
|
54
|
+
thread_safe do
|
55
|
+
if block_given?
|
56
|
+
command_set.each { |command| (commands << command) if yield(command) }
|
57
|
+
else
|
58
|
+
command_set.each { |command| commands << command }
|
59
|
+
end
|
60
|
+
end
|
51
61
|
end
|
52
62
|
|
53
63
|
# @return [Qonfig::CommandSet]
|
@@ -67,7 +77,8 @@ class Qonfig::CommandSet
|
|
67
77
|
#
|
68
78
|
# @api private
|
69
79
|
# @since 0.2.0
|
80
|
+
# @version 0.19.0
|
70
81
|
def thread_safe(&block)
|
71
|
-
@access_lock.synchronize(&block)
|
82
|
+
@access_lock.owned? ? yield : @access_lock.synchronize(&block)
|
72
83
|
end
|
73
84
|
end
|
data/lib/qonfig/commands/base.rb
CHANGED
@@ -3,6 +3,35 @@
|
|
3
3
|
# @api private
|
4
4
|
# @since 0.1.0
|
5
5
|
class Qonfig::Commands::Base
|
6
|
+
class << self
|
7
|
+
# @param identifier [Boolean]
|
8
|
+
# @return [Boolean]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.19.0
|
12
|
+
def inheritable=(identifier)
|
13
|
+
@inheritable = identifier
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Boolean]
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
# @since 0.19.0
|
20
|
+
def inheritable?
|
21
|
+
@inheritable
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param child_klass [Class]
|
25
|
+
# @return [Boolean]
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
# @since 0.19.0
|
29
|
+
def inherited(child_klass)
|
30
|
+
child_klass.instance_variable_set(:@inheritable, true)
|
31
|
+
super
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
6
35
|
# @param data_set [Qonfig::DataSet]
|
7
36
|
# @param settings [Qonfig::Settings]
|
8
37
|
# @return [void]
|
@@ -10,4 +39,12 @@ class Qonfig::Commands::Base
|
|
10
39
|
# @api private
|
11
40
|
# @since 0.1.0
|
12
41
|
def call(data_set, settings); end
|
42
|
+
|
43
|
+
# @return [Boolean]
|
44
|
+
#
|
45
|
+
# @api private
|
46
|
+
# @since 0.19.0
|
47
|
+
def inheritable?
|
48
|
+
self.class.inheritable?
|
49
|
+
end
|
13
50
|
end
|