anyway_config 2.0.6 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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