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
@@ -1,77 +1,73 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Qonfig
4
- module Commands
5
- # @api private
6
- # @since 0.2.0
7
- class LoadFromSelf < Base
8
- # @return [String]
9
- #
10
- # @api private
11
- # @since 0.2.0
12
- attr_reader :caller_location
3
+ # @api private
4
+ # @since 0.2.0
5
+ class Qonfig::Commands::LoadFromSelf < Qonfig::Commands::Base
6
+ # @return [String]
7
+ #
8
+ # @api private
9
+ # @since 0.2.0
10
+ attr_reader :caller_location
13
11
 
14
- # @param caller_location [String]
15
- #
16
- # @api private
17
- # @since 0.2.0
18
- def initialize(caller_location)
19
- @caller_location = caller_location
20
- end
12
+ # @param caller_location [String]
13
+ #
14
+ # @api private
15
+ # @since 0.2.0
16
+ def initialize(caller_location)
17
+ @caller_location = caller_location
18
+ end
21
19
 
22
- # @param settings [Qonfig::Settings]
23
- # @return [void]
24
- #
25
- # @api private
26
- # @since 0.2.0
27
- def call(settings)
28
- yaml_data = load_self_placed_yaml_data
20
+ # @param settings [Qonfig::Settings]
21
+ # @return [void]
22
+ #
23
+ # @api private
24
+ # @since 0.2.0
25
+ def call(settings)
26
+ yaml_data = load_self_placed_yaml_data
29
27
 
30
- yaml_based_settings = build_data_set_klass(yaml_data).new.settings
28
+ yaml_based_settings = build_data_set_klass(yaml_data).new.settings
31
29
 
32
- settings.__append_settings__(yaml_based_settings)
33
- end
30
+ settings.__append_settings__(yaml_based_settings)
31
+ end
34
32
 
35
- private
33
+ private
36
34
 
37
- # @return [Hash]
38
- #
39
- # @raise [Qonfig::SelfDataNotFound]
40
- # @raise [Qonfig::IncompatibleYAMLStructureError]
41
- #
42
- # @api private
43
- # @since 0.2.0
44
- def load_self_placed_yaml_data
45
- caller_file = caller_location.split(':').first
35
+ # @return [Hash]
36
+ #
37
+ # @raise [Qonfig::SelfDataNotFound]
38
+ # @raise [Qonfig::IncompatibleYAMLStructureError]
39
+ #
40
+ # @api private
41
+ # @since 0.2.0
42
+ def load_self_placed_yaml_data
43
+ caller_file = caller_location.split(':').first
46
44
 
47
- raise(
48
- Qonfig::SelfDataNotFoundError,
49
- "Caller file does not exist! (location: #{caller_location})"
50
- ) unless File.exist?(caller_file)
45
+ raise(
46
+ Qonfig::SelfDataNotFoundError,
47
+ "Caller file does not exist! (location: #{caller_location})"
48
+ ) unless File.exist?(caller_file)
51
49
 
52
- data_match = IO.read(caller_file).match(/\n__END__\n(?<end_data>.*)/m)
53
- raise Qonfig::SelfDataNotFoundError, '__END__ data not found!' unless data_match
50
+ data_match = IO.read(caller_file).match(/\n__END__\n(?<end_data>.*)/m)
51
+ raise Qonfig::SelfDataNotFoundError, '__END__ data not found!' unless data_match
54
52
 
55
- end_data = data_match[:end_data]
56
- raise Qonfig::SelfDataNotFoundError, '__END__ data not found!' unless end_data
53
+ end_data = data_match[:end_data]
54
+ raise Qonfig::SelfDataNotFoundError, '__END__ data not found!' unless end_data
57
55
 
58
- yaml_data = Qonfig::Loaders::YAML.load(end_data)
59
- raise(
60
- Qonfig::IncompatibleYAMLStructureError,
61
- 'YAML content should have a hash-like structure'
62
- ) unless yaml_data.is_a?(Hash)
56
+ yaml_data = Qonfig::Loaders::YAML.load(end_data)
57
+ raise(
58
+ Qonfig::IncompatibleYAMLStructureError,
59
+ 'YAML content should have a hash-like structure'
60
+ ) unless yaml_data.is_a?(Hash)
63
61
 
64
- yaml_data
65
- end
62
+ yaml_data
63
+ end
66
64
 
67
- # @param self_placed_yaml_data [Hash]
68
- # @return [Class<Qonfig::DataSet>]
69
- #
70
- # @api private
71
- # @since 0.2.0
72
- def build_data_set_klass(self_placed_yaml_data)
73
- Qonfig::DataSet::ClassBuilder.build_from_hash(self_placed_yaml_data)
74
- end
75
- end
65
+ # @param self_placed_yaml_data [Hash]
66
+ # @return [Class<Qonfig::DataSet>]
67
+ #
68
+ # @api private
69
+ # @since 0.2.0
70
+ def build_data_set_klass(self_placed_yaml_data)
71
+ Qonfig::DataSet::ClassBuilder.build_from_hash(self_placed_yaml_data)
76
72
  end
77
73
  end
@@ -1,62 +1,58 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Qonfig
4
- module Commands
5
- # @api private
6
- # @since 0.2.0
7
- class LoadFromYAML < Base
8
- # @return [String]
9
- #
10
- # @api private
11
- # @since 0.2.0
12
- attr_reader :file_path
13
-
14
- # @return [Boolean]
15
- #
16
- # @api private
17
- # @since 0.2.0
18
- attr_reader :strict
19
-
20
- # @param file_path [String]
21
- # @option strict [Boolean]
22
- #
23
- # @api private
24
- # @since 0.2.0
25
- def initialize(file_path, strict: true)
26
- @file_path = file_path
27
- @strict = strict
28
- end
29
-
30
- # @param settings [Qonfig::Settings]
31
- # @return [void]
32
- #
33
- # @raise [Qonfig::IncompatibleYAMLStructureError]
34
- #
35
- # @api private
36
- # @since 0.2.0
37
- def call(settings)
38
- yaml_data = Qonfig::Loaders::YAML.load_file(file_path, fail_on_unexist: strict)
39
-
40
- raise(
41
- Qonfig::IncompatibleYAMLStructureError,
42
- 'YAML content should have a hash-like structure'
43
- ) unless yaml_data.is_a?(Hash)
44
-
45
- yaml_based_settings = build_data_set_class(yaml_data).new.settings
46
-
47
- settings.__append_settings__(yaml_based_settings)
48
- end
49
-
50
- private
51
-
52
- # @param yaml_data [Hash]
53
- # @return [Class<Qonfig::DataSet>]
54
- #
55
- # @api private
56
- # @since 0.2.0
57
- def build_data_set_class(yaml_data)
58
- Qonfig::DataSet::ClassBuilder.build_from_hash(yaml_data)
59
- end
60
- end
3
+ # @api private
4
+ # @since 0.2.0
5
+ class Qonfig::Commands::LoadFromYAML < Qonfig::Commands::Base
6
+ # @return [String]
7
+ #
8
+ # @api private
9
+ # @since 0.2.0
10
+ attr_reader :file_path
11
+
12
+ # @return [Boolean]
13
+ #
14
+ # @api private
15
+ # @since 0.2.0
16
+ attr_reader :strict
17
+
18
+ # @param file_path [String]
19
+ # @option strict [Boolean]
20
+ #
21
+ # @api private
22
+ # @since 0.2.0
23
+ def initialize(file_path, strict: true)
24
+ @file_path = file_path
25
+ @strict = strict
26
+ end
27
+
28
+ # @param settings [Qonfig::Settings]
29
+ # @return [void]
30
+ #
31
+ # @raise [Qonfig::IncompatibleYAMLStructureError]
32
+ #
33
+ # @api private
34
+ # @since 0.2.0
35
+ def call(settings)
36
+ yaml_data = Qonfig::Loaders::YAML.load_file(file_path, fail_on_unexist: strict)
37
+
38
+ raise(
39
+ Qonfig::IncompatibleYAMLStructureError,
40
+ 'YAML content should have a hash-like structure'
41
+ ) unless yaml_data.is_a?(Hash)
42
+
43
+ yaml_based_settings = build_data_set_class(yaml_data).new.settings
44
+
45
+ settings.__append_settings__(yaml_based_settings)
46
+ end
47
+
48
+ private
49
+
50
+ # @param yaml_data [Hash]
51
+ # @return [Class<Qonfig::DataSet>]
52
+ #
53
+ # @api private
54
+ # @since 0.2.0
55
+ def build_data_set_class(yaml_data)
56
+ Qonfig::DataSet::ClassBuilder.build_from_hash(yaml_data)
61
57
  end
62
58
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.1.0
5
+ module Qonfig::Commands
6
+ require_relative 'commands/base'
7
+ require_relative 'commands/add_option'
8
+ require_relative 'commands/add_nested_option'
9
+ require_relative 'commands/compose'
10
+ require_relative 'commands/load_from_yaml'
11
+ require_relative 'commands/load_from_json'
12
+ require_relative 'commands/load_from_self'
13
+ require_relative 'commands/load_from_env'
14
+ require_relative 'commands/expose_yaml'
15
+ end
@@ -1,117 +1,115 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Qonfig
4
- # @api public
5
- # @since 0.2.0
6
- module Configurable
7
- class << self
8
- # @param base_klass [Class]
9
- # @return [void]
10
- #
11
- # @api private
12
- # @since 0.2.0
13
- def included(base_klass)
14
- base_klass.instance_variable_set(:@__qonfig_access_lock__, Mutex.new)
15
- base_klass.instance_variable_set(:@__qonfig_definition_lock__, Mutex.new)
16
- base_klass.instance_variable_set(:@__qonfig_config_klass__, Class.new(Qonfig::DataSet))
17
- base_klass.instance_variable_set(:@__qonfig_config__, nil)
3
+ # @api public
4
+ # @since 0.2.0
5
+ module Qonfig::Configurable
6
+ class << self
7
+ # @param base_klass [Class]
8
+ # @return [void]
9
+ #
10
+ # @api private
11
+ # @since 0.2.0
12
+ def included(base_klass)
13
+ base_klass.instance_variable_set(:@__qonfig_access_lock__, Mutex.new)
14
+ base_klass.instance_variable_set(:@__qonfig_definition_lock__, Mutex.new)
15
+ base_klass.instance_variable_set(:@__qonfig_config_klass__, Class.new(Qonfig::DataSet))
16
+ base_klass.instance_variable_set(:@__qonfig_config__, nil)
18
17
 
19
- base_klass.extend(ClassMethods)
20
- base_klass.include(InstanceMethods)
21
- base_klass.singleton_class.prepend(ClassInheritance)
18
+ base_klass.extend(ClassMethods)
19
+ base_klass.include(InstanceMethods)
20
+ base_klass.singleton_class.prepend(ClassInheritance)
22
21
 
23
- super
24
- end
22
+ super
25
23
  end
24
+ end
26
25
 
26
+ # @api private
27
+ # @since 0.2.0
28
+ module ClassInheritance
29
+ # @param child_klass [Class]
30
+ # @return [void]
31
+ #
27
32
  # @api private
28
33
  # @since 0.2.0
29
- module ClassInheritance
30
- # @param child_klass [Class]
31
- # @return [void]
32
- #
33
- # @api private
34
- # @since 0.2.0
35
- def inherited(child_klass)
36
- inherited_config_klass = Class.new(@__qonfig_config_klass__)
34
+ def inherited(child_klass)
35
+ inherited_config_klass = Class.new(@__qonfig_config_klass__)
37
36
 
38
- child_klass.instance_variable_set(:@__qonfig_definition_lock__, Mutex.new)
39
- child_klass.instance_variable_set(:@__qonfig_access_lock__, Mutex.new)
40
- child_klass.instance_variable_set(:@__qonfig_config_klass__, inherited_config_klass)
41
- child_klass.instance_variable_set(:@__qonfig_config__, nil)
37
+ child_klass.instance_variable_set(:@__qonfig_definition_lock__, Mutex.new)
38
+ child_klass.instance_variable_set(:@__qonfig_access_lock__, Mutex.new)
39
+ child_klass.instance_variable_set(:@__qonfig_config_klass__, inherited_config_klass)
40
+ child_klass.instance_variable_set(:@__qonfig_config__, nil)
42
41
 
43
- super
44
- end
42
+ super
45
43
  end
44
+ end
46
45
 
47
- # @api private
46
+ # @api private
47
+ # @since 0.2.0
48
+ module ClassMethods
49
+ # @param block [Proc]
50
+ # @return [void]
51
+ #
52
+ # @api public
48
53
  # @since 0.2.0
49
- module ClassMethods
50
- # @param block [Proc]
51
- # @return [void]
52
- #
53
- # @api public
54
- # @since 0.2.0
55
- def configuration(&block)
56
- @__qonfig_definition_lock__.synchronize do
57
- @__qonfig_config_klass__.instance_eval(&block) if block_given?
58
- end
54
+ def configuration(&block)
55
+ @__qonfig_definition_lock__.synchronize do
56
+ @__qonfig_config_klass__.instance_eval(&block) if block_given?
59
57
  end
58
+ end
60
59
 
61
- # @param options_map [Hash]
62
- # @param block [Proc]
63
- # @return [void]
64
- #
65
- # @api public
66
- # @since 0.2.0
67
- def configure(options_map = {}, &block)
68
- @__qonfig_access_lock__.synchronize do
69
- config.configure(options_map, &block)
70
- end
60
+ # @param options_map [Hash]
61
+ # @param block [Proc]
62
+ # @return [void]
63
+ #
64
+ # @api public
65
+ # @since 0.2.0
66
+ def configure(options_map = {}, &block)
67
+ @__qonfig_access_lock__.synchronize do
68
+ config.configure(options_map, &block)
71
69
  end
70
+ end
72
71
 
73
- # @return [Qonfig::DataSet]
74
- #
75
- # @api public
76
- # @since 0.2.0
77
- def config
78
- @__qonfig_definition_lock__.synchronize do
79
- @__qonfig_config__ ||= @__qonfig_config_klass__.new
80
- end
72
+ # @return [Qonfig::DataSet]
73
+ #
74
+ # @api public
75
+ # @since 0.2.0
76
+ def config
77
+ @__qonfig_definition_lock__.synchronize do
78
+ @__qonfig_config__ ||= @__qonfig_config_klass__.new
81
79
  end
82
80
  end
81
+ end
83
82
 
84
- # @api private
83
+ # @api private
84
+ # @since 0.2.0
85
+ module InstanceMethods
86
+ # @return [Qonfig::DataSet]
87
+ #
88
+ # @api public
85
89
  # @since 0.2.0
86
- module InstanceMethods
87
- # @return [Qonfig::DataSet]
88
- #
89
- # @api public
90
- # @since 0.2.0
91
- def config
92
- self.class.instance_variable_get(:@__qonfig_definition_lock__).synchronize do
93
- @__qonfig_config__ ||= self.class.instance_variable_get(:@__qonfig_config_klass__).new
94
- end
90
+ def config
91
+ self.class.instance_variable_get(:@__qonfig_definition_lock__).synchronize do
92
+ @__qonfig_config__ ||= self.class.instance_variable_get(:@__qonfig_config_klass__).new
95
93
  end
94
+ end
96
95
 
97
- # @return [Qonfig::DataSet]
98
- #
99
- # @api public
100
- # @since 0.6.0
101
- def shared_config
102
- self.class.config
103
- end
96
+ # @return [Qonfig::DataSet]
97
+ #
98
+ # @api public
99
+ # @since 0.6.0
100
+ def shared_config
101
+ self.class.config
102
+ end
104
103
 
105
- # @param options_map [Hash]
106
- # @param block [Proc]
107
- # @return [void]
108
- #
109
- # @api public
110
- # @since 0.2.0
111
- def configure(options_map = {}, &block)
112
- self.class.instance_variable_get(:@__qonfig_access_lock__).synchronize do
113
- config.configure(options_map, &block)
114
- end
104
+ # @param options_map [Hash]
105
+ # @param block [Proc]
106
+ # @return [void]
107
+ #
108
+ # @api public
109
+ # @since 0.2.0
110
+ def configure(options_map = {}, &block)
111
+ self.class.instance_variable_get(:@__qonfig_access_lock__).synchronize do
112
+ config.configure(options_map, &block)
115
113
  end
116
114
  end
117
115
  end
@@ -1,28 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Qonfig
4
- class DataSet
3
+ # @api private
4
+ # @since 0.2.0
5
+ module Qonfig::DataSet::ClassBuilder
6
+ class << self
7
+ # @param hash [Hash]
8
+ # @return [Class<Qonfig::DataSet>]
9
+ #
10
+ # @see Qonfig::DataSet
11
+ #
5
12
  # @api private
6
13
  # @since 0.2.0
7
- module ClassBuilder
8
- class << self
9
- # @param hash [Hash]
10
- # @return [Class<Qonfig::DataSet>]
11
- #
12
- # @see Qonfig::DataSet
13
- #
14
- # @api private
15
- # @since 0.2.0
16
- def build_from_hash(hash)
17
- Class.new(Qonfig::DataSet).tap do |data_set_klass|
18
- hash.each_pair do |key, value|
19
- if value.is_a?(Hash) && value.any?
20
- sub_data_set_klass = build_from_hash(value)
21
- data_set_klass.setting(key) { compose sub_data_set_klass }
22
- else
23
- data_set_klass.setting key, value
24
- end
25
- end
14
+ def build_from_hash(hash)
15
+ Class.new(Qonfig::DataSet).tap do |data_set_klass|
16
+ hash.each_pair do |key, value|
17
+ if value.is_a?(Hash) && value.any?
18
+ sub_data_set_klass = build_from_hash(value)
19
+ data_set_klass.setting(key) { compose sub_data_set_klass }
20
+ else
21
+ data_set_klass.setting key, value
26
22
  end
27
23
  end
28
24
  end