qonfig 0.16.0 → 0.17.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/.rubocop.yml +5 -1
- data/.travis.yml +6 -6
- data/CHANGELOG.md +17 -0
- data/README.md +630 -49
- data/gemfiles/with_external_deps.gemfile +2 -2
- data/lib/qonfig/commands/{add_nested_option.rb → definition/add_nested_option.rb} +1 -1
- data/lib/qonfig/commands/{add_option.rb → definition/add_option.rb} +1 -1
- data/lib/qonfig/commands/{compose.rb → definition/compose.rb} +1 -1
- data/lib/qonfig/commands/{expose_json.rb → definition/expose_json.rb} +1 -1
- data/lib/qonfig/commands/{expose_self.rb → definition/expose_self.rb} +1 -1
- data/lib/qonfig/commands/{expose_yaml.rb → definition/expose_yaml.rb} +1 -1
- data/lib/qonfig/commands/definition/load_from_env/value_converter.rb +82 -0
- data/lib/qonfig/commands/{load_from_env.rb → definition/load_from_env.rb} +1 -1
- data/lib/qonfig/commands/{load_from_json.rb → definition/load_from_json.rb} +1 -1
- data/lib/qonfig/commands/{load_from_self.rb → definition/load_from_self.rb} +1 -1
- data/lib/qonfig/commands/{load_from_yaml.rb → definition/load_from_yaml.rb} +1 -1
- data/lib/qonfig/commands/definition.rb +16 -0
- data/lib/qonfig/commands/instantiation/values_file.rb +171 -0
- data/lib/qonfig/commands/instantiation.rb +7 -0
- data/lib/qonfig/commands.rb +2 -10
- data/lib/qonfig/data_set/lock.rb +61 -4
- data/lib/qonfig/data_set.rb +151 -3
- data/lib/qonfig/dsl.rb +56 -16
- data/lib/qonfig/errors.rb +38 -11
- data/lib/qonfig/loaders/dynamic.rb +52 -0
- data/lib/qonfig/loaders/json.rb +6 -0
- data/lib/qonfig/loaders/yaml.rb +13 -0
- data/lib/qonfig/loaders.rb +3 -0
- data/lib/qonfig/plugins/toml/data_set.rb +13 -0
- data/lib/qonfig/plugins/toml/dsl.rb +6 -2
- data/lib/qonfig/plugins/toml/errors.rb +12 -0
- data/lib/qonfig/plugins/toml/loaders/dynamic.rb +31 -0
- data/lib/qonfig/plugins/toml/loaders/toml.rb +6 -0
- data/lib/qonfig/plugins/toml.rb +2 -0
- data/lib/qonfig/settings/builder.rb +1 -1
- data/lib/qonfig/settings.rb +21 -0
- data/lib/qonfig/validator/basic.rb +9 -1
- data/lib/qonfig/validator/builder/attribute_consistency.rb +29 -0
- data/lib/qonfig/validator/builder.rb +39 -14
- data/lib/qonfig/validator/dsl.rb +9 -1
- data/lib/qonfig/validator/method_based.rb +4 -2
- data/lib/qonfig/validator/predefined/common.rb +4 -2
- data/lib/qonfig/validator/predefined/registry.rb +0 -2
- data/lib/qonfig/validator/predefined/registry_control_mixin.rb +3 -2
- data/lib/qonfig/validator/proc_based.rb +4 -2
- data/lib/qonfig/version.rb +1 -1
- data/qonfig.gemspec +1 -1
- metadata +21 -15
- data/lib/qonfig/commands/load_from_env/value_converter.rb +0 -84
data/lib/qonfig/data_set.rb
CHANGED
@@ -13,19 +13,24 @@ class Qonfig::DataSet # rubocop:disable Metrics/ClassLength
|
|
13
13
|
extend Qonfig::Validator::DSL
|
14
14
|
|
15
15
|
class << self
|
16
|
+
# @param base_dataset_klass [Class<Qonfig::DataSet>]
|
16
17
|
# @param config_klass_definitions [Proc]
|
17
18
|
# @return [Qonfig::DataSet]
|
18
19
|
#
|
19
20
|
# @api public
|
20
21
|
# @since 0.16.0
|
21
|
-
def build(&config_klass_definitions)
|
22
|
-
|
22
|
+
def build(base_dataset_klass = self, &config_klass_definitions)
|
23
|
+
unless base_dataset_klass <= Qonfig::DataSet
|
24
|
+
raise(Qonfig::ArgumentError, 'Base inherited class should be a type of Qonfig::DataSet')
|
25
|
+
end
|
26
|
+
|
27
|
+
Class.new(base_dataset_klass, &config_klass_definitions).new
|
23
28
|
end
|
24
29
|
end
|
25
30
|
|
26
31
|
# @return [Qonfig::Settings]
|
27
32
|
#
|
28
|
-
# @api
|
33
|
+
# @api public
|
29
34
|
# @since 0.1.0
|
30
35
|
attr_reader :settings
|
31
36
|
|
@@ -70,6 +75,65 @@ class Qonfig::DataSet # rubocop:disable Metrics/ClassLength
|
|
70
75
|
end
|
71
76
|
end
|
72
77
|
|
78
|
+
# @param file_path [String, Symbol]
|
79
|
+
# @option format [String, Symbol]
|
80
|
+
# @option strict [Boolean]
|
81
|
+
# @option expose [NilClass, String, Symbol] Environment key
|
82
|
+
# @return [void]
|
83
|
+
#
|
84
|
+
# @see Qonfig::DataSet#load_setting_values_from_file
|
85
|
+
#
|
86
|
+
# @api public
|
87
|
+
# @since 0.17.0
|
88
|
+
def load_from_file(file_path, format: :dynamic, strict: true, expose: nil)
|
89
|
+
thread_safe_access do
|
90
|
+
load_setting_values_from_file(file_path, format: format, strict: strict, expose: expose)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# @param file_path [String]
|
95
|
+
# @option strict [Boolean]
|
96
|
+
# @option expose [NilClass, String, Symbol] Environment key
|
97
|
+
# @return [void]
|
98
|
+
#
|
99
|
+
# @see Qonfig::DataSet#load_from_file
|
100
|
+
#
|
101
|
+
# @api public
|
102
|
+
# @since 0.17.0
|
103
|
+
def load_from_yaml(file_path, strict: true, expose: nil)
|
104
|
+
load_from_file(file_path, format: :yml, strict: strict, expose: expose)
|
105
|
+
end
|
106
|
+
|
107
|
+
# @param file_path [String]
|
108
|
+
# @option strict [Boolean]
|
109
|
+
# @option expose [NilClass, String, Symbol] Environment key
|
110
|
+
# @return [void]
|
111
|
+
#
|
112
|
+
# @see Qonfig::DataSet#load_from_file
|
113
|
+
#
|
114
|
+
# @api public
|
115
|
+
# @since 0.17.0
|
116
|
+
def load_from_json(file_path, strict: true, expose: nil)
|
117
|
+
load_from_file(file_path, format: :json, strict: strict, expose: expose)
|
118
|
+
end
|
119
|
+
|
120
|
+
# @option format [String, Symbol]
|
121
|
+
# @option strict [Boolean]
|
122
|
+
# @option expose [NilClass, String, Symbol]
|
123
|
+
# @return [void]
|
124
|
+
#
|
125
|
+
# @api public
|
126
|
+
# @since 0.17.0
|
127
|
+
def load_from_self(format: :dynamic, strict: true, expose: nil)
|
128
|
+
caller_location = caller(1, 1).first
|
129
|
+
|
130
|
+
thread_safe_access do
|
131
|
+
load_setting_values_from_file(
|
132
|
+
:self, format: format, strict: strict, expose: expose, caller_location: caller_location
|
133
|
+
)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
73
137
|
# @param settings_map [Hash]
|
74
138
|
# @return [void]
|
75
139
|
#
|
@@ -184,6 +248,17 @@ class Qonfig::DataSet # rubocop:disable Metrics/ClassLength
|
|
184
248
|
thread_safe_access { settings.__subset__(*keys) }
|
185
249
|
end
|
186
250
|
|
251
|
+
# @param key_path [Array<String, Symbol>]
|
252
|
+
# @return [Boolean]
|
253
|
+
#
|
254
|
+
# @api public
|
255
|
+
# @since 0.17.0
|
256
|
+
def key?(*key_path)
|
257
|
+
thread_safe_access { settings.__has_key__(*key_path) }
|
258
|
+
end
|
259
|
+
alias_method :option?, :key?
|
260
|
+
alias_method :setting?, :key?
|
261
|
+
|
187
262
|
# @return [void]
|
188
263
|
#
|
189
264
|
# @api public
|
@@ -234,6 +309,41 @@ class Qonfig::DataSet # rubocop:disable Metrics/ClassLength
|
|
234
309
|
thread_safe_access { validator.validate! }
|
235
310
|
end
|
236
311
|
|
312
|
+
# @param temporary_configurations [Hash<Symbol|String,Any>]
|
313
|
+
# @param arbitary_code [Block]
|
314
|
+
# @return [void]
|
315
|
+
#
|
316
|
+
# @api public
|
317
|
+
# @since 0.17.0
|
318
|
+
def with(temporary_configurations = {}, &arbitary_code)
|
319
|
+
with_arbitary_access do
|
320
|
+
begin
|
321
|
+
original_settings = @settings
|
322
|
+
|
323
|
+
temporary_settings = self.class.build.dup.tap do |copied_config|
|
324
|
+
copied_config.configure(temporary_configurations)
|
325
|
+
end.settings
|
326
|
+
|
327
|
+
@settings = temporary_settings
|
328
|
+
yield if block_given?
|
329
|
+
ensure
|
330
|
+
@settings = original_settings
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
# @return [Qonfig::DataSet]
|
336
|
+
#
|
337
|
+
# @api public
|
338
|
+
# @since 0.17.0
|
339
|
+
def dup
|
340
|
+
thread_safe_definition do
|
341
|
+
self.class.build.tap do |duplicate|
|
342
|
+
duplicate.configure(to_h)
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
237
347
|
private
|
238
348
|
|
239
349
|
# @return [Qonfig::Validator]
|
@@ -270,6 +380,16 @@ class Qonfig::DataSet # rubocop:disable Metrics/ClassLength
|
|
270
380
|
yield(settings) if block_given?
|
271
381
|
end
|
272
382
|
|
383
|
+
# @return [void]
|
384
|
+
#
|
385
|
+
# @api private
|
386
|
+
# @since 0.17.0
|
387
|
+
def call_instance_management_commands
|
388
|
+
self.class.instance_commands.each do |instance_command|
|
389
|
+
instance_command.call(self, settings)
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
273
393
|
# @param settings_map [Hash]
|
274
394
|
# @param configurations [Proc]
|
275
395
|
# @return [void]
|
@@ -279,9 +399,33 @@ class Qonfig::DataSet # rubocop:disable Metrics/ClassLength
|
|
279
399
|
def load!(settings_map = {}, &configurations)
|
280
400
|
build_validator
|
281
401
|
build_settings
|
402
|
+
call_instance_management_commands
|
282
403
|
apply_settings(settings_map, &configurations)
|
283
404
|
end
|
284
405
|
|
406
|
+
# @param file_path [String, Symbol]
|
407
|
+
# @option format [String, Symbol]
|
408
|
+
# @option strict [Boolean]
|
409
|
+
# @option expose [NilClass, String, Symbol]
|
410
|
+
# @option callcer_location [NilClass, String]
|
411
|
+
# @return [void]
|
412
|
+
#
|
413
|
+
# @see Qonfig::Commands::Instantiation::ValuesFile
|
414
|
+
#
|
415
|
+
# @api private
|
416
|
+
# @since 0.17.0
|
417
|
+
def load_setting_values_from_file(
|
418
|
+
file_path,
|
419
|
+
format: :dynamic,
|
420
|
+
strict: true,
|
421
|
+
expose: nil,
|
422
|
+
caller_location: nil
|
423
|
+
)
|
424
|
+
Qonfig::Commands::Instantiation::ValuesFile.new(
|
425
|
+
file_path, caller_location, format: format, strict: strict, expose: expose
|
426
|
+
).call(self, settings)
|
427
|
+
end
|
428
|
+
|
285
429
|
# @param instructions [Proc]
|
286
430
|
# @return [Object]
|
287
431
|
#
|
@@ -299,4 +443,8 @@ class Qonfig::DataSet # rubocop:disable Metrics/ClassLength
|
|
299
443
|
def thread_safe_definition(&instructions)
|
300
444
|
@__lock__.thread_safe_definition(&instructions)
|
301
445
|
end
|
446
|
+
|
447
|
+
def with_arbitary_access(&instructions)
|
448
|
+
@__lock__.with_arbitary_access(&instructions)
|
449
|
+
end
|
302
450
|
end
|
data/lib/qonfig/dsl.rb
CHANGED
@@ -10,12 +10,16 @@ module Qonfig::DSL
|
|
10
10
|
# @api private
|
11
11
|
# @since 0.1.0
|
12
12
|
def extended(child_klass)
|
13
|
-
child_klass.instance_variable_set(:@
|
13
|
+
child_klass.instance_variable_set(:@definition_commands, Qonfig::CommandSet.new)
|
14
|
+
child_klass.instance_variable_set(:@instance_commands, Qonfig::CommandSet.new)
|
14
15
|
|
15
16
|
child_klass.singleton_class.prepend(Module.new do
|
16
17
|
def inherited(child_klass)
|
17
|
-
child_klass.instance_variable_set(:@
|
18
|
-
child_klass.
|
18
|
+
child_klass.instance_variable_set(:@definition_commands, Qonfig::CommandSet.new)
|
19
|
+
child_klass.instance_variable_set(:@instance_commands, Qonfig::CommandSet.new)
|
20
|
+
|
21
|
+
child_klass.definition_commands.concat(definition_commands)
|
22
|
+
child_klass.instance_commands.concat(instance_commands)
|
19
23
|
super
|
20
24
|
end
|
21
25
|
end)
|
@@ -25,9 +29,17 @@ module Qonfig::DSL
|
|
25
29
|
# @return [Qonfig::CommandSet]
|
26
30
|
#
|
27
31
|
# @api private
|
28
|
-
# @since 0.
|
29
|
-
def
|
30
|
-
@
|
32
|
+
# @since 0.17.0
|
33
|
+
def definition_commands
|
34
|
+
@definition_commands
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [Qonfig::CommandSet]
|
38
|
+
#
|
39
|
+
# @api private
|
40
|
+
# @since 0.17.0
|
41
|
+
def instance_commands
|
42
|
+
@instance_commands
|
31
43
|
end
|
32
44
|
|
33
45
|
# @param key [Symbol, String]
|
@@ -42,9 +54,9 @@ module Qonfig::DSL
|
|
42
54
|
# @since 0.1.0
|
43
55
|
def setting(key, initial_value = nil, &nested_settings)
|
44
56
|
if block_given?
|
45
|
-
|
57
|
+
definition_commands << Qonfig::Commands::Definition::AddNestedOption.new(key, nested_settings)
|
46
58
|
else
|
47
|
-
|
59
|
+
definition_commands << Qonfig::Commands::Definition::AddOption.new(key, initial_value)
|
48
60
|
end
|
49
61
|
end
|
50
62
|
|
@@ -56,7 +68,7 @@ module Qonfig::DSL
|
|
56
68
|
# @api private
|
57
69
|
# @sine 0.1.0
|
58
70
|
def compose(data_set_klass)
|
59
|
-
|
71
|
+
definition_commands << Qonfig::Commands::Definition::Compose.new(data_set_klass)
|
60
72
|
end
|
61
73
|
|
62
74
|
# @param file_path [String]
|
@@ -68,7 +80,9 @@ module Qonfig::DSL
|
|
68
80
|
# @api public
|
69
81
|
# @since 0.2.0
|
70
82
|
def load_from_yaml(file_path, strict: true)
|
71
|
-
|
83
|
+
definition_commands << Qonfig::Commands::Definition::LoadFromYAML.new(
|
84
|
+
file_path, strict: strict
|
85
|
+
)
|
72
86
|
end
|
73
87
|
|
74
88
|
# @return [void]
|
@@ -79,7 +93,10 @@ module Qonfig::DSL
|
|
79
93
|
# @since 0.2.0
|
80
94
|
def load_from_self(format: :yaml)
|
81
95
|
caller_location = caller(1, 1).first
|
82
|
-
|
96
|
+
|
97
|
+
definition_commands << Qonfig::Commands::Definition::LoadFromSelf.new(
|
98
|
+
caller_location, format: format
|
99
|
+
)
|
83
100
|
end
|
84
101
|
|
85
102
|
# @option convert_values [Boolean]
|
@@ -91,7 +108,7 @@ module Qonfig::DSL
|
|
91
108
|
# @api public
|
92
109
|
# @since 0.2.0
|
93
110
|
def load_from_env(convert_values: false, prefix: nil, trim_prefix: false)
|
94
|
-
|
111
|
+
definition_commands << Qonfig::Commands::Definition::LoadFromENV.new(
|
95
112
|
convert_values: convert_values,
|
96
113
|
prefix: prefix,
|
97
114
|
trim_prefix: trim_prefix
|
@@ -105,7 +122,7 @@ module Qonfig::DSL
|
|
105
122
|
# @api public
|
106
123
|
# @since 0.5.0
|
107
124
|
def load_from_json(file_path, strict: true)
|
108
|
-
|
125
|
+
definition_commands << Qonfig::Commands::Definition::LoadFromJSON.new(file_path, strict: strict)
|
109
126
|
end
|
110
127
|
|
111
128
|
# @param file_path [String]
|
@@ -117,7 +134,9 @@ module Qonfig::DSL
|
|
117
134
|
# @api public
|
118
135
|
# @since 0.7.0
|
119
136
|
def expose_yaml(file_path, strict: true, via:, env:)
|
120
|
-
|
137
|
+
definition_commands << Qonfig::Commands::Definition::ExposeYAML.new(
|
138
|
+
file_path, strict: strict, via: via, env: env
|
139
|
+
)
|
121
140
|
end
|
122
141
|
|
123
142
|
# @param file_path [String]
|
@@ -129,7 +148,9 @@ module Qonfig::DSL
|
|
129
148
|
# @api public
|
130
149
|
# @since 0.14.0
|
131
150
|
def expose_json(file_path, strict: true, via:, env:)
|
132
|
-
|
151
|
+
definition_commands << Qonfig::Commands::Definition::ExposeJSON.new(
|
152
|
+
file_path, strict: strict, via: via, env: env
|
153
|
+
)
|
133
154
|
end
|
134
155
|
|
135
156
|
# @option env [Symbol, String]
|
@@ -141,6 +162,25 @@ module Qonfig::DSL
|
|
141
162
|
# @since 0.14.0
|
142
163
|
def expose_self(env:, format: :yaml)
|
143
164
|
caller_location = caller(1, 1).first
|
144
|
-
|
165
|
+
|
166
|
+
definition_commands << Qonfig::Commands::Definition::ExposeSelf.new(
|
167
|
+
caller_location, env: env, format: format
|
168
|
+
)
|
169
|
+
end
|
170
|
+
|
171
|
+
# @param file_path [String]
|
172
|
+
# @option format [String, Symbol]
|
173
|
+
# @option strict [Boolean]
|
174
|
+
# @option expose [NilClass, String, Symbol] Environment key
|
175
|
+
# @return [void]
|
176
|
+
#
|
177
|
+
# @api public
|
178
|
+
# @since 0.17.0
|
179
|
+
def values_file(file_path, format: :dynamic, strict: false, expose: nil)
|
180
|
+
caller_location = caller(1, 1).first
|
181
|
+
|
182
|
+
instance_commands << Qonfig::Commands::Instantiation::ValuesFile.new(
|
183
|
+
file_path, caller_location, format: format, strict: strict, expose: expose
|
184
|
+
)
|
145
185
|
end
|
146
186
|
end
|
data/lib/qonfig/errors.rb
CHANGED
@@ -47,8 +47,8 @@ module Qonfig
|
|
47
47
|
|
48
48
|
# @see Qonfig::Settings
|
49
49
|
# @see Qonfig::Settings::KeyGuard
|
50
|
-
# @see Qonfig::Commands::AddOption
|
51
|
-
# @see Qonfig::Commands::AddNestedOption
|
50
|
+
# @see Qonfig::Commands::Definition::AddOption
|
51
|
+
# @see Qonfig::Commands::Definition::AddNestedOption
|
52
52
|
#
|
53
53
|
# @api public
|
54
54
|
# @since 0.2.0
|
@@ -69,24 +69,30 @@ module Qonfig
|
|
69
69
|
# :nocov:
|
70
70
|
end
|
71
71
|
|
72
|
-
# @see Qonfig::Commands::
|
72
|
+
# @see Qonfig::Commands::Instantiation::ValuesFile
|
73
|
+
#
|
74
|
+
# @api public
|
75
|
+
# @since 0.17.0
|
76
|
+
IncompatibleDataStructureError = Class.new(Error)
|
77
|
+
|
78
|
+
# @see Qonfig::Commands::Definition::LoadFromYAML
|
73
79
|
#
|
74
80
|
# @api public
|
75
81
|
# @since 0.2.0
|
76
|
-
IncompatibleYAMLStructureError = Class.new(
|
82
|
+
IncompatibleYAMLStructureError = Class.new(IncompatibleDataStructureError)
|
77
83
|
|
78
|
-
# @see Qonfig::Commands::LoadFromJSON
|
84
|
+
# @see Qonfig::Commands::Definition::LoadFromJSON
|
79
85
|
#
|
80
86
|
# @api public
|
81
87
|
# @since 0.5.0
|
82
|
-
IncompatibleJSONStructureError = Class.new(
|
88
|
+
IncompatibleJSONStructureError = Class.new(IncompatibleDataStructureError)
|
83
89
|
|
84
|
-
# @see Qonfig::Commands::LoadFromSelf
|
85
|
-
# @see Qonfig::Commands::ExposeSelf
|
90
|
+
# @see Qonfig::Commands::Definition::LoadFromSelf
|
91
|
+
# @see Qonfig::Commands::Definition::ExposeSelf
|
86
92
|
#
|
87
93
|
# @api public
|
88
94
|
# @since 0.15.0
|
89
|
-
IncompatibleEndDataStructureError = Class.new(
|
95
|
+
IncompatibleEndDataStructureError = Class.new(IncompatibleDataStructureError)
|
90
96
|
|
91
97
|
# @see Qonfig::Loaders::YAML
|
92
98
|
#
|
@@ -94,12 +100,33 @@ module Qonfig
|
|
94
100
|
# @since 0.2.0
|
95
101
|
FileNotFoundError = Class.new(Errno::ENOENT)
|
96
102
|
|
97
|
-
# @see Qonfig::Commands::LoadFromSelf
|
103
|
+
# @see Qonfig::Commands::Definition::LoadFromSelf
|
104
|
+
# @see Qonfig::Loaders::EndData
|
98
105
|
#
|
99
106
|
# @api public
|
100
107
|
# @since 0.2.0
|
101
108
|
SelfDataNotFoundError = Class.new(Error)
|
102
109
|
|
110
|
+
# @see Qonfig::Loaders::JSON
|
111
|
+
# @see Qonfig::Loaders::Dynamic
|
112
|
+
#
|
113
|
+
# @api public
|
114
|
+
# @since 0.17.0
|
115
|
+
JSONLoaderParseError = Class.new(::JSON::ParserError)
|
116
|
+
|
117
|
+
# @see Qonfig::Loaders::YAML
|
118
|
+
# @see Qonfig::Loaders::Dynamic
|
119
|
+
#
|
120
|
+
# @api public
|
121
|
+
# @since 0.17.0
|
122
|
+
YAMLLoaderParseError = Class.new(::Psych::SyntaxError)
|
123
|
+
|
124
|
+
# @see Qonfig::Loaders::Dynamic
|
125
|
+
#
|
126
|
+
# @api public
|
127
|
+
# @since 0.17.0
|
128
|
+
DynamicLoaderParseError = Class.new(Error)
|
129
|
+
|
103
130
|
# @see Qonfig::Plugins::Regsitry
|
104
131
|
#
|
105
132
|
# @api private
|
@@ -112,7 +139,7 @@ module Qonfig
|
|
112
139
|
# @since 0.4.0
|
113
140
|
UnregisteredPluginError = Class.new(Error)
|
114
141
|
|
115
|
-
# @see Qonfig::Commands::ExposeYAML
|
142
|
+
# @see Qonfig::Commands::Definition::ExposeYAML
|
116
143
|
#
|
117
144
|
# @api public
|
118
145
|
# @since 0.7.0
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.17.0
|
5
|
+
class Qonfig::Loaders::Dynamic < Qonfig::Loaders::Basic
|
6
|
+
class << self
|
7
|
+
# @param data [String]
|
8
|
+
# @return [Object]
|
9
|
+
#
|
10
|
+
# @raise [Qonfig::DynamicLoaderParseError]
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
# @since 0.17.0
|
14
|
+
def load(data)
|
15
|
+
try_to_load_json_data(data)
|
16
|
+
rescue Qonfig::JSONLoaderParseError
|
17
|
+
begin
|
18
|
+
try_to_load_yaml_data(data)
|
19
|
+
rescue Qonfig::YAMLLoaderParseError
|
20
|
+
raise Qonfig::DynamicLoaderParseError, 'File data has unknown format'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Hash]
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
# @since 0.17.0
|
28
|
+
def load_empty_data
|
29
|
+
{}
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# @param data [String]
|
35
|
+
# @return [Object]
|
36
|
+
#
|
37
|
+
# @api private
|
38
|
+
# @since 0.17.0
|
39
|
+
def try_to_load_yaml_data(data)
|
40
|
+
Qonfig::Loaders::YAML.load(data)
|
41
|
+
end
|
42
|
+
|
43
|
+
# @param data [String]
|
44
|
+
# @return [Object]
|
45
|
+
#
|
46
|
+
# @api private
|
47
|
+
# @since 0.17.0
|
48
|
+
def try_to_load_json_data(data)
|
49
|
+
Qonfig::Loaders::JSON.load(data)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/qonfig/loaders/json.rb
CHANGED
@@ -7,10 +7,16 @@ class Qonfig::Loaders::JSON < Qonfig::Loaders::Basic
|
|
7
7
|
# @param data [String]
|
8
8
|
# @return [Object]
|
9
9
|
#
|
10
|
+
# @raise [Qonfig::JSONLoaderParseError]
|
11
|
+
#
|
10
12
|
# @api private
|
11
13
|
# @since 0.5.0
|
12
14
|
def load(data)
|
13
15
|
::JSON.parse(data, max_nesting: false, allow_nan: true)
|
16
|
+
rescue ::JSON::ParserError => error
|
17
|
+
raise(Qonfig::JSONLoaderParseError.new(error.message).tap do |exception|
|
18
|
+
exception.set_backtrace(error.backtrace)
|
19
|
+
end)
|
14
20
|
end
|
15
21
|
|
16
22
|
# @return [Object]
|
data/lib/qonfig/loaders/yaml.rb
CHANGED
@@ -7,10 +7,23 @@ class Qonfig::Loaders::YAML < Qonfig::Loaders::Basic
|
|
7
7
|
# @param data [String]
|
8
8
|
# @return [Object]
|
9
9
|
#
|
10
|
+
# @raise [Qonfig::YAMLLoaderParseError]
|
11
|
+
#
|
10
12
|
# @api private
|
11
13
|
# @since 0.2.0
|
12
14
|
def load(data)
|
13
15
|
::YAML.load(ERB.new(data).result)
|
16
|
+
rescue ::Psych::SyntaxError => error
|
17
|
+
raise(
|
18
|
+
Qonfig::YAMLLoaderParseError.new(
|
19
|
+
error.file,
|
20
|
+
error.line,
|
21
|
+
error.column,
|
22
|
+
error.offset,
|
23
|
+
error.problem,
|
24
|
+
error.context
|
25
|
+
).tap { |exception| exception.set_backtrace(error.backtrace) }
|
26
|
+
)
|
14
27
|
end
|
15
28
|
|
16
29
|
# @return [Object]
|
data/lib/qonfig/loaders.rb
CHANGED
@@ -6,6 +6,7 @@ module Qonfig::Loaders
|
|
6
6
|
require_relative 'loaders/basic'
|
7
7
|
require_relative 'loaders/json'
|
8
8
|
require_relative 'loaders/yaml'
|
9
|
+
require_relative 'loaders/dynamic'
|
9
10
|
require_relative 'loaders/end_data'
|
10
11
|
|
11
12
|
class << self
|
@@ -22,6 +23,8 @@ module Qonfig::Loaders
|
|
22
23
|
Qonfig::Loaders::YAML
|
23
24
|
when 'json'
|
24
25
|
Qonfig::Loaders::JSON
|
26
|
+
when 'dynamic'
|
27
|
+
Qonfig::Loaders::Dynamic
|
25
28
|
else
|
26
29
|
raise(Qonfig::UnsupportedLoaderFormatError, "<#{format}> format is not supported.")
|
27
30
|
end
|
@@ -16,4 +16,17 @@ class Qonfig::DataSet
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
alias_method :dump_to_toml, :save_to_toml
|
19
|
+
|
20
|
+
# @param file_path [String]
|
21
|
+
# @option strict [Boolean]
|
22
|
+
# @option expose [NilClass, String, Symbol] Environment key
|
23
|
+
# @return [void]
|
24
|
+
#
|
25
|
+
# @see Qonfig::DataSet#load_from_file
|
26
|
+
#
|
27
|
+
# @api public
|
28
|
+
# @since 0.17.0
|
29
|
+
def load_from_toml(file_path, strict: true, expose: nil)
|
30
|
+
load_from_file(file_path, format: :toml, strict: strict, expose: expose)
|
31
|
+
end
|
19
32
|
end
|
@@ -10,7 +10,9 @@ module Qonfig::DSL
|
|
10
10
|
# @api public
|
11
11
|
# @since 0.12.0
|
12
12
|
def load_from_toml(file_path, strict: true)
|
13
|
-
|
13
|
+
definition_commands << Qonfig::Commands::LoadFromTOML.new(
|
14
|
+
file_path, strict: strict
|
15
|
+
)
|
14
16
|
end
|
15
17
|
|
16
18
|
# @param file_path [String]
|
@@ -22,6 +24,8 @@ module Qonfig::DSL
|
|
22
24
|
# @api public
|
23
25
|
# @since 0.12.0
|
24
26
|
def expose_toml(file_path, strict: true, via:, env:)
|
25
|
-
|
27
|
+
definition_commands << Qonfig::Commands::ExposeTOML.new(
|
28
|
+
file_path, strict: strict, via: via, env: env
|
29
|
+
)
|
26
30
|
end
|
27
31
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.17.0
|
5
|
+
class Qonfig::Loaders::Dynamic < Qonfig::Loaders::Basic
|
6
|
+
class << self
|
7
|
+
prepend(Module.new do
|
8
|
+
# @param data [String]
|
9
|
+
# @return [Object]
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
# @since 0.17.0
|
13
|
+
def load(data)
|
14
|
+
try_to_load_toml_data(data)
|
15
|
+
rescue Qonfig::TOMLLoaderParseError
|
16
|
+
super(data)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# @param data [String]
|
22
|
+
# @return [Object]
|
23
|
+
#
|
24
|
+
# @api private
|
25
|
+
# @since 0.17.0
|
26
|
+
def try_to_load_toml_data(data)
|
27
|
+
Qonfig::Loaders::TOML.load(data)
|
28
|
+
end
|
29
|
+
end)
|
30
|
+
end
|
31
|
+
end
|
@@ -7,10 +7,16 @@ class Qonfig::Loaders::TOML < Qonfig::Loaders::Basic
|
|
7
7
|
# @param data [String]
|
8
8
|
# @return [Object]
|
9
9
|
#
|
10
|
+
# @raise [Qonfig::TOMLLoaderParseError]
|
11
|
+
#
|
10
12
|
# @api private
|
11
13
|
# @since 0.12.0
|
12
14
|
def load(data)
|
13
15
|
::TomlRB.parse(ERB.new(data).result)
|
16
|
+
rescue ::TomlRB::ParseError => error
|
17
|
+
raise(Qonfig::TOMLLoaderParseError.new(error.message).tap do |exception|
|
18
|
+
exception.set_backtrace(error.backtrace)
|
19
|
+
end)
|
14
20
|
end
|
15
21
|
|
16
22
|
# @return [Object]
|
data/lib/qonfig/plugins/toml.rb
CHANGED
@@ -15,8 +15,10 @@ class Qonfig::Plugins::TOML < Qonfig::Plugins::Abstract
|
|
15
15
|
) unless const_defined?('::TomlRB')
|
16
16
|
|
17
17
|
require_relative 'toml/tomlrb_fixes'
|
18
|
+
require_relative 'toml/errors'
|
18
19
|
require_relative 'toml/loaders'
|
19
20
|
require_relative 'toml/loaders/toml'
|
21
|
+
require_relative 'toml/loaders/dynamic'
|
20
22
|
require_relative 'toml/uploaders/toml'
|
21
23
|
require_relative 'toml/commands/load_from_toml'
|
22
24
|
require_relative 'toml/commands/expose_toml'
|
@@ -11,7 +11,7 @@ module Qonfig::Settings::Builder
|
|
11
11
|
# @since 0.2.0
|
12
12
|
def build(data_set)
|
13
13
|
Qonfig::Settings.new(build_mutation_callbacks(data_set)).tap do |settings|
|
14
|
-
data_set.class.
|
14
|
+
data_set.class.definition_commands.dup.each do |command|
|
15
15
|
command.call(data_set, settings)
|
16
16
|
end
|
17
17
|
end
|