anyway_config 2.0.6 → 2.1.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.
@@ -34,11 +34,13 @@ module Anyway
34
34
 
35
35
  def record_value(val, *path, **opts)
36
36
  key = path.pop
37
- trace = if val.is_a?(Hash)
38
- Trace.new.tap { |_1| _1.merge_values(val, **opts) }
39
- else
40
- Trace.new(:value, val, **opts)
41
- end
37
+ (__m__ = if val.is_a?(Hash)
38
+ Trace.new.tap { |_1|
39
+ _1.merge_values(val, **opts)
40
+ }
41
+ else
42
+ Trace.new(:value, val, **opts)
43
+ end) && (((trace = __m__) || true) || Kernel.raise(NoMatchingPatternError, __m__.inspect))
42
44
 
43
45
  target_trace = path.empty? ? self : value.dig(*path)
44
46
  target_trace.value[key.to_s] = trace
@@ -141,7 +143,7 @@ module Anyway
141
143
 
142
144
  def current_trace() ; trace_stack.last; end
143
145
 
144
- alias tracing? current_trace
146
+ alias_method :tracing?, :current_trace
145
147
 
146
148
  def source_stack
147
149
  (Thread.current[:__anyway__trace_source_stack__] ||= [])
@@ -19,7 +19,7 @@ module Anyway # :nodoc:
19
19
  # Provides `attr_config` method to describe
20
20
  # configuration parameters and set defaults
21
21
  class Config
22
- PARAM_NAME = /^[a-z_]([\w]+)?$/
22
+ PARAM_NAME = /^[a-z_](\w+)?$/
23
23
 
24
24
  # List of names that couldn't be used as config names
25
25
  # (the class instance methods we use)
@@ -40,12 +40,14 @@ module Anyway # :nodoc:
40
40
  raise_validation_error
41
41
  reload
42
42
  resolve_config_path
43
+ tap
43
44
  to_h
44
45
  to_source_trace
45
46
  write_config_attr
46
47
  ].freeze
47
48
 
48
49
  class Error < StandardError; end
50
+
49
51
  class ValidationError < Error; end
50
52
 
51
53
  include OptparseConfig
@@ -142,9 +144,9 @@ module Anyway # :nodoc:
142
144
  end
143
145
 
144
146
  def on_load(*names, &block)
145
- raise ArgumentError, "Either methods or block should be specified, not both" if block_given? && !names.empty?
147
+ raise ArgumentError, "Either methods or block should be specified, not both" if block && !names.empty?
146
148
 
147
- if block_given?
149
+ if block
148
150
  load_callbacks << BlockCallback.new(block)
149
151
  else
150
152
  load_callbacks.push(*names.map { NamedCallback.new(_1) })
@@ -201,8 +203,7 @@ module Anyway # :nodoc:
201
203
  accessors_module.module_eval <<~RUBY, __FILE__, __LINE__ + 1
202
204
  def #{name}=(val)
203
205
  __trace__&.record_value(val, \"#{name}\", **Tracing.current_trace_source)
204
- # DEPRECATED: instance variable set will be removed in 2.1
205
- @#{name} = values[:#{name}] = val
206
+ values[:#{name}] = val
206
207
  end
207
208
 
208
209
  def #{name}
@@ -229,7 +230,7 @@ module Anyway # :nodoc:
229
230
  # handle two cases:
230
231
  # - SomeModule::Config => "some_module"
231
232
  # - SomeConfig => "some"
232
- unless name =~ /^(\w+)(\:\:)?Config$/
233
+ unless name =~ /^(\w+)(::)?Config$/
233
234
  raise "Couldn't infer config name, please, specify it explicitly" \
234
235
  "via `config_name :my_config`"
235
236
  end
@@ -288,17 +289,14 @@ module Anyway # :nodoc:
288
289
  trace = Tracing.capture do
289
290
  Tracing.trace!(:defaults) { base_config }
290
291
 
291
- load_from_sources(
292
- base_config,
293
- name: config_name,
294
- env_prefix: env_prefix,
295
- config_path: resolve_config_path(config_name, env_prefix)
296
- )
292
+ config_path = resolve_config_path(config_name, env_prefix)
293
+
294
+ load_from_sources(base_config, name: config_name, env_prefix: env_prefix, config_path: config_path)
297
295
 
298
296
  if overrides
299
297
  Tracing.trace!(:load) { overrides }
300
298
 
301
- base_config.deep_merge!(overrides)
299
+ Utils.deep_merge!(base_config, overrides)
302
300
  end
303
301
  end
304
302
 
@@ -321,7 +319,7 @@ module Anyway # :nodoc:
321
319
 
322
320
  def load_from_sources(base_config, **options)
323
321
  Anyway.loaders.each do |(_id, loader)|
324
- base_config.deep_merge!(loader.call(**options))
322
+ Utils.deep_merge!(base_config, loader.call(**options))
325
323
  end
326
324
  base_config
327
325
  end
@@ -34,11 +34,13 @@ module Anyway
34
34
 
35
35
  def record_value(val, *path, **opts)
36
36
  key = path.pop
37
- trace = if val.is_a?(Hash)
38
- Trace.new.tap { _1.merge_values(val, **opts) }
39
- else
40
- Trace.new(:value, val, **opts)
41
- end
37
+ (__m__ = if val.is_a?(Hash)
38
+ Trace.new.tap {
39
+ _1.merge_values(val, **opts)
40
+ }
41
+ else
42
+ Trace.new(:value, val, **opts)
43
+ end) && (((trace = __m__) || true) || Kernel.raise(NoMatchingPatternError, __m__.inspect))
42
44
 
43
45
  target_trace = path.empty? ? self : value.dig(*path)
44
46
  target_trace.value[key.to_s] = trace
@@ -141,7 +143,7 @@ module Anyway
141
143
 
142
144
  def current_trace() ; trace_stack.last; end
143
145
 
144
- alias tracing? current_trace
146
+ alias_method :tracing?, :current_trace
145
147
 
146
148
  def source_stack
147
149
  (Thread.current[:__anyway__trace_source_stack__] ||= [])
@@ -19,7 +19,7 @@ module Anyway # :nodoc:
19
19
  # Provides `attr_config` method to describe
20
20
  # configuration parameters and set defaults
21
21
  class Config
22
- PARAM_NAME = /^[a-z_]([\w]+)?$/
22
+ PARAM_NAME = /^[a-z_](\w+)?$/
23
23
 
24
24
  # List of names that couldn't be used as config names
25
25
  # (the class instance methods we use)
@@ -40,12 +40,14 @@ module Anyway # :nodoc:
40
40
  raise_validation_error
41
41
  reload
42
42
  resolve_config_path
43
+ tap
43
44
  to_h
44
45
  to_source_trace
45
46
  write_config_attr
46
47
  ].freeze
47
48
 
48
49
  class Error < StandardError; end
50
+
49
51
  class ValidationError < Error; end
50
52
 
51
53
  include OptparseConfig
@@ -106,21 +108,21 @@ module Anyway # :nodoc:
106
108
  def defaults
107
109
  return @defaults if instance_variable_defined?(:@defaults)
108
110
 
109
- if superclass < Anyway::Config
111
+ @defaults = if superclass < Anyway::Config
110
112
  superclass.defaults.deep_dup
111
113
  else
112
114
  new_empty_config
113
- end => @defaults
115
+ end
114
116
  end
115
117
 
116
118
  def config_attributes
117
119
  return @config_attributes if instance_variable_defined?(:@config_attributes)
118
120
 
119
- if superclass < Anyway::Config
121
+ @config_attributes = if superclass < Anyway::Config
120
122
  superclass.config_attributes.dup
121
123
  else
122
124
  []
123
- end => @config_attributes
125
+ end
124
126
  end
125
127
 
126
128
  def required(*names)
@@ -134,17 +136,17 @@ module Anyway # :nodoc:
134
136
  def required_attributes
135
137
  return @required_attributes if instance_variable_defined?(:@required_attributes)
136
138
 
137
- if superclass < Anyway::Config
139
+ @required_attributes = if superclass < Anyway::Config
138
140
  superclass.required_attributes.dup
139
141
  else
140
142
  []
141
- end => @required_attributes
143
+ end
142
144
  end
143
145
 
144
146
  def on_load(*names, &block)
145
- raise ArgumentError, "Either methods or block should be specified, not both" if block_given? && !names.empty?
147
+ raise ArgumentError, "Either methods or block should be specified, not both" if block && !names.empty?
146
148
 
147
- if block_given?
149
+ if block
148
150
  load_callbacks << BlockCallback.new(block)
149
151
  else
150
152
  load_callbacks.push(*names.map { NamedCallback.new(_1) })
@@ -154,11 +156,11 @@ module Anyway # :nodoc:
154
156
  def load_callbacks
155
157
  return @load_callbacks if instance_variable_defined?(:@load_callbacks)
156
158
 
157
- if superclass <= Anyway::Config
159
+ @load_callbacks = if superclass <= Anyway::Config
158
160
  superclass.load_callbacks.dup
159
161
  else
160
162
  []
161
- end => @load_callbacks
163
+ end
162
164
  end
163
165
 
164
166
  def config_name(val = nil)
@@ -185,11 +187,11 @@ module Anyway # :nodoc:
185
187
 
186
188
  return @env_prefix if instance_variable_defined?(:@env_prefix)
187
189
 
188
- if superclass < Anyway::Config && superclass.explicit_config_name?
190
+ @env_prefix = if superclass < Anyway::Config && superclass.explicit_config_name?
189
191
  superclass.env_prefix
190
192
  else
191
193
  config_name.upcase
192
- end => @env_prefix
194
+ end
193
195
  end
194
196
 
195
197
  def new_empty_config() = {}
@@ -201,8 +203,7 @@ module Anyway # :nodoc:
201
203
  accessors_module.module_eval <<~RUBY, __FILE__, __LINE__ + 1
202
204
  def #{name}=(val)
203
205
  __trace__&.record_value(val, \"#{name}\", **Tracing.current_trace_source)
204
- # DEPRECATED: instance variable set will be removed in 2.1
205
- @#{name} = values[:#{name}] = val
206
+ values[:#{name}] = val
206
207
  end
207
208
 
208
209
  def #{name}
@@ -215,9 +216,9 @@ module Anyway # :nodoc:
215
216
  def accessors_module
216
217
  return @accessors_module if instance_variable_defined?(:@accessors_module)
217
218
 
218
- Module.new.tap do |mod|
219
+ @accessors_module = Module.new.tap do |mod|
219
220
  include mod
220
- end => @accessors_module
221
+ end
221
222
  end
222
223
 
223
224
  def build_config_name
@@ -229,7 +230,7 @@ module Anyway # :nodoc:
229
230
  # handle two cases:
230
231
  # - SomeModule::Config => "some_module"
231
232
  # - SomeConfig => "some"
232
- unless name =~ /^(\w+)(\:\:)?Config$/
233
+ unless name =~ /^(\w+)(::)?Config$/
233
234
  raise "Couldn't infer config name, please, specify it explicitly" \
234
235
  "via `config_name :my_config`"
235
236
  end
@@ -285,22 +286,19 @@ module Anyway # :nodoc:
285
286
  def load(overrides = nil)
286
287
  base_config = self.class.defaults.deep_dup
287
288
 
288
- Tracing.capture do
289
+ trace = Tracing.capture do
289
290
  Tracing.trace!(:defaults) { base_config }
290
291
 
291
- load_from_sources(
292
- base_config,
293
- name: config_name,
294
- env_prefix: env_prefix,
295
- config_path: resolve_config_path(config_name, env_prefix)
296
- )
292
+ config_path = resolve_config_path(config_name, env_prefix)
293
+
294
+ load_from_sources(base_config, name: config_name, env_prefix:, config_path:)
297
295
 
298
296
  if overrides
299
297
  Tracing.trace!(:load) { overrides }
300
298
 
301
- base_config.deep_merge!(overrides)
299
+ Utils.deep_merge!(base_config, overrides)
302
300
  end
303
- end => trace
301
+ end
304
302
 
305
303
  base_config.each do |key, val|
306
304
  write_config_attr(key.to_sym, val)
@@ -321,7 +319,7 @@ module Anyway # :nodoc:
321
319
 
322
320
  def load_from_sources(base_config, **options)
323
321
  Anyway.loaders.each do |(_id, loader)|
324
- base_config.deep_merge!(loader.call(**options))
322
+ Utils.deep_merge!(base_config, loader.call(**options))
325
323
  end
326
324
  base_config
327
325
  end
@@ -16,7 +16,7 @@ module Anyway
16
16
  config = allocate
17
17
  options[:env_prefix] ||= name.to_s.upcase
18
18
  options[:config_path] ||= config.resolve_config_path(name, options[:env_prefix])
19
- config.load_from_sources(new_empty_config, name: name, **options)
19
+ config.load_from_sources(new_empty_config, name:, **options)
20
20
  end
21
21
  end
22
22
 
@@ -49,7 +49,7 @@ module Anyway
49
49
  path = key.sub(/^#{prefix}_/, "").downcase
50
50
 
51
51
  paths = path.split("__")
52
- trace!(:env, *paths, key: key) { data.bury(type_cast.call(val), *paths) }
52
+ trace!(:env, *paths, key:) { data.bury(type_cast.call(val), *paths) }
53
53
  end
54
54
  end
55
55
  end
@@ -30,6 +30,12 @@ module Anyway
30
30
  end
31
31
  end
32
32
 
33
+ refine ::Object do
34
+ def deep_dup
35
+ dup
36
+ end
37
+ end
38
+
33
39
  using self
34
40
  end
35
41
  end
@@ -5,18 +5,6 @@ module Anyway
5
5
  # Extend Hash through refinements
6
6
  module Hash
7
7
  refine ::Hash do
8
- # From ActiveSupport http://api.rubyonrails.org/classes/Hash.html#method-i-deep_merge
9
- def deep_merge!(other_hash)
10
- merge!(other_hash) do |key, this_value, other_value|
11
- if this_value.is_a?(::Hash) && other_value.is_a?(::Hash)
12
- this_value.deep_merge!(other_value)
13
- this_value
14
- else
15
- other_value
16
- end
17
- end
18
- end
19
-
20
8
  def stringify_keys!
21
9
  keys.each do |key|
22
10
  value = delete(key)
@@ -7,7 +7,7 @@ module Anyway
7
7
 
8
8
  class << self
9
9
  def call(local: Anyway::Settings.use_local_files, **opts)
10
- new(local: local).call(**opts)
10
+ new(local:).call(**opts)
11
11
  end
12
12
  end
13
13
 
@@ -17,7 +17,7 @@ module Anyway
17
17
  local_path = local_config_path(config_path)
18
18
  local_config = trace!(:yml, path: relative_config_path(local_path).to_s) { load_local_yml(local_path) }
19
19
 
20
- base_config.deep_merge!(local_config)
20
+ Utils.deep_merge!(base_config, local_config)
21
21
  end
22
22
 
23
23
  private
@@ -32,8 +32,8 @@ module Anyway
32
32
  end
33
33
  end
34
34
 
35
- alias load_base_yml parse_yml
36
- alias load_local_yml parse_yml
35
+ alias_method :load_base_yml, :parse_yml
36
+ alias_method :load_local_yml, :parse_yml
37
37
 
38
38
  def local_config_path(path)
39
39
  path.sub(/\.yml/, ".local.yml")
@@ -24,13 +24,13 @@ module Anyway
24
24
  ) do
25
25
  ::Rails.application.credentials.public_send(name)
26
26
  end.then do |creds|
27
- config.deep_merge!(creds) if creds
27
+ Utils.deep_merge!(config, creds) if creds
28
28
  end
29
29
 
30
30
  if use_local?
31
31
  trace!(:credentials, store: LOCAL_CONTENT_PATH) do
32
32
  local_credentials(name)
33
- end.then { |creds| config.deep_merge!(creds) if creds }
33
+ end.then { |creds| Utils.deep_merge!(config, creds) if creds }
34
34
  end
35
35
 
36
36
  config
@@ -15,7 +15,7 @@ module Anyway
15
15
  trace!(:secrets) do
16
16
  secrets.public_send(name)
17
17
  end.then do |secrets|
18
- config.deep_merge!(secrets) if secrets
18
+ Utils.deep_merge!(config, secrets) if secrets
19
19
  end
20
20
 
21
21
  config
@@ -5,11 +5,22 @@ module Anyway
5
5
  module Loaders
6
6
  class YAML < Anyway::Loaders::YAML
7
7
  def load_base_yml(*)
8
+ parsed_yml = super
9
+ return parsed_yml unless environmental?(parsed_yml)
10
+
8
11
  super[::Rails.env] || {}
9
12
  end
10
13
 
11
14
  private
12
15
 
16
+ def environmental?(parsed_yml)
17
+ return true unless Settings.future.unwrap_known_environments
18
+ # likely
19
+ return true if parsed_yml.key?(::Rails.env)
20
+ # less likely
21
+ ::Rails.application.config.anyway_config.known_environments.any? { parsed_yml.key?(_1) }
22
+ end
23
+
13
24
  def relative_config_path(path)
14
25
  Pathname.new(path).relative_path_from(::Rails.root)
15
26
  end
@@ -9,8 +9,13 @@ end
9
9
 
10
10
  module Anyway
11
11
  class Settings
12
+ class Future
13
+ setting :unwrap_known_environments, true
14
+ end
15
+
12
16
  class << self
13
17
  attr_reader :autoload_static_config_path, :autoloader
18
+ attr_accessor :known_environments
14
19
 
15
20
  if defined?(::Zeitwerk)
16
21
  def autoload_static_config_path=(val)
@@ -56,5 +61,6 @@ module Anyway
56
61
  end
57
62
 
58
63
  self.default_config_path = ->(name) { ::Rails.root.join("config", "#{name}.yml") }
64
+ self.known_environments = %w[test development production]
59
65
  end
60
66
  end