qonfig 0.12.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +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 · [![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.
|
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
|