qonfig 0.20.0 → 0.21.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.
@@ -23,18 +23,5 @@ module Qonfig::DataSet::ClassBuilder
23
23
  end
24
24
  end
25
25
  end
26
-
27
- # @option base_klass [Class<Qonfig::DataSet>]
28
- # @option child_klass [Class<Qonfig::DataSet>]
29
- # @return [void]
30
- #
31
- # @api private
32
- # @since 0.19.0
33
- def inherit(base_klass:, child_klass:)
34
- child_klass.definition_commands.concat(base_klass.definition_commands)
35
- child_klass.instance_commands.concat(base_klass.instance_commands, &:inheritable?)
36
- child_klass.predefined_validators.merge(base_klass.predefined_validators)
37
- child_klass.validators.concat(base_klass.validators)
38
- end
39
26
  end
40
27
  end
data/lib/qonfig/dsl.rb CHANGED
@@ -4,8 +4,10 @@
4
4
  # @since 0.1.0
5
5
  # @version 0.20.0
6
6
  module Qonfig::DSL # rubocop:disable Metrics/ModuleLength
7
+ require_relative 'dsl/inheritance'
8
+
7
9
  class << self
8
- # @param child_klass [Qonfig::DataSet]
10
+ # @param child_klass [Class<Qonfig::DataSet>]
9
11
  # @return [void]
10
12
  #
11
13
  # @see Qonfig::DataSet::ClassBuilder
@@ -26,7 +28,7 @@ module Qonfig::DSL # rubocop:disable Metrics/ModuleLength
26
28
  child_klass.instance_variable_set(:@instance_commands, Qonfig::CommandSet.new)
27
29
  child_klass.instance_variable_set(:@predefined_validators, Qonfig::Validation::Collections::PredefinedRegistry.new)
28
30
  child_klass.instance_variable_set(:@validators, Qonfig::Validation::Collections::InstanceCollection.new)
29
- Qonfig::DataSet::ClassBuilder.inherit(base_klass: self, child_klass: child_klass)
31
+ Qonfig::DSL::Inheritance.inherit(base: self, child: child_klass)
30
32
  super
31
33
  end
32
34
  end)
@@ -166,14 +168,16 @@ module Qonfig::DSL # rubocop:disable Metrics/ModuleLength
166
168
  )
167
169
  end
168
170
 
171
+ # @option format [Symbol, String]
169
172
  # @return [void]
170
173
  #
171
174
  # @see Qonfig::Commands::Definition::LoadFromSelf
172
175
  #
173
176
  # @api public
174
177
  # @since 0.2.0
175
- def load_from_self(format: :yaml)
176
- caller_location = caller(1, 1).first
178
+ # @version 0.21.0
179
+ def load_from_self(format: :dynamic)
180
+ caller_location = ::Kernel.caller(1, 1).first
177
181
 
178
182
  definition_commands << Qonfig::Commands::Definition::LoadFromSelf.new(
179
183
  caller_location, format: format
@@ -241,14 +245,16 @@ module Qonfig::DSL # rubocop:disable Metrics/ModuleLength
241
245
  end
242
246
 
243
247
  # @option env [Symbol, String]
248
+ # @option format [Symbol, String]
244
249
  # @return [void]
245
250
  #
246
251
  # @see Qonfig::Commands::Definition::ExposeSelf
247
252
  #
248
253
  # @api public
249
254
  # @since 0.14.0
250
- def expose_self(env:, format: :yaml)
251
- caller_location = caller(1, 1).first
255
+ # @version 0.21.0
256
+ def expose_self(env:, format: :dynamic)
257
+ caller_location = ::Kernel.caller(1, 1).first
252
258
 
253
259
  definition_commands << Qonfig::Commands::Definition::ExposeSelf.new(
254
260
  caller_location, env: env, format: format
@@ -266,7 +272,7 @@ module Qonfig::DSL # rubocop:disable Metrics/ModuleLength
266
272
  # @api public
267
273
  # @since 0.17.0
268
274
  def values_file(file_path, format: :dynamic, strict: false, expose: nil)
269
- caller_location = caller(1, 1).first
275
+ caller_location = ::Kernel.caller(1, 1).first
270
276
 
271
277
  instance_commands << Qonfig::Commands::Instantiation::ValuesFile.new(
272
278
  file_path, caller_location, format: format, strict: strict, expose: expose
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.21.0
5
+ module Qonfig::DSL::Inheritance
6
+ class << self
7
+ # @option base [Class<Qonfig::DataSet>, Class<Qonfig::Compacted>]
8
+ # @option child [Class<Qonfig::DataSet>, Class<Qonfig::Compacted>]
9
+ # @return [void]
10
+ #
11
+ # @api private
12
+ # @since 0.21.0
13
+ def inherit(base:, child:)
14
+ child.definition_commands.concat(base.definition_commands)
15
+ child.instance_commands.concat(base.instance_commands, &:inheritable?)
16
+ child.predefined_validators.merge(base.predefined_validators)
17
+ child.validators.concat(base.validators)
18
+ end
19
+ end
20
+ end
@@ -15,19 +15,34 @@ class Qonfig::Imports::Abstract
15
15
  # @since 0.18.0
16
16
  DEFAULT_RAW_BEHAVIOR = false
17
17
 
18
+ # @return [Boolean]
19
+ #
20
+ # @api private
21
+ # @since 0.21.0
22
+ AS_ACCESSOR = false
23
+
18
24
  # @param seeded_klass [Class]
19
25
  # @param imported_config [Qonfig::DataSet]
20
26
  # @option prefix [String, Symbol]
21
27
  # @option raw [Boolean]
28
+ # @option accessor [Boolean]
22
29
  # @return [void]
23
30
  #
24
31
  # @api private
25
32
  # @since 0.18.0
26
- def initialize(seeded_klass, imported_config, prefix: EMPTY_PREFIX, raw: DEFAULT_RAW_BEHAVIOR)
33
+ # @version 0.21.0
34
+ def initialize(
35
+ seeded_klass,
36
+ imported_config,
37
+ prefix: EMPTY_PREFIX,
38
+ raw: DEFAULT_RAW_BEHAVIOR,
39
+ accessor: AS_ACCESSOR
40
+ )
27
41
  @seeded_klass = seeded_klass
28
42
  @imported_config = imported_config
29
43
  @prefix = prefix
30
44
  @raw = !!raw
45
+ @accessor = !!accessor
31
46
  end
32
47
 
33
48
  # @param settings_interface [Module]
@@ -67,6 +82,12 @@ class Qonfig::Imports::Abstract
67
82
  # @since 0.18.0
68
83
  attr_reader :imported_config
69
84
 
85
+ # @return [Boolean]
86
+ #
87
+ # @api private
88
+ # @since 0.21.0
89
+ attr_reader :accessor
90
+
70
91
  # @param imported_config [Qonfig::DataSet]
71
92
  # @param prefix [String, Symbol]
72
93
  # @return [void]
@@ -8,19 +8,22 @@ class Qonfig::Imports::DirectKey < Qonfig::Imports::Abstract
8
8
  # @param keys [Array<String,Symbol>]
9
9
  # @option prefix [String, Symbol]
10
10
  # @option raw [Boolean]
11
+ # @option accessor [Boolean]
11
12
  # @return [void]
12
13
  #
13
14
  # @api private
14
- # @since 0.18.8
15
+ # @since 0.18.0
16
+ # @version 0.21.0
15
17
  def initialize(
16
18
  seeded_klass,
17
19
  imported_config,
18
20
  *keys,
19
21
  prefix: EMPTY_PREFIX,
20
- raw: DEFAULT_RAW_BEHAVIOR
22
+ raw: DEFAULT_RAW_BEHAVIOR,
23
+ accessor: AS_ACCESSOR
21
24
  )
22
25
  prevent_incompatible_import_params!(imported_config, prefix, keys)
23
- super(seeded_klass, imported_config, prefix: prefix, raw: raw)
26
+ super(seeded_klass, imported_config, prefix: prefix, raw: raw, accessor: accessor)
24
27
  @keys = keys
25
28
  @key_matchers = build_setting_key_matchers(keys)
26
29
  end
@@ -30,14 +33,16 @@ class Qonfig::Imports::DirectKey < Qonfig::Imports::Abstract
30
33
  #
31
34
  # @api private
32
35
  # @since 0.18.0
33
- def import!(settings_interface = Module.new) # rubocop:disable Metrics/AbcSize
36
+ # @version 0.21.0
37
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/BlockLength
38
+ def import!(settings_interface = Module.new)
34
39
  key_matchers.each do |key_matcher|
35
40
  raise(
36
41
  Qonfig::UnknownSettingError,
37
42
  "Setting with <#{key_matcher.scope_pattern}> key does not exist!"
38
43
  ) unless (imported_config.keys(all_variants: true).any? do |setting_key|
39
44
  key_matcher.match?(setting_key)
40
- end)
45
+ end || key_matcher.generic?)
41
46
 
42
47
  imported_config.keys(all_variants: true).each do |setting_key|
43
48
  next unless key_matcher.match?(setting_key)
@@ -46,7 +51,9 @@ class Qonfig::Imports::DirectKey < Qonfig::Imports::Abstract
46
51
  access_method_name = setting_key_path_sequence.last
47
52
  access_method_name = "#{prefix}#{access_method_name}" unless prefix.empty?
48
53
 
49
- settings_interface.module_exec(raw, imported_config) do |raw, imported_config|
54
+ settings_interface.module_exec(
55
+ raw, imported_config, accessor
56
+ ) do |raw, imported_config, accessor|
50
57
  unless raw
51
58
  # NOTE: get setting value via slice_value
52
59
  define_method(access_method_name) do
@@ -58,10 +65,22 @@ class Qonfig::Imports::DirectKey < Qonfig::Imports::Abstract
58
65
  imported_config.dig(*setting_key_path_sequence)
59
66
  end
60
67
  end
68
+
69
+ define_method("#{access_method_name}?") do
70
+ # NOTE: based on Qonfig::Settings#__define_option_predicate__ realization
71
+ !!imported_config[setting_key]
72
+ end
73
+
74
+ if accessor
75
+ define_method("#{access_method_name}=") do |value|
76
+ imported_config[setting_key] = value
77
+ end
78
+ end
61
79
  end
62
80
  end
63
81
  end
64
82
  end
83
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/BlockLength
65
84
 
66
85
  private
67
86
 
@@ -22,16 +22,19 @@ module Qonfig::Imports::DSL
22
22
  # @option prefix [String, Symbol]
23
23
  # @option raw [Boolean]
24
24
  # @option mappings [Hash<String|Symbol,String|Symbol>]
25
+ # @option accessor [Boolean]
25
26
  # @return [void]
26
27
  #
27
28
  # @api public
28
29
  # @since 0.18.0
30
+ # @version 0.21.0
29
31
  def import_settings(
30
32
  imported_config,
31
33
  *imported_setting_keys,
32
34
  prefix: Qonfig::Imports::Abstract::EMPTY_PREFIX,
33
35
  raw: Qonfig::Imports::Abstract::DEFAULT_RAW_BEHAVIOR,
34
- mappings: Qonfig::Imports::Mappings::EMPTY_MAPPINGS
36
+ mappings: Qonfig::Imports::Mappings::EMPTY_MAPPINGS,
37
+ accessor: Qonfig::Imports::Abstract::AS_ACCESSOR
35
38
  )
36
39
  Qonfig::Imports::General.import!(
37
40
  self,
@@ -39,7 +42,8 @@ module Qonfig::Imports::DSL
39
42
  *imported_setting_keys,
40
43
  prefix: prefix,
41
44
  raw: raw,
42
- mappings: mappings
45
+ mappings: mappings,
46
+ accessor: accessor
43
47
  )
44
48
  end
45
49
  end
@@ -10,20 +10,31 @@ module Qonfig::Imports::Export
10
10
  # @option mappings [Hash<String|Symbol,String|Symbol>]
11
11
  # @option raw [Boolean]
12
12
  # @option prefix [String, Symbol]
13
+ # @option accessor [Boolean]
13
14
  # @return [void]
14
15
  #
15
16
  # @api private
16
17
  # @since 0.18.0
18
+ # @version 0.21.0
17
19
  def export!(
18
20
  exportable_object,
19
21
  exported_config,
20
22
  *exported_setting_keys,
21
23
  mappings: Qonfig::Imports::Mappings::EMPTY_MAPPINGS,
22
- raw: false,
23
- prefix: Qonfig::Imports::Abstract::EMPTY_PREFIX
24
+ raw: Qonfig::Imports::Abstract::DEFAULT_RAW_BEHAVIOR,
25
+ prefix: Qonfig::Imports::Abstract::EMPTY_PREFIX,
26
+ accessor: Qonfig::Imports::Abstract::AS_ACCESSOR
24
27
  )
25
- unless exportable_object.is_a?(Module)
26
- exportable_object = exportable_object.singleton_class
28
+ exportable_is_a_module = exportable_object.is_a?(Module) rescue false
29
+ # NOTE: (rescue false (rescue NoMethodError for #is_a?))
30
+ # it means that #is_a? is not defined for exportable_object.
31
+ # it happens only with BasicObject instances.
32
+
33
+ unless exportable_is_a_module
34
+ # NOTE:
35
+ # << is a universal way for extrating the singleton class of an object
36
+ # cuz BasicObject has no #singelton_class method;
37
+ exportable_object = (class << exportable_object; self; end)
27
38
  end
28
39
 
29
40
  Qonfig::Imports::General.import!(
@@ -32,7 +43,8 @@ module Qonfig::Imports::Export
32
43
  *exported_setting_keys,
33
44
  prefix: prefix,
34
45
  raw: raw,
35
- mappings: mappings
46
+ mappings: mappings,
47
+ accessor: accessor
36
48
  )
37
49
  end
38
50
  end
@@ -10,17 +10,20 @@ class Qonfig::Imports::General
10
10
  # @option mappings [Hash<String|Symbol,String|Symbol>]
11
11
  # @option prefix [String, Symbol]
12
12
  # @option raw [Boolean]
13
+ # @option accessor [Boolean]
13
14
  # @return void]
14
15
  #
15
16
  # @api private
16
17
  # @since 0.18.0
18
+ # @version 0.21.0
17
19
  def import!(
18
20
  seeded_klass,
19
21
  imported_config,
20
22
  *imported_keys,
21
23
  mappings: Qonfig::Imports::Mappings::EMPTY_MAPPINGS,
22
24
  prefix: Qonfig::Imports::Abstract::EMPTY_PREFIX,
23
- raw: false
25
+ raw: Qonfig::Imports::Abstract::DEFAULT_RAW_BEHAVIOR,
26
+ accessor: Qonfig::Imports::Abstract::AS_ACCESSOR
24
27
  )
25
28
  new(
26
29
  seeded_klass,
@@ -28,7 +31,8 @@ class Qonfig::Imports::General
28
31
  *imported_keys,
29
32
  mappings: mappings,
30
33
  prefix: prefix,
31
- raw: raw
34
+ raw: raw,
35
+ accessor: accessor
32
36
  ).import!
33
37
  end
34
38
  end
@@ -39,24 +43,39 @@ class Qonfig::Imports::General
39
43
  # @option mappings [Hash<String|Symbol,String|Symbol>]
40
44
  # @option prefix [String, Symbol]
41
45
  # @option raw [Boolean]
46
+ # @option accessor [Boolean]
42
47
  # @return void]
43
48
  #
44
49
  # @api private
45
50
  # @since 0.18.0
51
+ # @version 0.21.0
46
52
  def initialize(
47
53
  seeded_klass,
48
54
  imported_config,
49
55
  *imported_keys,
50
56
  mappings: Qonfig::Imports::Mappings::EMPTY_MAPPINGS,
51
57
  prefix: Qonfig::Imports::Abstract::EMPTY_PREFIX,
52
- raw: false
58
+ raw: Qonfig::Imports::Abstract::DEFAULT_RAW_BEHAVIOR,
59
+ accessor: Qonfig::Imports::Abstract::AS_ACCESSOR
53
60
  )
54
61
  @seeded_klass = seeded_klass
62
+
55
63
  @direct_key_importer = build_direct_key_importer(
56
- seeded_klass, imported_config, *imported_keys, prefix: prefix, raw: raw
64
+ seeded_klass,
65
+ imported_config,
66
+ *imported_keys,
67
+ prefix: prefix,
68
+ raw: raw,
69
+ accessor: accessor
57
70
  )
71
+
58
72
  @mappings_importer = build_mappings_importer(
59
- seeded_klass, imported_config, mappings: mappings, prefix: prefix, raw: raw
73
+ seeded_klass,
74
+ imported_config,
75
+ mappings: mappings,
76
+ prefix: prefix,
77
+ raw: raw,
78
+ accessor: accessor
60
79
  )
61
80
  end
62
81
 
@@ -96,17 +115,27 @@ class Qonfig::Imports::General
96
115
  # @param imported_keys [Array<String,Symbol>]
97
116
  # @option prefix [String, Symbol]
98
117
  # @option raw [Boolean]
118
+ # @option accessor [Boolean]
99
119
  # @return [Qonfig::Imports::DirectKey]
100
120
  #
101
121
  # @api private
102
122
  # @since 0.18.0
103
- def build_direct_key_importer(seeded_klass, imported_config, *imported_keys, prefix:, raw:)
123
+ # @version 0.21.0
124
+ def build_direct_key_importer(
125
+ seeded_klass,
126
+ imported_config,
127
+ *imported_keys,
128
+ prefix:,
129
+ raw:,
130
+ accessor:
131
+ )
104
132
  Qonfig::Imports::DirectKey.new(
105
133
  seeded_klass,
106
134
  imported_config,
107
135
  *imported_keys,
108
136
  prefix: prefix,
109
- raw: raw
137
+ raw: raw,
138
+ accessor: accessor
110
139
  )
111
140
  end
112
141
 
@@ -115,17 +144,27 @@ class Qonfig::Imports::General
115
144
  # @option mappings [Hash<Symbol|String,Symbol|String>]
116
145
  # @option prefix [String, Symbol]
117
146
  # @option raw [Boolean]
147
+ # @option accessor [Boolean]
118
148
  # @return [Qonfig::Imports::Mappings]
119
149
  #
120
150
  # @api private
121
151
  # @since 0.18.0
122
- def build_mappings_importer(seeded_klass, imported_config, mappings:, prefix:, raw:)
152
+ # @version 0.21.0
153
+ def build_mappings_importer(
154
+ seeded_klass,
155
+ imported_config,
156
+ mappings:,
157
+ prefix:,
158
+ raw:,
159
+ accessor:
160
+ )
123
161
  Qonfig::Imports::Mappings.new(
124
162
  seeded_klass,
125
163
  imported_config,
126
164
  mappings: mappings,
127
165
  prefix: prefix,
128
- raw: raw
166
+ raw: raw,
167
+ accessor: accessor
129
168
  )
130
169
  end
131
170
  end
@@ -14,19 +14,22 @@ class Qonfig::Imports::Mappings < Qonfig::Imports::Abstract
14
14
  # @option prefix [String, Symbol]
15
15
  # @option raw [Boolean]
16
16
  # @option mappings [Hash<Symbol|String,Symbol|String>]
17
+ # @option accessor [Boolean]
17
18
  # @return [void]
18
19
  #
19
20
  # @api private
20
21
  # @since 0.18.0
22
+ # @version 0.21.0
21
23
  def initialize(
22
24
  seeded_klass,
23
25
  imported_config,
24
26
  mappings: EMPTY_MAPPINGS,
25
27
  prefix: EMPTY_PREFIX,
26
- raw: DEFAULT_RAW_BEHAVIOR
28
+ raw: DEFAULT_RAW_BEHAVIOR,
29
+ accessor: AS_ACCESSOR
27
30
  )
28
31
  prevent_incompatible_import_params!(imported_config, prefix, mappings)
29
- super(seeded_klass, imported_config, prefix: prefix, raw: raw)
32
+ super(seeded_klass, imported_config, prefix: prefix, raw: raw, accessor: accessor)
30
33
  @mappings = mappings
31
34
  @key_matchers = build_setting_key_matchers(mappings)
32
35
  end
@@ -36,6 +39,8 @@ class Qonfig::Imports::Mappings < Qonfig::Imports::Abstract
36
39
  #
37
40
  # @api private
38
41
  # @since 0.18.0
42
+ # @version 0.21.0
43
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/BlockLength
39
44
  def import!(settings_interface = Module.new) # rubocop:disable Metrics/AbcSize
40
45
  key_matchers.each_pair do |(mapped_method_name, key_matcher)|
41
46
  raise(
@@ -43,7 +48,7 @@ class Qonfig::Imports::Mappings < Qonfig::Imports::Abstract
43
48
  "Setting with <#{key_matcher.scope_pattern}> key does not exist!"
44
49
  ) unless (imported_config.keys(all_variants: true).any? do |setting_key|
45
50
  key_matcher.match?(setting_key)
46
- end)
51
+ end || key_matcher.generic?)
47
52
 
48
53
  imported_config.keys(all_variants: true).each do |setting_key|
49
54
  next unless key_matcher.match?(setting_key)
@@ -51,7 +56,9 @@ class Qonfig::Imports::Mappings < Qonfig::Imports::Abstract
51
56
  setting_key_path_sequence = setting_key.split('.')
52
57
  mapped_method_name = "#{prefix}#{mapped_method_name}" unless prefix.empty?
53
58
 
54
- settings_interface.module_exec(raw, imported_config) do |raw, imported_config|
59
+ settings_interface.module_exec(
60
+ raw, imported_config, accessor
61
+ ) do |raw, imported_config, accessor|
55
62
  unless raw
56
63
  # NOTE: get setting value via slice_value
57
64
  define_method(mapped_method_name) do
@@ -63,10 +70,22 @@ class Qonfig::Imports::Mappings < Qonfig::Imports::Abstract
63
70
  imported_config.dig(*setting_key_path_sequence)
64
71
  end
65
72
  end
73
+
74
+ define_method("#{mapped_method_name}?") do
75
+ # NOTE: based on Qonfig::Settings#__define_option_predicate__ realization
76
+ !!imported_config[setting_key]
77
+ end
78
+
79
+ if accessor
80
+ define_method("#{mapped_method_name}=") do |value|
81
+ imported_config[setting_key] = value
82
+ end
83
+ end
66
84
  end
67
85
  end
68
86
  end
69
87
  end
88
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/BlockLength
70
89
 
71
90
  private
72
91