qonfig 0.10.0 → 0.11.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.
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