qonfig 0.12.0 → 0.13.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 +8 -0
- data/README.md +457 -137
- data/lib/qonfig/command_set.rb +7 -1
- data/lib/qonfig/commands/add_nested_option.rb +3 -1
- data/lib/qonfig/commands/add_option.rb +2 -1
- data/lib/qonfig/commands/base.rb +2 -1
- data/lib/qonfig/commands/compose.rb +16 -10
- data/lib/qonfig/commands/expose_yaml.rb +2 -1
- data/lib/qonfig/commands/load_from_env.rb +2 -1
- data/lib/qonfig/commands/load_from_json.rb +2 -1
- data/lib/qonfig/commands/load_from_self.rb +2 -1
- data/lib/qonfig/commands/load_from_yaml.rb +2 -1
- data/lib/qonfig/data_set/lock.rb +46 -0
- data/lib/qonfig/data_set.rb +92 -23
- data/lib/qonfig/errors.rb +8 -0
- data/lib/qonfig/plugins/toml/commands/expose_toml.rb +2 -1
- data/lib/qonfig/plugins/toml/commands/load_from_toml.rb +2 -1
- data/lib/qonfig/settings/builder.rb +20 -4
- data/lib/qonfig/settings/callbacks.rb +43 -0
- data/lib/qonfig/settings/key_matcher.rb +175 -0
- data/lib/qonfig/settings/lock.rb +3 -3
- data/lib/qonfig/settings.rb +144 -33
- data/lib/qonfig/validator/basic.rb +53 -0
- data/lib/qonfig/validator/builder/attribute_consistency.rb +181 -0
- data/lib/qonfig/validator/builder.rb +169 -0
- data/lib/qonfig/validator/collection.rb +73 -0
- data/lib/qonfig/validator/dsl.rb +51 -0
- data/lib/qonfig/validator/method_based.rb +49 -0
- data/lib/qonfig/validator/predefined/common.rb +53 -0
- data/lib/qonfig/validator/predefined/registry.rb +83 -0
- data/lib/qonfig/validator/predefined/registry_control_mixin.rb +43 -0
- data/lib/qonfig/validator/predefined.rb +41 -0
- data/lib/qonfig/validator/proc_based.rb +53 -0
- data/lib/qonfig/validator.rb +58 -0
- data/lib/qonfig/version.rb +1 -1
- data/lib/qonfig.rb +1 -0
- data/qonfig.gemspec +1 -1
- metadata +19 -5
- data/lib/qonfig/data_set/validator.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7f383ceef309126a60c17c1383cdfd3de9445aa5978ccb80374226dfd17e83c
|
4
|
+
data.tar.gz: 6f2f868550a9822b4feb8daff758a2a91d486903f9e57726c1045725fc658e55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf030ed32f26241ebe6a8717e02e3b705d5f31e666c1096f19776c14e2db92f251e08ee12e668831a69bea51ce2fb40288791dbc4d8dfd19bc9fdd10c0505db8
|
7
|
+
data.tar.gz: 67e3f1712357a8de30e651271b8ca2dd2590af18cedd42ee57d48b86a755bfe15a0ea7ae59fea448212ae5fa798b19a12364acaa2fde588fc5778c33ef4d25c1
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
# Changelog
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## [0.13.0] - 2019-08-13
|
5
|
+
### Added
|
6
|
+
- Iteration over setting keys (`#each_setting { |key, value| }`, `#deep_each_setting { |key, value| }`);
|
7
|
+
- Brand new `Validation API`;
|
8
|
+
|
9
|
+
### Changed
|
10
|
+
- Actualized development dependencies;
|
11
|
+
|
4
12
|
## [0.12.0] - 2019-07-19
|
5
13
|
### Added
|
6
14
|
- Support for **TOML** (`.toml`) format
|
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.
|
4
|
+
Lazy instantiation. Thread-safe. Command-style DSL. Validation layer. Support for **YAML**, **TOML**, **JSON**, **\_\_END\_\_**, **ENV**.
|
5
|
+
Extremely simple to define. Extremely simple to use. That's all? **NOT** :)
|
5
6
|
|
6
7
|
## Installation
|
7
8
|
|
@@ -21,27 +22,38 @@ require 'qonfig'
|
|
21
22
|
|
22
23
|
## Usage
|
23
24
|
|
24
|
-
- [Definition
|
25
|
-
- [
|
26
|
-
- [
|
27
|
-
- [
|
28
|
-
- [
|
29
|
-
- [
|
30
|
-
- [
|
31
|
-
- [
|
32
|
-
- [
|
33
|
-
- [
|
34
|
-
- [
|
35
|
-
- [
|
36
|
-
- [
|
37
|
-
- [
|
38
|
-
- [
|
39
|
-
- [
|
40
|
-
- [
|
25
|
+
- [Definition](#definition)
|
26
|
+
- [Definition and Settings Access](#definition-and-access)
|
27
|
+
- [Configuration](#configuration)
|
28
|
+
- [Inheritance](#inheritance)
|
29
|
+
- [Composition](#composition)
|
30
|
+
- [Hash representation](#hash-representation)
|
31
|
+
- [Smart Mixin](#smart-mixin) (`Qonfig::Configurable`)
|
32
|
+
- [Interaction](#interaction)
|
33
|
+
- [Iteration over setting keys](#iteration-over-setting-keys) (`#each_setting`, `#deep_each_setting`)
|
34
|
+
- [Config reloading](#config-reloading) (reload config definitions and option values)
|
35
|
+
- [Clear options](#clear-options) (set to nil)
|
36
|
+
- [State freeze](#state-freeze)
|
37
|
+
- [Settings as Predicates](#settings-as-predicates)
|
38
|
+
- [Validation](#validation)
|
39
|
+
- [Key search pattern](#key-search-pattern)
|
40
|
+
- [Proc-based validation](#proc-based-validation)
|
41
|
+
- [Method-based validation](#method-based-validation)
|
42
|
+
- [Predefined validations](#predefined-validations)
|
43
|
+
- [Work with files](#work-with-files)
|
44
|
+
- [Load from YAML file](#load-from-yaml-file)
|
45
|
+
- [Expose YAML](#expose-yaml) (`Rails`-like environment-based YAML configs)
|
46
|
+
- [Load from JSON file](#load-from-json-file)
|
47
|
+
- [Load from ENV](#load-from-env)
|
48
|
+
- [Load from \_\_END\_\_](#load-from-__end__) (aka `load_from_self`)
|
49
|
+
- [Save to JSON file](#save-to-json-file) (`save_to_json`)
|
50
|
+
- [Save to YAML file](#save-to-yaml-file) (`save_to_yaml`)
|
41
51
|
- [Plugins](#plugins)
|
42
|
-
- [toml](#
|
52
|
+
- [toml](#plugins-toml) (provides `load_from_toml`, `save_to_toml`, `expose_toml`)
|
43
53
|
---
|
44
54
|
|
55
|
+
## Definition
|
56
|
+
|
45
57
|
### Definition and Access
|
46
58
|
|
47
59
|
```ruby
|
@@ -274,6 +286,164 @@ Config.new.to_h
|
|
274
286
|
|
275
287
|
---
|
276
288
|
|
289
|
+
### Smart Mixin
|
290
|
+
|
291
|
+
- class-level:
|
292
|
+
- `.configuration` - settings definitions;
|
293
|
+
- `.configure` - configuration;
|
294
|
+
- `.config` - config object;
|
295
|
+
- settings definitions are inheritable;
|
296
|
+
- instance-level:
|
297
|
+
- `#configure` - configuration;
|
298
|
+
- `#config` - config object;
|
299
|
+
- `#shared_config` - class-level config object;
|
300
|
+
|
301
|
+
```ruby
|
302
|
+
# --- usage ---
|
303
|
+
|
304
|
+
class Application
|
305
|
+
# make configurable
|
306
|
+
include Qonfig::Configurable
|
307
|
+
|
308
|
+
configuration do
|
309
|
+
setting :user
|
310
|
+
setting :password
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
app = Application.new
|
315
|
+
|
316
|
+
# class-level config
|
317
|
+
Application.config.settings.user # => nil
|
318
|
+
Application.config.settings.password # => nil
|
319
|
+
|
320
|
+
# instance-level config
|
321
|
+
app.config.settings.user # => nil
|
322
|
+
app.config.settings.password # => nil
|
323
|
+
|
324
|
+
# access to the class level config from an instance
|
325
|
+
app.shared_config.settings.user # => nil
|
326
|
+
app.shared_config.settings.password # => nil
|
327
|
+
|
328
|
+
# class-level configuration
|
329
|
+
Application.configure do |conf|
|
330
|
+
conf.user = '0exp'
|
331
|
+
conf.password = 'test123'
|
332
|
+
end
|
333
|
+
|
334
|
+
# instance-level configuration
|
335
|
+
app.configure do |conf|
|
336
|
+
conf.user = 'admin'
|
337
|
+
conf.password = '123test'
|
338
|
+
end
|
339
|
+
|
340
|
+
# class has own config object
|
341
|
+
Application.config.settings.user # => '0exp'
|
342
|
+
Application.config.settings.password # => 'test123'
|
343
|
+
|
344
|
+
# instance has own config object
|
345
|
+
app.config.settings.user # => 'admin'
|
346
|
+
app.config.settings.password # => '123test'
|
347
|
+
|
348
|
+
# access to the class level config from an instance
|
349
|
+
app.shared_config.settings.user # => '0exp'
|
350
|
+
app.shared_config.settings.password # => 'test123'
|
351
|
+
|
352
|
+
# and etc... (all Qonfig-related features)
|
353
|
+
```
|
354
|
+
|
355
|
+
```ruby
|
356
|
+
# --- inheritance ---
|
357
|
+
|
358
|
+
class BasicApplication
|
359
|
+
# make configurable
|
360
|
+
include Qonfig::Configurable
|
361
|
+
|
362
|
+
configuration do
|
363
|
+
setting :user
|
364
|
+
setting :pswd
|
365
|
+
end
|
366
|
+
|
367
|
+
configure do |conf|
|
368
|
+
conf.user = 'admin'
|
369
|
+
conf.pswd = 'admin'
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
class GeneralApplication < BasicApplication
|
374
|
+
# extend inherited definitions
|
375
|
+
configuration do
|
376
|
+
setting :db do
|
377
|
+
setting :adapter
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
configure do |conf|
|
382
|
+
conf.user = '0exp' # .user inherited from BasicApplication
|
383
|
+
conf.pswd = '123test' # .pswd inherited from BasicApplication
|
384
|
+
conf.db.adapter = 'pg'
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
BasicApplication.config.to_h
|
389
|
+
{ 'user' => 'admin', 'pswd' => 'admin' }
|
390
|
+
|
391
|
+
GeneralApplication.config.to_h
|
392
|
+
{ 'user' => '0exp', 'pswd' => '123test', 'db' => { 'adapter' => 'pg' } }
|
393
|
+
|
394
|
+
# and etc... (all Qonfig-related features)
|
395
|
+
```
|
396
|
+
|
397
|
+
---
|
398
|
+
|
399
|
+
|
400
|
+
## Interaction
|
401
|
+
|
402
|
+
---
|
403
|
+
|
404
|
+
### Iteration over setting keys
|
405
|
+
|
406
|
+
- `#each_setting { |key, value| }`
|
407
|
+
- iterates over the root setting keys;
|
408
|
+
- `#deep_each_setting { |key, value| }`
|
409
|
+
- iterates over all setting keys (deep inside);
|
410
|
+
- key object is represented as a string of `.`-joined keys;
|
411
|
+
|
412
|
+
```ruby
|
413
|
+
class Config < Qonfig::DataSet
|
414
|
+
setting :db do
|
415
|
+
setting :creds do
|
416
|
+
setting :user, 'D@iVeR'
|
417
|
+
setting :password, 'test123',
|
418
|
+
setting :data, test: false
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
setting :telegraf_url, 'udp://localhost:8094'
|
423
|
+
setting :telegraf_prefix, 'test'
|
424
|
+
end
|
425
|
+
|
426
|
+
config = Config.new
|
427
|
+
|
428
|
+
# 1. #each_setting
|
429
|
+
config.each_setting { |key, value| { key => value } }
|
430
|
+
# result of each step:
|
431
|
+
{ 'db' => <Qonfig::Settings:0x00007ff8> }
|
432
|
+
{ 'telegraf_url' => 'udp://localhost:8094' }
|
433
|
+
{ 'telegraf_prefix' => 'test' }
|
434
|
+
|
435
|
+
# 2. #deep_each_setting
|
436
|
+
config.deep_each_setting { |key, value| { key => value } }
|
437
|
+
# result of each step:
|
438
|
+
{ 'db.creds.user' => 'D@iveR' }
|
439
|
+
{ 'db.creds.password' => 'test123' }
|
440
|
+
{ 'db.creds.data' => { test: false } }
|
441
|
+
{ 'telegraf_url' => 'udp://localhost:8094' }
|
442
|
+
{ 'telegraf_prefix' => 'test' }
|
443
|
+
```
|
444
|
+
|
445
|
+
---
|
446
|
+
|
277
447
|
### Config reloading
|
278
448
|
|
279
449
|
```ruby
|
@@ -423,6 +593,264 @@ config.settings.database.engine.driver? # => true (true => true)
|
|
423
593
|
|
424
594
|
---
|
425
595
|
|
596
|
+
## Validation
|
597
|
+
|
598
|
+
Qonfig provides a lightweight DSL for defining validations and works in all cases when setting values are initialized or mutated.
|
599
|
+
Settings are validated as keys (matched with a [specific string pattern](#key-search-patern)).
|
600
|
+
You can validate both a set of keys and each key separately.
|
601
|
+
If you want to check the config object completely you can define a custom validation.
|
602
|
+
|
603
|
+
**Features**:
|
604
|
+
|
605
|
+
- is invoked on any mutation of any setting key
|
606
|
+
- during dataset instantiation;
|
607
|
+
- when assigning new values;
|
608
|
+
- when calling `#reload!`;
|
609
|
+
- when calling `#clear!`;
|
610
|
+
|
611
|
+
- provides special [key search pattern](#key-search-pattern) for matching setting key names;
|
612
|
+
- uses the [key search pattern](#key-search-pattern) for definging what the setting key should be validated;
|
613
|
+
- you can define your own custom validation logic and validate dataset instance completely;
|
614
|
+
- validation logic should return **truthy** or **falsy** value;
|
615
|
+
|
616
|
+
- supprots two validation techniques (**proc-based** and **dataset-method-based**)
|
617
|
+
- **proc-based** (`setting validation`)
|
618
|
+
```ruby
|
619
|
+
validate 'db.user' do |value|
|
620
|
+
value.is_a?(String)
|
621
|
+
end
|
622
|
+
```
|
623
|
+
- **proc-based** (`dataset validation`)
|
624
|
+
```ruby
|
625
|
+
validate do
|
626
|
+
settings.user == User[1]
|
627
|
+
end
|
628
|
+
```
|
629
|
+
- **dataset-method-based** (`setting validation`)
|
630
|
+
```ruby
|
631
|
+
validate 'db.user', by: :check_user
|
632
|
+
|
633
|
+
def check_user(value)
|
634
|
+
value.is_a?(String)
|
635
|
+
end
|
636
|
+
```
|
637
|
+
- **dataset-method-based** (`dataset validation`)
|
638
|
+
```ruby
|
639
|
+
validate by: :check_config
|
640
|
+
|
641
|
+
def check_config
|
642
|
+
settings.user == User[1]
|
643
|
+
end
|
644
|
+
```
|
645
|
+
|
646
|
+
- provides a set of standard validations:
|
647
|
+
- `integer`
|
648
|
+
- `float`
|
649
|
+
- `numeric`
|
650
|
+
- `big_decimal`
|
651
|
+
- `boolean`
|
652
|
+
- `string`
|
653
|
+
- `symbol`
|
654
|
+
- `text` (string or symbol)
|
655
|
+
- `array`
|
656
|
+
- `hash`
|
657
|
+
- `proc`
|
658
|
+
- `class`
|
659
|
+
- `module`
|
660
|
+
- `not_nil`
|
661
|
+
|
662
|
+
---
|
663
|
+
|
664
|
+
### Key search pattern
|
665
|
+
|
666
|
+
**Key search pattern** works according to the following rules:
|
667
|
+
|
668
|
+
- works in `RabbitMQ`-like key pattern ruleses;
|
669
|
+
- has a string format;
|
670
|
+
- nested configs are defined by a set of keys separated by `.`-symbol;
|
671
|
+
- if the setting key name at the current nesting level does not matter - use `*`;
|
672
|
+
- if both the setting key name and nesting level does not matter - use `#`
|
673
|
+
- examples:
|
674
|
+
- `db.settings.user` - matches to `db.settings.user` setting;
|
675
|
+
- `db.settings.*` - matches to all setting keys inside `db.settings` group of settings;
|
676
|
+
- `db.*.user` - matches to all `user` setting keys at the first level of `db` group of settings;
|
677
|
+
- `#.user` - matches to all `user` setting keys;
|
678
|
+
- `service.#.password` - matches to all `password` setting keys at all levels of `service` group of settings;
|
679
|
+
- `#` - matches to ALL setting keys;
|
680
|
+
- `*` - matches to all setting keys at the root level;
|
681
|
+
- and etc;
|
682
|
+
|
683
|
+
---
|
684
|
+
|
685
|
+
### Proc-based validation
|
686
|
+
|
687
|
+
- your proc should return truthy value or falsy value;
|
688
|
+
- how to validate setting keys:
|
689
|
+
- define proc with attribute: `validate 'your.setting.path' do |value|; end`
|
690
|
+
- proc will receive setting value;
|
691
|
+
- how to validate dataset instance:
|
692
|
+
- define proc without setting key pattern: `validate do; end`
|
693
|
+
|
694
|
+
```ruby
|
695
|
+
class Config < Qonfig::DataSet
|
696
|
+
setting :db do
|
697
|
+
setting :user, 'D@iVeR'
|
698
|
+
setting :password, 'test123'
|
699
|
+
end
|
700
|
+
|
701
|
+
setting :service do
|
702
|
+
setting :address, 'google.ru'
|
703
|
+
setting :protocol, 'https'
|
704
|
+
|
705
|
+
setting :creds do
|
706
|
+
seting :admin, 'D@iVeR'
|
707
|
+
end
|
708
|
+
end
|
709
|
+
|
710
|
+
setting :enabled, false
|
711
|
+
|
712
|
+
# validates:
|
713
|
+
# - db.password
|
714
|
+
validate 'db.password' do |value|
|
715
|
+
value.is_a?(String)
|
716
|
+
end
|
717
|
+
|
718
|
+
# validates:
|
719
|
+
# - service.address
|
720
|
+
# - service.protocol
|
721
|
+
# - service.creds.user
|
722
|
+
validate 'service.#' do |value|
|
723
|
+
value.is_a?(String)
|
724
|
+
end
|
725
|
+
|
726
|
+
# validates:
|
727
|
+
# - dataset instance
|
728
|
+
validate do # NOTE: no setting key pattern
|
729
|
+
settings.enabled == false
|
730
|
+
end
|
731
|
+
end
|
732
|
+
|
733
|
+
config = Config.new
|
734
|
+
config.settings.db.password = 123 # => Qonfig::ValidationError (should be a string)
|
735
|
+
config.settings.service.address = 123 # => Qonfig::ValidationError (should be a string)
|
736
|
+
config.settings.service.protocol = :http # => Qonfig::ValidationError (should be a string)
|
737
|
+
config.settings.service.creds.admin = :billikota # => Qonfig::ValidationError (should be a string)
|
738
|
+
config.settings.enabled = true # => Qonfig::ValidationError (isnt `true`)
|
739
|
+
```
|
740
|
+
|
741
|
+
---
|
742
|
+
|
743
|
+
### Method-based validation
|
744
|
+
|
745
|
+
- method should return truthy value or falsy value;
|
746
|
+
- how to validate setting keys:
|
747
|
+
- define validation: `validate 'db.*.user', by: :your_custom_method`;
|
748
|
+
- define your method with attribute: `def your_custom_method(setting_value); end`
|
749
|
+
- how to validate config instance
|
750
|
+
- define validation: `validate by: :your_custom_method`
|
751
|
+
- define your method without attributes: `def your_custom_method; end`
|
752
|
+
|
753
|
+
```ruby
|
754
|
+
class Config < Qonfig::DataSet
|
755
|
+
setting :services do
|
756
|
+
setting :counts do
|
757
|
+
setting :google, 2
|
758
|
+
setting :rambler, 3
|
759
|
+
end
|
760
|
+
|
761
|
+
setting :minimals do
|
762
|
+
setting :google, 1
|
763
|
+
setting :rambler, 0
|
764
|
+
end
|
765
|
+
end
|
766
|
+
|
767
|
+
setting :enabled, true
|
768
|
+
|
769
|
+
# validates:
|
770
|
+
# - services.counts.google
|
771
|
+
# - services.counts.rambler
|
772
|
+
# - services.minimals.google
|
773
|
+
# - services.minimals.rambler
|
774
|
+
validate 'services.#', by: :check_presence
|
775
|
+
|
776
|
+
# validates:
|
777
|
+
# - dataset instance
|
778
|
+
validate by: :check_state # NOTE: no setting key pattern
|
779
|
+
|
780
|
+
def check_presence(value)
|
781
|
+
value.is_a?(Numeric) && value > 0
|
782
|
+
end
|
783
|
+
|
784
|
+
def check_state
|
785
|
+
settings.enabled.is_a?(TrueClass) || settings.enabled.is_a?(FalseClass)
|
786
|
+
end
|
787
|
+
end
|
788
|
+
|
789
|
+
config = Config.new
|
790
|
+
|
791
|
+
config.settings.counts.google = 0 # => Qonfig::ValidationError (< 0)
|
792
|
+
config.settings.counts.rambler = nil # => Qonfig::ValidationError (should be a numeric)
|
793
|
+
config.settings.minimals.google = -1 # => Qonfig::ValidationError (< 0)
|
794
|
+
config.settings.minimals.rambler = 'no' # => Qonfig::ValidationError (should be a numeric)
|
795
|
+
config.settings.enabled = nil # => Qonfig::ValidationError (should be a boolean)
|
796
|
+
```
|
797
|
+
|
798
|
+
---
|
799
|
+
|
800
|
+
### Predefined validations
|
801
|
+
|
802
|
+
- DSL: `validate 'key.pattern', :predefned_validator`
|
803
|
+
- predefined validators:
|
804
|
+
- `:not_nil`
|
805
|
+
- `:integer`
|
806
|
+
- `:float`
|
807
|
+
- `:numeric`
|
808
|
+
- `:big_decimal`
|
809
|
+
- `:array`
|
810
|
+
- `:hash`
|
811
|
+
- `:string`
|
812
|
+
- `:symbol`
|
813
|
+
- `:text` (`string` or `symbol`)
|
814
|
+
- `:boolean`
|
815
|
+
- `:class`
|
816
|
+
- `:module`
|
817
|
+
- `:proc`
|
818
|
+
|
819
|
+
```ruby
|
820
|
+
class Config < Qonfig::DataSet
|
821
|
+
setting :user
|
822
|
+
setting :password
|
823
|
+
|
824
|
+
setting :service do
|
825
|
+
setting :provider
|
826
|
+
setting :protocol
|
827
|
+
setting :on_fail, -> { puts 'atata!' }
|
828
|
+
end
|
829
|
+
|
830
|
+
setting :ignorance, false
|
831
|
+
|
832
|
+
validate 'user', :string
|
833
|
+
validate 'password', :string
|
834
|
+
validate 'service.provider', :text
|
835
|
+
validate 'service.protocol', :text
|
836
|
+
validate 'service.on_fail', :proc
|
837
|
+
validate 'ignorance', :not_nil
|
838
|
+
end
|
839
|
+
|
840
|
+
config = Config.new do |conf|
|
841
|
+
conf.user = 'D@iVeR'
|
842
|
+
conf.password = 'test123'
|
843
|
+
conf.service.provider = :google
|
844
|
+
conf.service.protocol = :https
|
845
|
+
end # NOTE: all right :)
|
846
|
+
|
847
|
+
config.settings.ignorance = nil # => Qonfig::ValidationError (cant be nil)
|
848
|
+
```
|
849
|
+
|
850
|
+
---
|
851
|
+
|
852
|
+
## Work with files
|
853
|
+
|
426
854
|
### Load from YAML file
|
427
855
|
|
428
856
|
- supports `ERB`;
|
@@ -922,116 +1350,6 @@ dynamic: 10
|
|
922
1350
|
|
923
1351
|
---
|
924
1352
|
|
925
|
-
### Smart Mixin
|
926
|
-
|
927
|
-
- class-level:
|
928
|
-
- `.configuration` - settings definitions;
|
929
|
-
- `.configure` - configuration;
|
930
|
-
- `.config` - config object;
|
931
|
-
- settings definitions are inheritable;
|
932
|
-
- instance-level:
|
933
|
-
- `#configure` - configuration;
|
934
|
-
- `#config` - config object;
|
935
|
-
- `#shared_config` - class-level config object;
|
936
|
-
|
937
|
-
```ruby
|
938
|
-
# --- usage ---
|
939
|
-
|
940
|
-
class Application
|
941
|
-
# make configurable
|
942
|
-
include Qonfig::Configurable
|
943
|
-
|
944
|
-
configuration do
|
945
|
-
setting :user
|
946
|
-
setting :password
|
947
|
-
end
|
948
|
-
end
|
949
|
-
|
950
|
-
app = Application.new
|
951
|
-
|
952
|
-
# class-level config
|
953
|
-
Application.config.settings.user # => nil
|
954
|
-
Application.config.settings.password # => nil
|
955
|
-
|
956
|
-
# instance-level config
|
957
|
-
app.config.settings.user # => nil
|
958
|
-
app.config.settings.password # => nil
|
959
|
-
|
960
|
-
# access to the class level config from an instance
|
961
|
-
app.shared_config.settings.user # => nil
|
962
|
-
app.shared_config.settings.password # => nil
|
963
|
-
|
964
|
-
# class-level configuration
|
965
|
-
Application.configure do |conf|
|
966
|
-
conf.user = '0exp'
|
967
|
-
conf.password = 'test123'
|
968
|
-
end
|
969
|
-
|
970
|
-
# instance-level configuration
|
971
|
-
app.configure do |conf|
|
972
|
-
conf.user = 'admin'
|
973
|
-
conf.password = '123test'
|
974
|
-
end
|
975
|
-
|
976
|
-
# class has own config object
|
977
|
-
Application.config.settings.user # => '0exp'
|
978
|
-
Application.config.settings.password # => 'test123'
|
979
|
-
|
980
|
-
# instance has own config object
|
981
|
-
app.config.settings.user # => 'admin'
|
982
|
-
app.config.settings.password # => '123test'
|
983
|
-
|
984
|
-
# access to the class level config from an instance
|
985
|
-
app.shared_config.settings.user # => '0exp'
|
986
|
-
app.shared_config.settings.password # => 'test123'
|
987
|
-
|
988
|
-
# and etc... (all Qonfig-related features)
|
989
|
-
```
|
990
|
-
|
991
|
-
```ruby
|
992
|
-
# --- inheritance ---
|
993
|
-
|
994
|
-
class BasicApplication
|
995
|
-
# make configurable
|
996
|
-
include Qonfig::Configurable
|
997
|
-
|
998
|
-
configuration do
|
999
|
-
setting :user
|
1000
|
-
setting :pswd
|
1001
|
-
end
|
1002
|
-
|
1003
|
-
configure do |conf|
|
1004
|
-
conf.user = 'admin'
|
1005
|
-
conf.pswd = 'admin'
|
1006
|
-
end
|
1007
|
-
end
|
1008
|
-
|
1009
|
-
class GeneralApplication < BasicApplication
|
1010
|
-
# extend inherited definitions
|
1011
|
-
configuration do
|
1012
|
-
setting :db do
|
1013
|
-
setting :adapter
|
1014
|
-
end
|
1015
|
-
end
|
1016
|
-
|
1017
|
-
configure do |conf|
|
1018
|
-
conf.user = '0exp' # .user inherited from BasicApplication
|
1019
|
-
conf.pswd = '123test' # .pswd inherited from BasicApplication
|
1020
|
-
conf.db.adapter = 'pg'
|
1021
|
-
end
|
1022
|
-
end
|
1023
|
-
|
1024
|
-
BasicApplication.config.to_h
|
1025
|
-
{ 'user' => 'admin', 'pswd' => 'admin' }
|
1026
|
-
|
1027
|
-
GeneralApplication.config.to_h
|
1028
|
-
{ 'user' => '0exp', 'pswd' => '123test', 'db' => { 'adapter' => 'pg' } }
|
1029
|
-
|
1030
|
-
# and etc... (all Qonfig-related features)
|
1031
|
-
```
|
1032
|
-
|
1033
|
-
---
|
1034
|
-
|
1035
1353
|
### Plugins
|
1036
1354
|
|
1037
1355
|
```ruby
|
@@ -1047,23 +1365,25 @@ Qonfig.plugin(:plugin_name) # or Qonfig.plugin('plugin_name')
|
|
1047
1365
|
### Plugins: toml
|
1048
1366
|
|
1049
1367
|
- adds support for `toml` format ([specification](https://github.com/toml-lang/toml));
|
1050
|
-
- depends on `toml-rb` gem;
|
1051
|
-
-
|
1052
|
-
- provides `
|
1053
|
-
- provides `
|
1368
|
+
- depends on `toml-rb` gem ([link](https://github.com/emancu/toml-rb));
|
1369
|
+
- supports TOML `0.4.0` format (dependency lock);
|
1370
|
+
- provides `load_from_toml` (works in `load_from_yaml` manner ([doc](#load-from-yaml-file)));
|
1371
|
+
- provides `save_to_toml` (works in `save_to_yaml` manner ([doc](#save-to-yaml-file))) (`toml-rb` has no native options);
|
1372
|
+
- provides `expose_toml` (works in `expose_yaml` manner ([doc](#expose-yaml)));
|
1054
1373
|
|
1055
1374
|
```ruby
|
1375
|
+
# 1) require external dependency
|
1056
1376
|
require 'toml-rb'
|
1377
|
+
|
1378
|
+
# 2) enable plugin
|
1057
1379
|
Qonfig.plugin(:toml)
|
1058
|
-
|
1380
|
+
|
1381
|
+
# 3) use :)
|
1059
1382
|
```
|
1060
1383
|
---
|
1061
1384
|
|
1062
1385
|
## Roadmap
|
1063
1386
|
|
1064
|
-
- support for TOML format;
|
1065
|
-
- explicit "settings" object;
|
1066
|
-
- validation layer;
|
1067
1387
|
- distributed configuration server;
|
1068
1388
|
- support for Rails-like secrets;
|
1069
1389
|
|
data/lib/qonfig/command_set.rb
CHANGED
@@ -3,12 +3,18 @@
|
|
3
3
|
# @api private
|
4
4
|
# @since 0.1.0
|
5
5
|
class Qonfig::CommandSet
|
6
|
+
# @api private
|
7
|
+
# @since 0.13.0
|
8
|
+
include Enumerable
|
9
|
+
|
6
10
|
# @return [Array<Qonfig::Commands::Base>]
|
7
11
|
#
|
8
12
|
# @api private
|
9
13
|
# @since 0.1.0
|
10
14
|
attr_reader :commands
|
11
15
|
|
16
|
+
# @return [void]
|
17
|
+
#
|
12
18
|
# @api private
|
13
19
|
# @since 0.1.0
|
14
20
|
def initialize
|
@@ -57,7 +63,7 @@ class Qonfig::CommandSet
|
|
57
63
|
private
|
58
64
|
|
59
65
|
# @param block [Proc]
|
60
|
-
# @return [
|
66
|
+
# @return [Any]
|
61
67
|
#
|
62
68
|
# @api private
|
63
69
|
# @since 0.2.0
|