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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rspec +1 -1
- data/.rubocop.yml +1 -1
- data/.travis.yml +3 -3
- data/CHANGELOG.md +10 -0
- data/README.md +146 -1
- data/Rakefile +2 -0
- data/lib/qonfig/command_set.rb +53 -55
- data/lib/qonfig/commands/add_nested_option.rb +36 -40
- data/lib/qonfig/commands/add_option.rb +33 -37
- data/lib/qonfig/commands/base.rb +9 -13
- data/lib/qonfig/commands/compose.rb +29 -33
- data/lib/qonfig/commands/expose_yaml.rb +154 -158
- data/lib/qonfig/commands/load_from_env.rb +77 -79
- data/lib/qonfig/commands/load_from_json.rb +52 -56
- data/lib/qonfig/commands/load_from_self.rb +57 -61
- data/lib/qonfig/commands/load_from_yaml.rb +54 -58
- data/lib/qonfig/commands.rb +15 -0
- data/lib/qonfig/configurable.rb +88 -90
- data/lib/qonfig/data_set/class_builder.rb +17 -21
- data/lib/qonfig/data_set.rb +186 -138
- data/lib/qonfig/dsl.rb +106 -108
- data/lib/qonfig/{error.rb → exceptions.rb} +13 -1
- data/lib/qonfig/loaders/basic.rb +30 -32
- data/lib/qonfig/loaders/json.rb +16 -23
- data/lib/qonfig/loaders/yaml.rb +16 -23
- data/lib/qonfig/loaders.rb +9 -0
- data/lib/qonfig/plugins/abstract.rb +7 -11
- data/lib/qonfig/plugins/access_mixin.rb +21 -25
- data/lib/qonfig/plugins/registry.rb +120 -124
- data/lib/qonfig/plugins.rb +56 -54
- data/lib/qonfig/settings/builder.rb +10 -14
- data/lib/qonfig/settings/key_guard.rb +60 -64
- data/lib/qonfig/settings/lock.rb +53 -57
- data/lib/qonfig/settings.rb +392 -354
- data/lib/qonfig/uploaders/base.rb +18 -0
- data/lib/qonfig/uploaders/file.rb +55 -0
- data/lib/qonfig/uploaders/json.rb +35 -0
- data/lib/qonfig/uploaders/yaml.rb +93 -0
- data/lib/qonfig/uploaders.rb +10 -0
- data/lib/qonfig/version.rb +1 -1
- data/lib/qonfig.rb +4 -21
- data/qonfig.gemspec +1 -1
- metadata +13 -6
@@ -1,77 +1,73 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
28
|
+
yaml_based_settings = build_data_set_klass(yaml_data).new.settings
|
31
29
|
|
32
|
-
|
33
|
-
|
30
|
+
settings.__append_settings__(yaml_based_settings)
|
31
|
+
end
|
34
32
|
|
35
|
-
|
33
|
+
private
|
36
34
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
45
|
+
raise(
|
46
|
+
Qonfig::SelfDataNotFoundError,
|
47
|
+
"Caller file does not exist! (location: #{caller_location})"
|
48
|
+
) unless File.exist?(caller_file)
|
51
49
|
|
52
|
-
|
53
|
-
|
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
|
-
|
56
|
-
|
53
|
+
end_data = data_match[:end_data]
|
54
|
+
raise Qonfig::SelfDataNotFoundError, '__END__ data not found!' unless end_data
|
57
55
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
-
|
65
|
-
|
62
|
+
yaml_data
|
63
|
+
end
|
66
64
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
data/lib/qonfig/configurable.rb
CHANGED
@@ -1,117 +1,115 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
18
|
+
base_klass.extend(ClassMethods)
|
19
|
+
base_klass.include(InstanceMethods)
|
20
|
+
base_klass.singleton_class.prepend(ClassInheritance)
|
22
21
|
|
23
|
-
|
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
|
-
|
30
|
-
|
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
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
-
|
44
|
-
end
|
42
|
+
super
|
45
43
|
end
|
44
|
+
end
|
46
45
|
|
47
|
-
|
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
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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
|
-
|
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
|
-
|
87
|
-
|
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
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
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
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
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
|
-
|
4
|
-
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|