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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +199 -181
- data/README.md +69 -9
- data/lib/.rbnext/1995.next/anyway/config.rb +391 -0
- data/lib/.rbnext/1995.next/anyway/dynamic_config.rb +27 -0
- data/lib/.rbnext/1995.next/anyway/env.rb +56 -0
- data/lib/.rbnext/1995.next/anyway/loaders/base.rb +21 -0
- data/lib/.rbnext/1995.next/anyway/tracing.rb +181 -0
- data/lib/.rbnext/2.7/anyway/config.rb +12 -14
- data/lib/.rbnext/2.7/anyway/rails/loaders/yaml.rb +30 -0
- data/lib/.rbnext/2.7/anyway/settings.rb +79 -0
- data/lib/.rbnext/2.7/anyway/tracing.rb +8 -6
- data/lib/.rbnext/{2.8 → 3.0}/anyway/config.rb +12 -14
- data/lib/.rbnext/{2.8 → 3.0}/anyway/loaders.rb +0 -0
- data/lib/.rbnext/{2.8 → 3.0}/anyway/loaders/base.rb +0 -0
- data/lib/.rbnext/{2.8 → 3.0}/anyway/tracing.rb +8 -6
- data/lib/anyway/config.rb +26 -28
- data/lib/anyway/dynamic_config.rb +1 -1
- data/lib/anyway/env.rb +1 -1
- data/lib/anyway/ext/deep_dup.rb +6 -0
- data/lib/anyway/ext/hash.rb +0 -12
- data/lib/anyway/loaders/base.rb +1 -1
- data/lib/anyway/loaders/yaml.rb +3 -3
- data/lib/anyway/rails/loaders/credentials.rb +2 -2
- data/lib/anyway/rails/loaders/secrets.rb +1 -1
- data/lib/anyway/rails/loaders/yaml.rb +11 -0
- data/lib/anyway/rails/settings.rb +6 -0
- data/lib/anyway/settings.rb +52 -2
- data/lib/anyway/tracing.rb +4 -4
- data/lib/anyway/utils/deep_merge.rb +21 -0
- data/lib/anyway/version.rb +1 -1
- data/lib/anyway_config.rb +2 -0
- metadata +18 -10
@@ -34,11 +34,13 @@ module Anyway
|
|
34
34
|
|
35
35
|
def record_value(val, *path, **opts)
|
36
36
|
key = path.pop
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
-
|
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_](
|
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
|
147
|
+
raise ArgumentError, "Either methods or block should be specified, not both" if block && !names.empty?
|
146
148
|
|
147
|
-
if
|
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
|
-
|
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+)(
|
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
|
-
|
292
|
-
|
293
|
-
|
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
|
-
|
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
|
-
|
322
|
+
Utils.deep_merge!(base_config, loader.call(**options))
|
325
323
|
end
|
326
324
|
base_config
|
327
325
|
end
|
File without changes
|
File without changes
|
@@ -34,11 +34,13 @@ module Anyway
|
|
34
34
|
|
35
35
|
def record_value(val, *path, **opts)
|
36
36
|
key = path.pop
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
-
|
146
|
+
alias_method :tracing?, :current_trace
|
145
147
|
|
146
148
|
def source_stack
|
147
149
|
(Thread.current[:__anyway__trace_source_stack__] ||= [])
|
data/lib/anyway/config.rb
CHANGED
@@ -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_](
|
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
|
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
|
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
|
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
|
147
|
+
raise ArgumentError, "Either methods or block should be specified, not both" if block && !names.empty?
|
146
148
|
|
147
|
-
if
|
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
|
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
|
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
|
-
|
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
|
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+)(
|
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
|
-
|
292
|
-
|
293
|
-
|
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
|
-
|
299
|
+
Utils.deep_merge!(base_config, overrides)
|
302
300
|
end
|
303
|
-
end
|
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
|
-
|
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
|
19
|
+
config.load_from_sources(new_empty_config, name:, **options)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
data/lib/anyway/env.rb
CHANGED
@@ -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:
|
52
|
+
trace!(:env, *paths, key:) { data.bury(type_cast.call(val), *paths) }
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
data/lib/anyway/ext/deep_dup.rb
CHANGED
data/lib/anyway/ext/hash.rb
CHANGED
@@ -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)
|
data/lib/anyway/loaders/base.rb
CHANGED
data/lib/anyway/loaders/yaml.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
36
|
-
|
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
|
-
|
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|
|
33
|
+
end.then { |creds| Utils.deep_merge!(config, creds) if creds }
|
34
34
|
end
|
35
35
|
|
36
36
|
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
|