qonfig 0.20.0 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0c47867d48b4170e321a53b70e527817db87b4dec1b7a4b464d352590501478
4
- data.tar.gz: ddaa44855f051262fac8477a7ff736d43c896ade3c1c75ee4efa9a89d58ac555
3
+ metadata.gz: d8bb3c845cef4655af444f78682841a1d882176463aca7d05e6d156f64e70f38
4
+ data.tar.gz: 58e18c72976148f86eb6c9f845d976b69311ce3edbd5fe219a141accc9cec6a1
5
5
  SHA512:
6
- metadata.gz: 220ba3ccc61ce56a09ef245b07c36a8a7e695688e57e98039882ecb8917fa83bca7fe5e075fd5b68d671639a04d7fe92ad600587c9a20717296675c6ecb8053b
7
- data.tar.gz: 05cf1fcac1bdff9c4414530ab1561057b52cfc0903fd64c1af0962b49bd91702e662d2f0467494862ad0bda633842a05e3665d68a91fe61316760c97adbf8a31
6
+ metadata.gz: c201ccb87e62e2424f38784aefaae67410c1725c6c2a33f00126412f9d495c081c6b8faf4fbf52b17e9f2ae674b87b8454002eedafdf4f5209e328afe4892821
7
+ data.tar.gz: d7a6bb166580c9f8d8df2aba63cefbbc3251b2e84daf6ca9863442b585267459ba9b528327e484a86a26a4f5e031adaa911d3acfca36b3cf6d434e2aa50bd14d
data/.travis.yml CHANGED
@@ -17,6 +17,9 @@ matrix:
17
17
  - rvm: jruby-head
18
18
  gemfile: gemfiles/with_external_deps.gemfile
19
19
  env: TEST_PLUGINS=true
20
+ - rvm: truffleruby
21
+ gemfile: gemfiles/with_external_deps.gemfile
22
+ env: TEST_PLUGINS=true
20
23
  - rvm: 2.4.9
21
24
  gemfile: gemfiles/without_external_deps.gemfile
22
25
  - rvm: 2.5.7
@@ -27,9 +30,12 @@ matrix:
27
30
  gemfile: gemfiles/without_external_deps.gemfile
28
31
  - rvm: jruby-head
29
32
  gemfile: gemfiles/without_external_deps.gemfile
33
+ - rvm: truffleruby
34
+ gemfile: gemfiles/without_external_deps.gemfile
30
35
  allow_failures:
31
36
  - rvm: ruby-head
32
37
  - rvm: jruby-head
38
+ - rvm: truffleruby
33
39
  sudo: false
34
40
  cache: bundler
35
41
  before_install: gem install bundler
data/CHANGELOG.md CHANGED
@@ -1,6 +1,35 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [Unreleased]
5
+ ### Added
6
+ - Brand new type of config objects `Qonfig::Compacted`:
7
+ - represents the compacted config object with setting readers and setting writers only;
8
+ - setting keys are represented as direct instace methods (`#settings` invokation does not need);
9
+ - no any other useful instance-based functionality;
10
+ - full support of `Qonfig::DataSet` DSL commands (`setting`, `validate`, `add_validator`, `load_from_x`/`expose_x` and etc);
11
+ - can be instantiated by:
12
+ - by existing config object: `Qonfig::DataSet#compacted` or `Qonfig::Compacted.build_from(config, &configuration)`
13
+ - by direct instantiation: `Qonfig::Compacted.new(settings_values = {}, &configuration)`;
14
+ - by implicit instance building without explicit class definition `Qonfig::Compacted.build(&dsl_commands) # => instance of Qonfig::Compacted`;
15
+ - Added `Qonfig::DataSet.build_compacted` method: works in `Qonfig::DataSet.build` manner but returns compacted config object (`Qonfig::Compacted`);
16
+ - Added missing `#[]=(key, value)` accessor-method for `Qonfig::DataSet` objects;
17
+ - Added support for `do |config|` configuration block in `#load_from_self` / `#load_from_yaml` / `#load_from_json` / `#load_from_toml`
18
+ values-loading methods;
19
+ - **Plugins** `pretty_print`:
20
+ - added missing beautification logic for `Qonfig::Settings` objects;
21
+ - added support for `Qonfig::Compacted` beautification;
22
+ - `#valid_with?` now supports configuration block (`do |config|`);
23
+ - `Import API`: support for predicate methods;
24
+
25
+ ### Changed
26
+ - `.load_from_self`: default format was changed from `:yaml` to `:dynamic`;
27
+ - `.expose_self`: default format was changed from `:yaml` to `:dynamic`;
28
+ - Minor `Qonfig::DataSet` and `Qonfig::Settings::Builder` refactorings;
29
+
30
+ ### Fixed
31
+ - Configs without any setting key can not be imported and exported by generic key patterns (`*` and `#`);
32
+
4
33
  ## [0.20.0] - 2019-12-01
5
34
  ### Added
6
35
  - Extended **Validation API**: you can define your own predefined validators via `.define_validator(name, &validation)` directive;
data/README.md CHANGED
@@ -42,6 +42,17 @@ require 'qonfig'
42
42
  - [Hash representation](#hash-representation)
43
43
  - [Smart Mixin](#smart-mixin) (`Qonfig::Configurable`)
44
44
  - [Instantiation without class definition](#instantiation-without-class-definition) (`Qonfig::DataSet.build(&definitions)`)
45
+ - [Compacted config](#compacted-config)
46
+ - [Definition and instantiation](#definition-and-instantiation)
47
+ - [by raw initialization](#by-raw-initialization)
48
+ - [by existing Qonfig::DataSet class](#by-existing-qonfigdataset-class)
49
+ - [by existing Qonfig::DataSet instance](#by-existing-qonfigdataset-instance)
50
+ - [instantiation without class definition](#instantiation-without-class-definition-1)
51
+ - [validation API](#validation-api-see-full-documentation)
52
+ - [Setting readers and writers](#setting-readers-and-writers)
53
+ - [reading](#reading-by-setting-name-and-index-method-with-dot-notation-support-and-indifferent-access)
54
+ - [writing](#writing-by-setting-name-and-index-method-with-dot-notation-support-and-indifferent-access)
55
+ - [precitaes](#predicates-see-full-documentation)
45
56
  - [Interaction](#interaction)
46
57
  - [Iteration over setting keys](#iteration-over-setting-keys) (`#each_setting`, `#deep_each_setting`)
47
58
  - [List of config keys](#list-of-config-keys) (`#keys`, `#root_keys`)
@@ -53,6 +64,12 @@ require 'qonfig'
53
64
  - [Run arbitrary code with temporary settings](#run-arbitrary-code-with-temporary-settings) (`#with(configs = {}, &arbitrary_code)`)
54
65
  - [Import settings / Export settings](#import-settings--export-settings)
55
66
  - [Import config settings](#import-config-settings) (`as instance methods`)
67
+ - [Import a set of setting keys (simple dot-noated key list)](#import-a-set-of-setting-keys-simple-dot-noated-key-list)
68
+ - [Import with custom method names (mappings)](#import-with-custom-method-names-mappings)
69
+ - [Prexify method name](#prexify-method-name)
70
+ - [Import nested settings as raw Qonfig::Settings objects](#import-nested-settings-as-raw-qonfigsettings-objects)
71
+ - [Import with pattern-matching](#import-with-pattern-matching)
72
+ - [Support for predicate-like methods](#support-for-predicate-like-methods)
56
73
  - [Export config settings](#export-config-settings) (`as singleton methods`)
57
74
  - [Validation](#validation)
58
75
  - [Introduction](#introduction)
@@ -64,6 +81,7 @@ require 'qonfig'
64
81
  - [Validation of potential setting values](#validation-of-potential-setting-values)
65
82
  - [Work with files](#work-with-files)
66
83
  - **Setting keys definition**
84
+ - `(DSL methods for dynamic setting keys definition by reading them from a file)`
67
85
  - [Load from YAML file](#load-from-yaml-file)
68
86
  - [Expose YAML](#expose-yaml) (`Rails`-like environment-based YAML configs)
69
87
  - [Load from JSON file](#load-from-json-file)
@@ -72,6 +90,7 @@ require 'qonfig'
72
90
  - [Load from \_\_END\_\_](#load-from-__end__) (aka `.load_from_self`)
73
91
  - [Expose \_\_END\_\_](#expose-__end__) (aka `.expose_self`)
74
92
  - **Setting values**
93
+ - `(instance methods for loading setting values from a file to existing config object with already defined setting keys)`
75
94
  - [Default setting values file](#default-setting-values-file)
76
95
  - [Load setting values from YAML file](#load-setting-values-from-yaml-file-by-instance)
77
96
  - [Load setting values from JSON file](#load-setting-values-from-json-file-by-instance)
@@ -99,9 +118,9 @@ require 'qonfig'
99
118
 
100
119
  ### Definition and Access
101
120
 
102
- - `setting(name, value)` - define setting with corresponding name and value;
103
- - `setting(name) { setting(name, value); ... }` - define nested settings OR reopen existing nested setting and define some new nested settings;
104
- - `re_setting(name, value)`, `re_setting(name) { ... }` - re-define existing setting (or define new if the original does not exist);
121
+ - `setting(name, value = nil)` - define setting with corresponding name and value;
122
+ - `setting(name) { setting(name, value = nil); ... }` - define nested settings OR reopen existing nested setting and define some new nested settings;
123
+ - `re_setting(name, value = nil)`, `re_setting(name) { ... }` - re-define existing setting (or define new if the original does not exist);
105
124
  - accessing: [access via method](#access-via-method), [access via index-method \[\]](#access-via-index-method-),
106
125
  [.dig](#dig), [.slice](#slice), [.slice_value](#slice_value), [.subset](#subset);
107
126
 
@@ -599,6 +618,218 @@ config.settings.web_api # => "api.google.com"
599
618
 
600
619
  ---
601
620
 
621
+ ## Compacted config
622
+
623
+ - [Definition and instantiation](#definition-and-instantiation)
624
+ - [by raw initialization](#by-raw-initialization)
625
+ - [by existing Qonfig::DataSet class](#by-existing-qonfigdataset-class)
626
+ - [by existing Qonfig::DataSet instance](#by-existing-qonfigdataset-instance)
627
+ - [instantiation without class definition](#instantiation-without-class-definition-1)
628
+ - [validation API](#validation-api-see-full-documentation)
629
+ - [Setting readers and writers](#setting-readers-and-writers)
630
+ - [reading](#reading-by-setting-name-and-index-method-with-dot-notation-support-and-indifferent-access)
631
+ - [writing](#writing-by-setting-name-and-index-method-with-dot-notation-support-and-indifferent-access)
632
+ - [precitaes](#predicates-see-full-documentation)
633
+
634
+ ---
635
+
636
+ - `Qonfig::Compacted`: represents the compacted config object with setting readers and setting writers;
637
+ - setting keys are represented as direct instace methods (`#settings` invokation does not need);
638
+ - no any other useful instance-based functionality - just setting readers, setting writers and setting predicates:
639
+ - support for index-like access methods (`[]`,`[]=`);
640
+ - full support of `Qonfig::DataSet` definition DSL commands:
641
+ - `setting`, `re_setting` [doc](#definition-and-access)
642
+ - `validate`, `add_validator` [doc](#validation)
643
+ - `load_from_self` [doc](#load-from-__end__), `load_from_yaml` [doc](#load-from-yaml-file), `load_from_json` [doc](#load-from-json-file), `load_from_toml` [doc](#plugins-toml);
644
+ - `expose_self` [doc](#expose-__end__), `expose_yaml` [doc](#expose-yaml), `expose_json` [doc](#expose-json), `expose_toml` [doc](#plugins-toml)
645
+ - `values_file` [doc](#default-setting-values-file)
646
+ - support for validation of potential setting values `.valid_with?` [documentation](#validation-of-potential-setting-values);
647
+ - can be instantiated by:
648
+ - by existing config object: `Qonfig::DataSet#compacted` or `Qonfig::Compacted.build_from(config, &configuration)`;
649
+ - from existing `Qonfig::DataSet` class: ``Qonfig::DataSet.build_compacted`;
650
+ - by direct instantiation: `Qonfig::Compacted.new(settings_values = {}, &configuration)`;
651
+ - by implicit instance building without explicit class definition `Qonfig::Compacted.build(&dsl_commands) # => instance of Qonfig::Compacted`;
652
+ - you can define your own instance methods too;
653
+
654
+ ---
655
+
656
+ ### Definition and instantiation
657
+
658
+ #### by raw initialization
659
+
660
+ ```ruby
661
+ class Config < Qonfig::Compacted
662
+ setting :api, 'google.com'
663
+ setting :enabled, true
664
+ setting :queue do
665
+ setting :engine, :sidekiq
666
+ end
667
+ end
668
+
669
+ config = Config.new(api: 'yandex.ru') do |conf|
670
+ conf.enabled = false
671
+ end
672
+
673
+ config.api # => 'yandex.ru'
674
+ config.enabled # => false
675
+ config.queue.engine # => :sidekiq
676
+ ```
677
+
678
+ #### by existing Qonfig::DataSet class
679
+
680
+ ```ruby
681
+ class Config < Qonfig::DataSet
682
+ setting :api, 'google.com'
683
+ setting :enabled, true
684
+ end
685
+
686
+ config = Config.build_compacted # builds Qonfig::Compacted instance
687
+
688
+ config.api # => 'google.com'
689
+ config.enabled # => true
690
+ ```
691
+
692
+ #### by existing Qonfig::DataSet instance
693
+
694
+ - `Qonfig::DataSet#compacted`
695
+ - (or) `Qonfig::Compacted.build_from(config)`
696
+
697
+ ```ruby
698
+ class Config < Qonfig::DataSet
699
+ setting :api, 'google.com'
700
+ setting :enabled, true
701
+ end
702
+
703
+ config = Config.new
704
+
705
+ compacted_config = config.compacted
706
+ # --- or ---
707
+ compacted_config = Qonfig::Compacted.build_from(config)
708
+
709
+ compacted_config.api # => 'google.com'
710
+ compacted_config.enabled # => true
711
+ ```
712
+
713
+ #### instantiation without class definition
714
+
715
+ ```ruby
716
+ config = Qonfig::Compacted.build do
717
+ setting :api, 'google.ru'
718
+ setting :enabled, true
719
+ end
720
+
721
+ config.api # => 'google.ru'
722
+ config.enabled # => true
723
+ ```
724
+
725
+ #### validation API (see [full documentation](#validation)):
726
+
727
+ ```ruby
728
+ # custom validators
729
+ Qonfig::Compacted.define_validator(:version_check) do |value|
730
+ value.is_a?(Integer) && value < 100
731
+ end
732
+
733
+ class Config < Qonfig::Compacted
734
+ setting :api, 'google.ru'
735
+ setting :enabled, true
736
+ setting :version, 2
737
+ setting :queue { setting :engine, :sidekiq }
738
+
739
+ # full support of original validation api
740
+ validate :api, :string, strict: true
741
+ validate :enabled, :boolean, strict: true
742
+ validate :version, :version_check # custom validator
743
+ validate 'queue.#', :symbol
744
+ end
745
+
746
+ # potential values validation
747
+ Config.valid_with?(api: :yandex) # => false
748
+ Config.valid_with?(enabled: nil) # => false
749
+ Config.valid_with?(version: nil) # => false
750
+ Config.valid_with?(api: 'yandex.ru', enabled: false, version: 3) # => true
751
+
752
+ config = Config.new
753
+
754
+ # instance validation
755
+ config.api = :yandex # => Qonfig::ValidationError (should be a type of string)
756
+ config.version = nil # => Qonfig::ValidationError (can not be nil)
757
+ config.queue.engine = 'sneakers' # => Qonfig::ValidationError (should be a type of symbol)
758
+ ```
759
+
760
+ ---
761
+
762
+ ### Setting readers and writers
763
+
764
+ ```ruby
765
+ class Config < Qonfig::Compcated
766
+ setting :api, 'google.ru'
767
+ setting :enabled, true
768
+ setting :queue do
769
+ setting :engine, :sidekiq
770
+ setting :workers_count, 10
771
+ end
772
+ end
773
+
774
+ config = Config.new
775
+ ```
776
+
777
+ #### reading (by setting name and index method with dot-notation support and indifferent access)
778
+
779
+ ```ruby
780
+ # by setting name
781
+ config.api # => 'google.ru'
782
+ config.enabled # => true
783
+ config.queue.engine # => :sidekiq
784
+ config.queue.workers_count # => 10
785
+
786
+ # by index method with dot-notation support and indiffernt access
787
+ config[:api] # => 'google.ru'
788
+ config['enabled'] # => true
789
+ config[:queue][:engine] # => :sidekiq
790
+ config['queue.workers_count'] # => 10
791
+ ```
792
+
793
+ #### writing (by setting name and index method with dot-notation support and indifferent access)
794
+
795
+ ```ruby
796
+ # by setting name
797
+ config.api = 'yandex.ru'
798
+ config.queue.engine = :sidekiq
799
+ # and etc
800
+
801
+ # by index method with dot-notaiton support and indifferent access
802
+ config['api'] = 'yandex.ru'
803
+ config['queue.engine'] = :sidekiq
804
+ config[:queue][:workers_count] = 5
805
+ ```
806
+
807
+ #### predicates ([see full documentation](#settings-as-predicates))
808
+
809
+ ```ruby
810
+ class Config < Qonfig::Compcated
811
+ setting :enabled, true
812
+ setting :api, 'yandex.ru'
813
+ setting :queue do
814
+ setting :engine, :sidekiq
815
+ end
816
+ end
817
+
818
+ config = Config.new
819
+
820
+ config.enabled? # => true
821
+ config.enabled = nil
822
+ config.enabled? # => false
823
+
824
+ config.queue.engine? # => true
825
+ config.queue.engine = nil
826
+ config.queue.engine? # => false
827
+
828
+ config.queue? # => true
829
+ ```
830
+
831
+ ---
832
+
602
833
  ## Interaction
603
834
 
604
835
  - [Iteration over setting keys](#iteration-over-setting-keys) (`#each_setting`, `#deep_each_setting`)
@@ -1057,6 +1288,9 @@ You can use RabbitMQ-like pattern matching in setting key names:
1057
1288
  - `Qonfig::Imports` - a special mixin that provides the convenient DSL to work with config import features (`.import_settings` method);
1058
1289
  - `.import_settings` - DSL method for importing configuration settings (from a config instance) as instance methods of a class;
1059
1290
  - (**IMPORTANT**) `import_settings` imports config settings as access methods to config's settings (creates `attr_reader`s for your config);
1291
+ - generated methods can be used as predicates (with trailing `?` symbol);
1292
+ - you can generate `attr_accessor`s by specifying `accessor: true` option
1293
+ (be careful: you can get `Qonfig::AmbiguousSettingValueError` when you try to assign a value to config option which have nested settings);
1060
1294
  - signature: `.import_settings(config_object, *setting_keys, mappings: {}, prefix: '', raw: false)`
1061
1295
  - `config_object` - an instance of `Qonfig::DataSet` whose config settings should be imported;
1062
1296
  - `*setting_keys` - an array of dot-notaed config's setting keys that should be imported
@@ -1065,7 +1299,7 @@ You can use RabbitMQ-like pattern matching in setting key names:
1065
1299
  - `mappings:` - a map of keys that describes custom method names for each imported setting;
1066
1300
  - `prefix:` - prexifies setting access method name with custom prefix;
1067
1301
  - `raw:` - use nested settings as objects or hashify them (`false` by default (means "hashify nested settings"));
1068
-
1302
+ - `accessor:` - generate `attr_accessor` for imported config settigns (`false` by default (means "generate `attr_reader`s only"));
1069
1303
  ---
1070
1304
 
1071
1305
  Suppose we have a config with deeply nested keys:
@@ -1088,6 +1322,13 @@ end
1088
1322
 
1089
1323
  Let's see what we can to do :)
1090
1324
 
1325
+ - [Import a set of setting keys (simple dot-noated key list)](#import-a-set-of-setting-keys-simple-dot-noated-key-list)
1326
+ - [Import with custom method names (mappings)](#import-with-custom-method-names-mappings)
1327
+ - [Prexify method name](#prexify-method-name)
1328
+ - [Import nested settings as raw Qonfig::Settings objects](#import-nested-settings-as-raw-qonfigsettings-objects)
1329
+ - [Import with pattern-matching](#import-with-pattern-matching)
1330
+ - [Support for predicate-like methods](#support-for-predicate-like-methods)
1331
+
1091
1332
  #### Import a set of setting keys (simple dot-noated key list)
1092
1333
 
1093
1334
  - last part of dot-notated key will become a name of the setting access instance method;
@@ -1145,10 +1386,30 @@ end
1145
1386
 
1146
1387
  service = ServiceObject.new
1147
1388
 
1148
- service.config_credentials # => { login" => "D@iVeR", "auth_token" => "IAdkoa0@()1239uA" }
1389
+ service.config_account # => { login" => "D@iVeR", "auth_token" => "IAdkoa0@()1239uA" }
1149
1390
  service.config_secret_token # => "IAdkoa0@()1239uA"
1150
1391
  ```
1151
1392
 
1393
+ #### Support for predicate-like methods
1394
+
1395
+ - generated methods can be used as predicates (with trailing `?` symbol);
1396
+
1397
+ ```ruby
1398
+ class ServiceObject
1399
+ include Qonfig::Imports
1400
+
1401
+ import_settings(AppConfig,
1402
+ 'web_api.credentials.account',
1403
+ mappings: { secret_token: 'web_api.credentials.account.auth_token' },
1404
+ )
1405
+ end
1406
+
1407
+ service = ServiceObject.new
1408
+
1409
+ service.account? # => true
1410
+ service.secret_token? # => true
1411
+ ```
1412
+
1152
1413
  #### Import nested settings as raw Qonfig::Settings objects
1153
1414
 
1154
1415
  - `raw: false` is used by default (hashify nested settings)
@@ -1181,7 +1442,7 @@ service = ServiceObject.new
1181
1442
  service.credentials # => { "account" => { "login" => "D@iVeR", "auth_token" => "IAdkoa0@()1239uA"} }
1182
1443
  ```
1183
1444
 
1184
- #### Immport with pattern-matching
1445
+ #### Import with pattern-matching
1185
1446
 
1186
1447
  - import root keys only: `import_settings(config_object, '*')`;
1187
1448
  - import all keys: `import_settings(config_object, '#')`;
@@ -1211,7 +1472,7 @@ class ServiceObject
1211
1472
  # => service.graphql_api
1212
1473
 
1213
1474
  # import ALL keys
1214
- import_Settings(AppConfig, '#')
1475
+ import_settings(AppConfig, '#')
1215
1476
  # generated instance methods:
1216
1477
  # => service.web_api
1217
1478
  # => service.credentials
@@ -1226,8 +1487,12 @@ end
1226
1487
 
1227
1488
  ### Export config settings
1228
1489
 
1490
+ - works in `.import_settings` manner [doc](#import-config-settings) (see examples and documentation above `:)`)
1229
1491
  - all config objects can export their settings to an arbitrary object as singleton methods;
1230
1492
  - (**IMPORTANT**) `export_settings` exports config settings as access methods to config's settings (creates `attr_reader`s for your config);
1493
+ - generated methods can be used as predicates (with trailing `?` symbol);
1494
+ - you can generate `attr_accessor`s by specifying `accessor: true` option
1495
+ (be careful: you can get `Qonfig::AmbiguousSettingValueError` when you try to assign a value to config option which have nested settings);
1231
1496
  - signature: `#export_settings(exportable_object, *setting_keys, mappings: {}, prefix: '', raw: false)`:
1232
1497
  - `exportable_object` - an arbitrary object for exporting;
1233
1498
  - `*setting_keys` - an array of dot-notaed config's setting keys that should be exported
@@ -1236,7 +1501,7 @@ end
1236
1501
  - `mappings:` - a map of keys that describes custom method names for each exported setting;
1237
1502
  - `prefix:` - prexifies setting access method name with custom prefix;
1238
1503
  - `raw:` - use nested settings as objects or hashify them (`false` by default (means "hashify nested settings"));
1239
- - works in `.import_settings` manner [doc](#import-config-settings) (see examples and documentation above `:)`)
1504
+ - `accessor:` - generate `attr_accessor` for imported config settigns (`false` by default (means "generate `attr_reader`s only"));
1240
1505
 
1241
1506
  ```ruby
1242
1507
  class Config < Qonfig::DataSet
@@ -1258,12 +1523,16 @@ config = Config.new
1258
1523
  service = ServiceObject.new
1259
1524
 
1260
1525
  service.config_account # => NoMethodError
1526
+ ```
1261
1527
 
1528
+ ```ruby
1262
1529
  # NOTE: export settings as access methods to config's settings
1263
1530
  config.export_settings(service, 'web_api.credentials.account', prefix: 'config_')
1264
1531
 
1265
1532
  service.config_account # => { "login" => "D@iVeR", "auth_token" => "IAdkoa0@()1239uA" }
1533
+ ```
1266
1534
 
1535
+ ```ruby
1267
1536
  # NOTE: export settings with pattern matching
1268
1537
  config.export_settings(service, '*') # export root settings
1269
1538
 
@@ -1271,6 +1540,14 @@ service.web_api # => { 'credentials' => { 'account' => { ... } }, 'graphql_api'
1271
1540
  service.graphql_api # => false
1272
1541
  ```
1273
1542
 
1543
+ ```ruby
1544
+ # NOTE: predicates
1545
+ config.export_settings(service, '*')
1546
+
1547
+ config.web_api? # => true
1548
+ config.graphql_api? # => false
1549
+ ```
1550
+
1274
1551
  ---
1275
1552
 
1276
1553
  ## Validation
@@ -1573,11 +1850,12 @@ class Config < Qonfig::DataSet
1573
1850
 
1574
1851
  setting :admin # some key
1575
1852
 
1576
- validate :admin, :user_type # NOTE: useage
1853
+ # NOTE: usage
1854
+ validate :admin, :user_type
1577
1855
  end
1578
1856
  ```
1579
1857
 
1580
- #### Defin new global validator
1858
+ #### Define new global validator
1581
1859
 
1582
1860
  ```ruby
1583
1861
  Qonfig::DataSet.define_validator(:secured_value) do |value|
@@ -1619,8 +1897,8 @@ end
1619
1897
 
1620
1898
  ### Validation of potential setting values
1621
1899
 
1622
- - (**instance-level**) `#valid_with?(configurations = {})` - check that current config instalce will be valid with passed configurations;
1623
- - (**class-level**) `.valid_with?(configurations = {})` - check that potential config instancess will be valid with passed configurations;
1900
+ - (**instance-level**) `#valid_with?(setting_values = {}, &configuration)` - check that current config instalce will be valid with passed configurations;
1901
+ - (**class-level**) `.valid_with?(setting_values = {}, &configuration)` - check that potential config instancess will be valid with passed configurations;
1624
1902
  - makes no assignments;
1625
1903
 
1626
1904
  #### #valid_with? (instance-level)
@@ -1641,6 +1919,12 @@ config = Config.new
1641
1919
  config.valid_with?(enabled: true, queue: { adapter: 'que' }) # => true
1642
1920
  config.valid_with?(enabled: 123) # => false (should be a type of boolean)
1643
1921
  config.valid_with?(enabled: true, queue: { adapter: Sidekiq }) # => false (queue.adapter should be a type of string)
1922
+
1923
+ # do-config notation is supported too
1924
+ config.valid_with?(enabled: true) do |conf|
1925
+ conf.queue.adapter = :sidekiq
1926
+ end
1927
+ # => false (queue.adapter should be a type of string)
1644
1928
  ```
1645
1929
 
1646
1930
  #### .valid_with? (class-level)
@@ -1659,6 +1943,12 @@ end
1659
1943
  Config.valid_with?(enabled: true, queue: { adapter: 'que' }) # => true
1660
1944
  Config.valid_with?(enabled: 123) # => false (should be a type of boolean)
1661
1945
  Config.valid_with?(enabled: true, queue: { adapter: Sidekiq }) # => false (queue.adapter should be a type of string)
1946
+
1947
+ # do-config notation is supported too
1948
+ Config.valid_with?(enabled: true) do |config|
1949
+ config.queue.adapter = :sidekiq
1950
+ end
1951
+ # => false (queue.adapter should be a type of string)
1662
1952
  ```
1663
1953
 
1664
1954
  ---
@@ -2117,13 +2407,14 @@ config.settings['RUN_CI'] # => '1'
2117
2407
 
2118
2408
  - aka `load_from_self`
2119
2409
  - `:format` - specify the format of data placed under the `__END__` instruction:
2120
- - `format: :yaml` - **YAML** format (by default);
2410
+ - `format: :dynamic` (default) - automatic format resolvation;
2411
+ - `format: :yaml` - **YAML** format;
2121
2412
  - `format: :json` - **JSON** format;
2122
2413
  - `format: :toml` - **TOML** format (via `toml`-plugin);
2123
2414
 
2124
2415
  ```ruby
2125
2416
  class Config < Qonfig::DataSet
2126
- load_from_self # on the root (format: :yaml is used by default)
2417
+ load_from_self # on the root (:dynamic format is used by default)
2127
2418
 
2128
2419
  setting :nested do
2129
2420
  load_from_self, format: :yaml # with explicitly identified YAML format
@@ -2164,7 +2455,8 @@ connection_timeout:
2164
2455
  - works in `expose_json` and `expose_yaml` manner, but with `__END__` instruction of the current file;
2165
2456
  - `env:` - your environment name (must be a type of `String`, `Symbol` or `Numeric`);
2166
2457
  - `:format` - specify the format of data placed under the `__END__` instruction:
2167
- - `format: :yaml` - **YAML** format (by default);
2458
+ - `format: :dynamic` (default) - automatic format resolvation;
2459
+ - `format: :yaml` - **YAML** format;
2168
2460
  - `format: :json` - **JSON** format;
2169
2461
  - `format: :toml` - **TOML** format (via `toml`-plugin);
2170
2462
 
@@ -2333,10 +2625,11 @@ config = Config.new # => Qonfig::FileNotFoundError
2333
2625
  ### Load setting values from YAML file (by instance)
2334
2626
 
2335
2627
  - prvoides an ability to load predefined setting values from a yaml file;
2336
- - `#load_from_yaml(file_path, strict: true, expose: nil)`
2628
+ - `#load_from_yaml(file_path, strict: true, expose: nil, &configurations)`
2337
2629
  - `file_path` - full file path or `:self` (`:self` means "load setting values from __END__ data");
2338
2630
  - `:strict` - rerquires that file (or __END__-data) should exist (`true` by default);
2339
2631
  - `:expose` - what the environment-based subset of keys should be used (`nil` means "do not use any subset of keys") (`nil` by default);
2632
+ - `&configurations` - `do |config|` ability :)
2340
2633
 
2341
2634
  #### Default behavior
2342
2635
 
@@ -2431,10 +2724,11 @@ config.settings.creds.auth_token # => "kek.pek" (from config.yml)
2431
2724
  ### Load setting values from JSON file (by instance)
2432
2725
 
2433
2726
  - prvoides an ability to load predefined setting values from a json file;
2434
- - `#load_from_yaml(file_path, strict: true, expose: nil)`
2727
+ - `#load_from_json(file_path, strict: true, expose: nil, &configurations)`
2435
2728
  - `file_path` - full file path or `:self` (`:self` means "load setting values from __END__ data");
2436
2729
  - `:strict` - rerquires that file (or __END__-data) should exist (`true` by default);
2437
2730
  - `:expose` - what the environment-based subset of keys should be used (`nil` means "do not use any subset of keys") (`nil` by default);
2731
+ - `&configurations` - `do |config|` ability :)
2438
2732
 
2439
2733
  #### Default behavior
2440
2734
 
@@ -2539,11 +2833,12 @@ config.settings.creds.auth_token # => "kek.pek" (from config.json)
2539
2833
  ### Load setting values from \_\_END\_\_ (by instance)
2540
2834
 
2541
2835
  - prvoides an ability to load predefined setting values from `__END__` file section;
2542
- - `#load_from_self(strict: true, expose: nil)`
2836
+ - `#load_from_self(strict: true, expose: nil, &configurations)`
2543
2837
  - `:format` - defines the format of file (`:dynamic` means "try to automatically infer the file format") (`:dynamic` by default);
2544
2838
  - supports `:yaml`, `:json`, `:toml` (via `Qonfig.plugin(:toml)`), `:dynamic` (automatic format detection);
2545
2839
  - `:strict` - requires that __END__-data should exist (`true` by default);
2546
2840
  - `:expose` - what the environment-based subset of keys should be used (`nil` means "do not use any subset of keys") (`nil` by default);
2841
+ - `&configurations` - `do |config|` ability :)
2547
2842
 
2548
2843
  #### Default behavior
2549
2844
 
@@ -2627,12 +2922,13 @@ __END__
2627
2922
 
2628
2923
  - prvoides an ability to load predefined setting values from a file;
2629
2924
  - works in instance-based `#load_from_yaml` / `#load_from_json` / `#load_from_self` manner;
2630
- - signature: `#load_from_file(file_path, format: :dynamic, strict: true, expose: nil)`:
2925
+ - signature: `#load_from_file(file_path, format: :dynamic, strict: true, expose: nil, &configurations)`:
2631
2926
  - `file_path` - full file path or `:self` (`:self` means "load setting values from __END__ data");
2632
2927
  - `:format` - defines the format of file (`:dynamic` means "try to automatically infer the file format") (`:dynamic` by default);
2633
2928
  - supports `:yaml`, `:json`, `:toml` (via `Qonfig.plugin(:toml)`), `:dynamic` (automatic format detection);
2634
2929
  - `:strict` - rerquires that file (or __END__-data) should exist (`true` by default);
2635
2930
  - `:expose` - what the environment-based subset of keys should be used (`nil` means "do not use any subset of keys") (`nil` by default);
2931
+ - `&configurations` - `do |config|` ability :)
2636
2932
  - see examples for instance-based `#load_from_yaml` ([doc](#load-setting-values-from-yaml-by-instance)) / `#load_from_json` ([doc](#load-setting-values-from-json-by-instance)) / `#load_from_self` ([doc](#load-setting-values-from-__end__-by-instance));
2637
2933
 
2638
2934
  ---
@@ -2818,9 +3114,10 @@ Qonfig.enabled_plugins # => ["pretty_print"]
2818
3114
 
2819
3115
  ### Plugins: toml
2820
3116
 
3117
+ - `Qonfig.plugin(:toml)`
2821
3118
  - adds support for `toml` format ([specification](https://github.com/toml-lang/toml));
2822
- - depends on `toml-rb` gem ([link](https://github.com/emancu/toml-rb));
2823
- - supports TOML `0.5.0` format (dependency lock);
3119
+ - depends on `toml-rb` gem ([link](https://github.com/emancu/toml-rb)) (tested on `>= 2.0`);
3120
+ - supports TOML `0.5.0` format (dependency lock) (`toml-rb >= 2.0`);
2824
3121
  - provides `.load_from_toml` (works in `.load_from_yaml` manner ([doc](#load-from-yaml-file)));
2825
3122
  - provides `.expose_toml` (works in `.expose_yaml` manner ([doc](#expose-yaml)));
2826
3123
  - provides `#save_to_toml` (works in `#save_to_yaml` manner ([doc](#save-to-yaml-file))) (`toml-rb` has no native options);