qonfig 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -1
  4. data/.rubocop.yml +1 -1
  5. data/.travis.yml +3 -3
  6. data/CHANGELOG.md +10 -0
  7. data/README.md +146 -1
  8. data/Rakefile +2 -0
  9. data/lib/qonfig/command_set.rb +53 -55
  10. data/lib/qonfig/commands/add_nested_option.rb +36 -40
  11. data/lib/qonfig/commands/add_option.rb +33 -37
  12. data/lib/qonfig/commands/base.rb +9 -13
  13. data/lib/qonfig/commands/compose.rb +29 -33
  14. data/lib/qonfig/commands/expose_yaml.rb +154 -158
  15. data/lib/qonfig/commands/load_from_env.rb +77 -79
  16. data/lib/qonfig/commands/load_from_json.rb +52 -56
  17. data/lib/qonfig/commands/load_from_self.rb +57 -61
  18. data/lib/qonfig/commands/load_from_yaml.rb +54 -58
  19. data/lib/qonfig/commands.rb +15 -0
  20. data/lib/qonfig/configurable.rb +88 -90
  21. data/lib/qonfig/data_set/class_builder.rb +17 -21
  22. data/lib/qonfig/data_set.rb +186 -138
  23. data/lib/qonfig/dsl.rb +106 -108
  24. data/lib/qonfig/{error.rb → exceptions.rb} +13 -1
  25. data/lib/qonfig/loaders/basic.rb +30 -32
  26. data/lib/qonfig/loaders/json.rb +16 -23
  27. data/lib/qonfig/loaders/yaml.rb +16 -23
  28. data/lib/qonfig/loaders.rb +9 -0
  29. data/lib/qonfig/plugins/abstract.rb +7 -11
  30. data/lib/qonfig/plugins/access_mixin.rb +21 -25
  31. data/lib/qonfig/plugins/registry.rb +120 -124
  32. data/lib/qonfig/plugins.rb +56 -54
  33. data/lib/qonfig/settings/builder.rb +10 -14
  34. data/lib/qonfig/settings/key_guard.rb +60 -64
  35. data/lib/qonfig/settings/lock.rb +53 -57
  36. data/lib/qonfig/settings.rb +392 -354
  37. data/lib/qonfig/uploaders/base.rb +18 -0
  38. data/lib/qonfig/uploaders/file.rb +55 -0
  39. data/lib/qonfig/uploaders/json.rb +35 -0
  40. data/lib/qonfig/uploaders/yaml.rb +93 -0
  41. data/lib/qonfig/uploaders.rb +10 -0
  42. data/lib/qonfig/version.rb +1 -1
  43. data/lib/qonfig.rb +4 -21
  44. data/qonfig.gemspec +1 -1
  45. metadata +13 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e73813f816c3ed07773bfd932c9d4d628688327326463d5d7a2755058acd49bc
4
- data.tar.gz: 513fe5d381b2cbddddb6e5bc0f10f518b3cae24dce6f8689810600a22698396f
3
+ metadata.gz: bc263b67aa4feb6e9c42f6f5f593e61dec61e758e7d7de41f4d36fc40bee18a6
4
+ data.tar.gz: f2e3e3f49318c392749c742a299edea3e58169bb5fc13930517a1c39cede4c91
5
5
  SHA512:
6
- metadata.gz: 1855afada5513df5986bd45b2d4ce8d747f6389886763841ace0b4cd6a2f1b063c69feaff8075da4b803cee23cc335c3b4a6cfa434a328d1d9b43080e7b65b54
7
- data.tar.gz: 7990a53bd25a8c6d0f78c8daff1453b4e14d2c9b380dde31e813499829d28f9667d8ae30e886a51ea5f8c5d2392d3bef9c23315afd7314a8c54bb008bac77ae1
6
+ metadata.gz: 46a9fd484859f615746bb5f1c21df8024ebd1766cc40353c313276b759795ec11b61e479306d3fb9f3f3e3764455ec06541746d827c56de0145c13838ccae6de
7
+ data.tar.gz: 491d96820bd2be04f8dde6d103598643d26dfafbf13a50a150a5b1c8469b8a4a726d02aeb35d9450a5a3785ee8fe3e7cc865c68e6080cd2f74701a20465de304
data/.gitignore CHANGED
@@ -11,3 +11,4 @@ Gemfile.lock
11
11
  /.idea
12
12
  .ruby-version
13
13
  /.vscode/
14
+ /spec/artifacts/
data/.rspec CHANGED
@@ -1,3 +1,3 @@
1
1
  --color
2
- --format=progress
2
+ --format progress
3
3
  --require spec_helper
data/.rubocop.yml CHANGED
@@ -4,7 +4,7 @@ inherit_gem:
4
4
  - lib/rubocop.rspec.yml
5
5
 
6
6
  AllCops:
7
- TargetRubyVersion: 2.6.1
7
+ TargetRubyVersion: 2.6.3
8
8
  Include:
9
9
  - lib/**/*.rb
10
10
  - spec/**/*.rb
data/.travis.yml CHANGED
@@ -3,9 +3,9 @@ matrix:
3
3
  fast_finish: true
4
4
  include:
5
5
  - rvm: 2.3.8
6
- - rvm: 2.4.5
7
- - rvm: 2.5.3
8
- - rvm: 2.6.1
6
+ - rvm: 2.4.6
7
+ - rvm: 2.5.5
8
+ - rvm: 2.6.3
9
9
  - rvm: ruby-head
10
10
  - rvm: jruby-head
11
11
  allow_failures:
data/CHANGELOG.md CHANGED
@@ -1,6 +1,16 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [0.11.0] - 2019-05-15
5
+ ### Added
6
+ - `#save_to_json` - save configurations to a json file (uses native `::JSON.generate` under the hood);
7
+ - `#save_to_yaml` - save configurations to a yaml file (uses native `::Psych.dump` under the hood);
8
+
9
+ ### Changed
10
+ - new `#to_h` signature: `#to_h(key_transformer:, value_transformer:)`
11
+ - `:key_transformer` - proc object used for key pre-processing (`-> (key) { key }` by default);
12
+ - `:value_transformer` - proc object used for value pre-processing (`-> (value) { value }` by default);
13
+
4
14
  ## [0.10.0] - 2019-02-26
5
15
  ### Added
6
16
  - `#slice_value` - get a slice of config options as a hash set and fetch the required value using the given key set;
data/README.md CHANGED
@@ -22,7 +22,6 @@ require 'qonfig'
22
22
  ## Usage
23
23
 
24
24
  - [Definition and Settings Access](#definition-and-access)
25
- - [Dynamic value calculation](???)
26
25
  - [Configuration](#configuration)
27
26
  - [Inheritance](#inheritance)
28
27
  - [Composition](#composition)
@@ -36,6 +35,8 @@ require 'qonfig'
36
35
  - [Load from JSON file](#load-from-json-file)
37
36
  - [Load from ENV](#load-from-env)
38
37
  - [Load from \_\_END\_\_](#load-from-__end__) (aka `load_from_self`)
38
+ - [Save to JSON file](#save-to-json-file) (`save_to_json`)
39
+ - [Save to YAML file](#save-to-yaml-file) (`save_to_yaml`)
39
40
  - [Smart Mixin](#smart-mixin) (`Qonfig::Configurable`)
40
41
  - [Plugins](#plugins)
41
42
 
@@ -777,6 +778,150 @@ connection_timeout:
777
778
 
778
779
  ---
779
780
 
781
+ ### Save to JSON file
782
+
783
+ - `#save_to_json` - represents config object as a json structure and saves it to a file:
784
+ - uses native `::JSON.generate` under the hood;
785
+ - writes new file (or rewrites existing file);
786
+ - attributes:
787
+ - `:path` - (required) - file path;
788
+ - `:options` - (optional) - native `::JSON.generate` options (from stdlib):
789
+ - `:indent` - `" "` by default;
790
+ - `:space` - `" "` by default/
791
+ - `:object_nl` - `"\n"` by default;
792
+ - `&value_preprocessor` - (optional) - value pre-processor;
793
+
794
+ #### Without value preprocessing (standard usage)
795
+
796
+ ```ruby
797
+ class AppConfig < Qonfig::DataSet
798
+ setting :server do
799
+ setting :address, 'localhost'
800
+ setting :port, 12_345
801
+ end
802
+
803
+ setting :enabled, true
804
+ end
805
+
806
+ config = AppConfig.new
807
+
808
+ # NOTE: save to json file
809
+ config.save_to_json(path: 'config.json')
810
+ ```
811
+
812
+ ```json
813
+ {
814
+ "sentry": {
815
+ "address": "localhost",
816
+ "port": 12345
817
+ },
818
+ "enabled": true
819
+ }
820
+ ```
821
+
822
+ #### With value preprocessing
823
+
824
+ ```ruby
825
+ class AppConfig < Qonfig::DataSet
826
+ setting :server do
827
+ setting :address, 'localhost'
828
+ setting :port, 12_345
829
+ end
830
+
831
+ setting :enabled, true
832
+ setting :dynamic, -> { 1 + 2 }
833
+ end
834
+
835
+ config = AppConfig.new
836
+
837
+ # NOTE: save to json file with custom options (no spaces / no new line / no indent; call procs)
838
+ config.save_to_json(path: 'config.json', options: { indent: '', space: '', object_nl: '' }) do |value|
839
+ value.is_a?(Proc) ? value.call : value
840
+ end
841
+ ```
842
+
843
+ ```json
844
+ // no spaces / no new line / no indent / calculated "dynamic" setting key
845
+ {"sentry":{"address":"localhost","port":12345},"enabled":true,"dynamic":3}
846
+ ```
847
+
848
+ ---
849
+
850
+ ### Save to YAML file
851
+
852
+ - `#save_to_yaml` - represents config object as a yaml structure and saves it to a file:
853
+ - uses native `::Psych.dump` under the hood;
854
+ - writes new file (or rewrites existing file);
855
+ - attributes:
856
+ - `:path` - (required) - file path;
857
+ - `:options` - (optional) - native `::Psych.dump` options (from stdlib):
858
+ - `:indentation` - `2` by default;
859
+ - `:line_width` - `-1` by default;
860
+ - `:canonical` - `false` by default;
861
+ - `:header` - `false` by default;
862
+ - `:symbolize_keys` - (non-native option) - `false` by default;
863
+ - `&value_preprocessor` - (optional) - value pre-processor;
864
+
865
+ #### Without value preprocessing (standard usage)
866
+
867
+ ```ruby
868
+ class AppConfig < Qonfig::DataSet
869
+ setting :server do
870
+ setting :address, 'localhost'
871
+ setting :port, 12_345
872
+ end
873
+
874
+ setting :enabled, true
875
+ end
876
+
877
+ config = AppConfig.new
878
+
879
+ # NOTE: save to yaml file
880
+ config.save_to_yaml(path: 'config.yml')
881
+ ```
882
+
883
+ ```yaml
884
+ ---
885
+ server:
886
+ address: localhost
887
+ port: 12345
888
+ enabled: true
889
+ ```
890
+
891
+ #### With value preprocessing and custom options
892
+
893
+ ```ruby
894
+ class AppConfig < Qonfig::DataSet
895
+ setting :server do
896
+ setting :address, 'localhost'
897
+ setting :port, 12_345
898
+ end
899
+
900
+ setting :enabled, true
901
+ setting :dynamic, -> { 5 + 5 }
902
+ end
903
+
904
+ config = AppConfig.new
905
+
906
+ # NOTE: save to yaml file with custom options (add yaml version header; call procs)
907
+ config.save_to_yaml(path: 'config.yml', options: { header: true }) do |value|
908
+ value.is_a?(Proc) ? value.call : value
909
+ end
910
+ ```
911
+
912
+ ```yaml
913
+ # yaml version header / calculated "dynamic" setting key
914
+ %YAML 1.1
915
+ ---
916
+ server:
917
+ address: localhost
918
+ port: 12345
919
+ enabled: true
920
+ dynamic: 10
921
+ ```
922
+
923
+ ---
924
+
780
925
  ### Smart Mixin
781
926
 
782
927
  - class-level:
data/Rakefile CHANGED
@@ -4,6 +4,7 @@ require 'bundler/gem_tasks'
4
4
  require 'rspec/core/rake_task'
5
5
  require 'rubocop'
6
6
  require 'rubocop-rspec'
7
+ require 'rubocop-performance'
7
8
  require 'rubocop/rake_task'
8
9
 
9
10
  RuboCop::RakeTask.new(:rubocop) do |t|
@@ -11,6 +12,7 @@ RuboCop::RakeTask.new(:rubocop) do |t|
11
12
 
12
13
  t.options = ['--config', config_path]
13
14
  t.requires << 'rubocop-rspec'
15
+ t.requires << 'rubocop-performance'
14
16
  end
15
17
 
16
18
  RSpec::Core::RakeTask.new(:rspec)
@@ -1,69 +1,67 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Qonfig
3
+ # @api private
4
+ # @since 0.1.0
5
+ class Qonfig::CommandSet
6
+ # @return [Array<Qonfig::Commands::Base>]
7
+ #
4
8
  # @api private
5
9
  # @since 0.1.0
6
- class CommandSet
7
- # @return [Array<Qonfig::Commands::Base>]
8
- #
9
- # @api private
10
- # @since 0.1.0
11
- attr_reader :commands
10
+ attr_reader :commands
12
11
 
13
- # @api private
14
- # @since 0.1.0
15
- def initialize
16
- @commands = []
17
- @access_lock = Mutex.new
18
- end
12
+ # @api private
13
+ # @since 0.1.0
14
+ def initialize
15
+ @commands = []
16
+ @access_lock = Mutex.new
17
+ end
19
18
 
20
- # @param command [Qonfig::Commands::Base]
21
- # @return [void]
22
- #
23
- # @api private
24
- # @since 0.1.0
25
- def add_command(command)
26
- thread_safe { commands << command }
27
- end
28
- alias_method :<<, :add_command
19
+ # @param command [Qonfig::Commands::Base]
20
+ # @return [void]
21
+ #
22
+ # @api private
23
+ # @since 0.1.0
24
+ def add_command(command)
25
+ thread_safe { commands << command }
26
+ end
27
+ alias_method :<<, :add_command
29
28
 
30
- # @param block [Proc]
31
- # @return [Enumerable]
32
- #
33
- # @api private
34
- # @since 0.1.0
35
- def each(&block)
36
- thread_safe { block_given? ? commands.each(&block) : commands.each }
37
- end
29
+ # @param block [Proc]
30
+ # @return [Enumerable]
31
+ #
32
+ # @api private
33
+ # @since 0.1.0
34
+ def each(&block)
35
+ thread_safe { block_given? ? commands.each(&block) : commands.each }
36
+ end
38
37
 
39
- # @param command_set [Qonfig::CommandSet]
40
- # @return [void]
41
- #
42
- # @api private
43
- # @since 0.1.0
44
- def concat(command_set)
45
- thread_safe { commands.concat(command_set.commands) }
46
- end
38
+ # @param command_set [Qonfig::CommandSet]
39
+ # @return [void]
40
+ #
41
+ # @api private
42
+ # @since 0.1.0
43
+ def concat(command_set)
44
+ thread_safe { commands.concat(command_set.commands) }
45
+ end
47
46
 
48
- # @return [Qonfig::CommandSet]
49
- #
50
- # @api private
51
- # @since 0.2.0
52
- def dup
53
- thread_safe do
54
- self.class.new.tap { |duplicate| duplicate.concat(self) }
55
- end
47
+ # @return [Qonfig::CommandSet]
48
+ #
49
+ # @api private
50
+ # @since 0.2.0
51
+ def dup
52
+ thread_safe do
53
+ self.class.new.tap { |duplicate| duplicate.concat(self) }
56
54
  end
55
+ end
57
56
 
58
- private
57
+ private
59
58
 
60
- # @param block [Proc]
61
- # @return [Object]
62
- #
63
- # @api private
64
- # @since 0.2.0
65
- def thread_safe(&block)
66
- @access_lock.synchronize(&block)
67
- end
59
+ # @param block [Proc]
60
+ # @return [Object]
61
+ #
62
+ # @api private
63
+ # @since 0.2.0
64
+ def thread_safe(&block)
65
+ @access_lock.synchronize(&block)
68
66
  end
69
67
  end
@@ -1,49 +1,45 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Qonfig
4
- module Commands
5
- # @api private
6
- # @since 0.1.0
7
- class AddNestedOption < Base
8
- # @return [Symbol, String]
9
- #
10
- # @api private
11
- # @since 0.1.0
12
- attr_reader :key
3
+ # @api private
4
+ # @since 0.1.0
5
+ class Qonfig::Commands::AddNestedOption < Qonfig::Commands::Base
6
+ # @return [Symbol, String]
7
+ #
8
+ # @api private
9
+ # @since 0.1.0
10
+ attr_reader :key
13
11
 
14
- # @return [Class<Qonfig::DataSet>]
15
- #
16
- # @api private
17
- # @since 0.2.0
18
- attr_reader :nested_data_set_klass
12
+ # @return [Class<Qonfig::DataSet>]
13
+ #
14
+ # @api private
15
+ # @since 0.2.0
16
+ attr_reader :nested_data_set_klass
19
17
 
20
- # @param key [Symbol, String]
21
- # @param nested_definitions [Proc]
22
- #
23
- # @raise [Qonfig::ArgumentError]
24
- # @raise [Qonfig::CoreMethodIntersectionError]
25
- #
26
- # @api private
27
- # @since 0.1.0
28
- def initialize(key, nested_definitions)
29
- Qonfig::Settings::KeyGuard.prevent_incomparabilities!(key)
18
+ # @param key [Symbol, String]
19
+ # @param nested_definitions [Proc]
20
+ #
21
+ # @raise [Qonfig::ArgumentError]
22
+ # @raise [Qonfig::CoreMethodIntersectionError]
23
+ #
24
+ # @api private
25
+ # @since 0.1.0
26
+ def initialize(key, nested_definitions)
27
+ Qonfig::Settings::KeyGuard.prevent_incomparabilities!(key)
30
28
 
31
- @key = key
32
- @nested_data_set_klass = Class.new(Qonfig::DataSet).tap do |data_set|
33
- data_set.instance_eval(&nested_definitions)
34
- end
35
- end
29
+ @key = key
30
+ @nested_data_set_klass = Class.new(Qonfig::DataSet).tap do |data_set|
31
+ data_set.instance_eval(&nested_definitions)
32
+ end
33
+ end
36
34
 
37
- # @param settings [Qonfig::Settings]
38
- # @return [void]
39
- #
40
- # @api private
41
- # @since 0.1.0
42
- def call(settings)
43
- nested_settings = nested_data_set_klass.new.settings
35
+ # @param settings [Qonfig::Settings]
36
+ # @return [void]
37
+ #
38
+ # @api private
39
+ # @since 0.1.0
40
+ def call(settings)
41
+ nested_settings = nested_data_set_klass.new.settings
44
42
 
45
- settings.__define_setting__(key, nested_settings)
46
- end
47
- end
43
+ settings.__define_setting__(key, nested_settings)
48
44
  end
49
45
  end
@@ -1,45 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Qonfig
4
- module Commands
5
- # @api private
6
- # @since 0.1.0
7
- class AddOption < Base
8
- # @return [Symbol, String]
9
- #
10
- # @api private
11
- # @since 0.1.0
12
- attr_reader :key
3
+ # @api private
4
+ # @since 0.1.0
5
+ class Qonfig::Commands::AddOption < Qonfig::Commands::Base
6
+ # @return [Symbol, String]
7
+ #
8
+ # @api private
9
+ # @since 0.1.0
10
+ attr_reader :key
13
11
 
14
- # @return [Object]
15
- #
16
- # @api private
17
- # @since 0.1.0
18
- attr_reader :value
12
+ # @return [Object]
13
+ #
14
+ # @api private
15
+ # @since 0.1.0
16
+ attr_reader :value
19
17
 
20
- # @param key [Symbol, String]
21
- # @param value [Object]
22
- #
23
- # @raise [Qonfig::ArgumentError]
24
- # @raise [Qonfig::CoreMethodIntersectionError]
25
- #
26
- # @api private
27
- # @since 0.1.0
28
- def initialize(key, value)
29
- Qonfig::Settings::KeyGuard.prevent_incomparabilities!(key)
18
+ # @param key [Symbol, String]
19
+ # @param value [Object]
20
+ #
21
+ # @raise [Qonfig::ArgumentError]
22
+ # @raise [Qonfig::CoreMethodIntersectionError]
23
+ #
24
+ # @api private
25
+ # @since 0.1.0
26
+ def initialize(key, value)
27
+ Qonfig::Settings::KeyGuard.prevent_incomparabilities!(key)
30
28
 
31
- @key = key
32
- @value = value
33
- end
29
+ @key = key
30
+ @value = value
31
+ end
34
32
 
35
- # @param settings [Qonfig::Settings]
36
- # @return [void]
37
- #
38
- # @api private
39
- # @since 0.1.0
40
- def call(settings)
41
- settings.__define_setting__(key, value)
42
- end
43
- end
33
+ # @param settings [Qonfig::Settings]
34
+ # @return [void]
35
+ #
36
+ # @api private
37
+ # @since 0.1.0
38
+ def call(settings)
39
+ settings.__define_setting__(key, value)
44
40
  end
45
41
  end
@@ -1,16 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Qonfig
4
- module Commands
5
- # @api private
6
- # @since 0.1.0
7
- class Base
8
- # @param settings [Qonfig::Settings]
9
- # @return [void]
10
- #
11
- # @api private
12
- # @since 0.1.0
13
- def call(settings); end
14
- end
15
- end
3
+ # @api private
4
+ # @since 0.1.0
5
+ class Qonfig::Commands::Base
6
+ # @param settings [Qonfig::Settings]
7
+ # @return [void]
8
+ #
9
+ # @api private
10
+ # @since 0.1.0
11
+ def call(settings); end
16
12
  end
@@ -1,41 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Qonfig
4
- module Commands
5
- # @api private
6
- # @since 0.1.0
7
- class Compose < Base
8
- # @return [Qonfig::DataSet]
9
- #
10
- # @api private
11
- # @since 0.1.0
12
- attr_reader :data_set_klass
3
+ # @api private
4
+ # @since 0.1.0
5
+ class Qonfig::Commands::Compose < Qonfig::Commands::Base
6
+ # @return [Qonfig::DataSet]
7
+ #
8
+ # @api private
9
+ # @since 0.1.0
10
+ attr_reader :data_set_klass
13
11
 
14
- # @param data_set_klass [Qonfig::DataSet]
15
- #
16
- # @raise [Qonfig::ArgumentError]
17
- #
18
- # @api private
19
- # @since 0.1.0
20
- def initialize(data_set_klass)
21
- raise(
22
- Qonfig::ArgumentError,
23
- 'Composed config class should be a subtype of Qonfig::DataSet'
24
- ) unless data_set_klass.is_a?(Class) && data_set_klass < Qonfig::DataSet
12
+ # @param data_set_klass [Qonfig::DataSet]
13
+ #
14
+ # @raise [Qonfig::ArgumentError]
15
+ #
16
+ # @api private
17
+ # @since 0.1.0
18
+ def initialize(data_set_klass)
19
+ raise(
20
+ Qonfig::ArgumentError,
21
+ 'Composed config class should be a subtype of Qonfig::DataSet'
22
+ ) unless data_set_klass.is_a?(Class) && data_set_klass < Qonfig::DataSet
25
23
 
26
- @data_set_klass = data_set_klass
27
- end
24
+ @data_set_klass = data_set_klass
25
+ end
28
26
 
29
- # @param settings [Qonfig::Settings]
30
- # @return [void]
31
- #
32
- # @api private
33
- # @since 0.1.0
34
- def call(settings)
35
- composite_settings = data_set_klass.new.settings
27
+ # @param settings [Qonfig::Settings]
28
+ # @return [void]
29
+ #
30
+ # @api private
31
+ # @since 0.1.0
32
+ def call(settings)
33
+ composite_settings = data_set_klass.new.settings
36
34
 
37
- settings.__append_settings__(composite_settings)
38
- end
39
- end
35
+ settings.__append_settings__(composite_settings)
40
36
  end
41
37
  end