qonfig 0.18.1 → 0.19.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 · [![Gem Version](https://badge.fury.io/rb/qonfig.svg)](https://badge.fury.io/rb/qonfig) [![Build Status](https://travis-ci.org/0exp/qonfig.svg?branch=master)](https://travis-ci.org/0exp/qonfig) [![Coverage Status](https://coveralls.io/repos/github/0exp/qonfig/badge.svg?branch=master)](https://coveralls.io/github/0exp/qonfig?branch=master)
|
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
|