anyway_config 2.2.3 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +34 -1
- data/lib/.rbnext/2.7/anyway/config.rb +28 -4
- data/lib/.rbnext/2.7/anyway/loaders/yaml.rb +84 -0
- data/lib/.rbnext/2.7/anyway/settings.rb +16 -1
- data/lib/.rbnext/2.7/anyway/tracing.rb +9 -8
- data/lib/.rbnext/3.0/anyway/config.rb +28 -4
- data/lib/.rbnext/3.0/anyway/tracing.rb +9 -8
- data/lib/.rbnext/3.1/anyway/config.rb +28 -4
- data/lib/.rbnext/3.1/anyway/tracing.rb +9 -8
- data/lib/anyway/config.rb +28 -4
- data/lib/anyway/loaders/yaml.rb +25 -3
- data/lib/anyway/rails/loaders/yaml.rb +1 -28
- data/lib/anyway/rails/settings.rb +8 -8
- data/lib/anyway/settings.rb +16 -1
- data/lib/anyway/tracing.rb +9 -8
- data/lib/anyway/version.rb +1 -1
- data/sig/anyway_config.rbs +27 -12
- metadata +3 -3
- data/lib/.rbnext/2.7/anyway/rails/loaders/yaml.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe4f769be22bc9cb820fd1159b88a565b2fb71e13ad617d90aaafbcb1673f995
|
4
|
+
data.tar.gz: 175e468716722b43b6c7d163a97b6523801f6658118d1c56bb5a4a0255807ef9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c323f89197ca35405ca77ee1e58a8b3fbbf4b0d6b57e7ccce380311a13994d18121966428a2681cb55a5892c2eff52ec347a6e3568072ea8f85d1cf7f75aa80
|
7
|
+
data.tar.gz: 25ee0b877318a2335c2019a414684d5b15e3755ceff90e51de3a0b821ee48f86a119f9753eaddac5dfb4724e38876ec5f18b68b065db7aa4b23d20b837666929
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 2.3.0 (2022-03-11)
|
6
|
+
|
7
|
+
- Add ability to load configurations under specific environments in pure Ruby apps. ([@fargelus][]).
|
8
|
+
|
9
|
+
Before loading environment configurations you need to specify variable `Anyway::Settings.current_environment`. In Rails apps this variable is same as `Rails.env` value.
|
10
|
+
After adding yaml loader will try to load params under this environment.
|
11
|
+
|
12
|
+
Also required env option was added to `Anyway::Config`.
|
13
|
+
|
5
14
|
## 2.2.3 (2022-01-21)
|
6
15
|
|
7
16
|
- Fix Ruby 3.1 compatibility. ([@palkan][])
|
@@ -449,3 +458,4 @@ No we're dependency-free!
|
|
449
458
|
[@envek]: https://github.com/Envek
|
450
459
|
[@progapandist]: https://github.com/progapandist
|
451
460
|
[@skryukov]: https://github.com/skryukov
|
461
|
+
[@fargelus]: https://github.com/fargelus
|
data/README.md
CHANGED
@@ -297,6 +297,24 @@ end
|
|
297
297
|
MyConfig.new(api_secret: "") #=> raises Anyway::Config::ValidationError
|
298
298
|
```
|
299
299
|
|
300
|
+
`Required` method supports additional `env` parameter which indicates necessity to run validations under specified
|
301
|
+
environments. `Env` parameter could be present in symbol, string, array or hash formats:
|
302
|
+
|
303
|
+
```ruby
|
304
|
+
class EnvConfig < Anyway::Config
|
305
|
+
required :password, env: "production"
|
306
|
+
required :maps_api_key, env: :production
|
307
|
+
required :smtp_host, env: %i[production staging]
|
308
|
+
required :aws_bucket, env: %w[production staging]
|
309
|
+
required :anycable_rpc_host, env: {except: :development}
|
310
|
+
required :anycable_redis_url, env: {except: %i[development test]}
|
311
|
+
required :anycable_broadcast_adapter, env: {except: %w[development test]}
|
312
|
+
end
|
313
|
+
```
|
314
|
+
|
315
|
+
If your current `Anyway::Settings.current_environment` is mismatch keys that specified
|
316
|
+
`Anyway::Config::ValidationError` error will be raised.
|
317
|
+
|
300
318
|
If you need more complex validation or need to manipulate with config state right after it has been loaded, you can use _on load callbacks_ and `#raise_validation_error` method:
|
301
319
|
|
302
320
|
```ruby
|
@@ -529,7 +547,22 @@ The default data loading mechanism for non-Rails applications is the following (
|
|
529
547
|
|
530
548
|
1) **YAML configuration files**: `./config/<config-name>.yml`.
|
531
549
|
|
532
|
-
In pure Ruby apps, we
|
550
|
+
In pure Ruby apps, we also can load data under specific _environments_ (`test`, `development`, `production`, etc.).
|
551
|
+
If you want to enable this feature you must specify `Anyway::Settings.current_environment` variable for load config under specific environment.
|
552
|
+
|
553
|
+
```ruby
|
554
|
+
Anyway::Settings.current_environment = "development"
|
555
|
+
```
|
556
|
+
|
557
|
+
YAML files should be in this format:
|
558
|
+
|
559
|
+
```yml
|
560
|
+
development:
|
561
|
+
host: localhost
|
562
|
+
port: 3000
|
563
|
+
```
|
564
|
+
|
565
|
+
If `Anyway::Settings.current_environment` is missed we assume that the YAML contains values for a single environment:
|
533
566
|
|
534
567
|
```yml
|
535
568
|
host: localhost
|
@@ -47,6 +47,8 @@ module Anyway # :nodoc:
|
|
47
47
|
__type_caster__
|
48
48
|
].freeze
|
49
49
|
|
50
|
+
ENV_OPTION_EXCLUDE_KEY = :except
|
51
|
+
|
50
52
|
class Error < StandardError; end
|
51
53
|
|
52
54
|
class ValidationError < Error; end
|
@@ -126,14 +128,36 @@ module Anyway # :nodoc:
|
|
126
128
|
end
|
127
129
|
end
|
128
130
|
|
129
|
-
def required(*names)
|
130
|
-
|
131
|
-
|
132
|
-
end
|
131
|
+
def required(*names, env: nil)
|
132
|
+
unknown_names = names - config_attributes
|
133
|
+
raise ArgumentError, "Unknown config param: #{unknown_names.join(",")}" if unknown_names.any?
|
133
134
|
|
135
|
+
names = filter_by_env(names, env)
|
134
136
|
required_attributes.push(*names)
|
135
137
|
end
|
136
138
|
|
139
|
+
def filter_by_env(names, env)
|
140
|
+
return names if env.nil? || env.to_s == current_env
|
141
|
+
|
142
|
+
filtered_names = if env.is_a?(Hash)
|
143
|
+
names_with_exclude_env_option(names, env)
|
144
|
+
elsif env.is_a?(Array)
|
145
|
+
names if env.flat_map(&:to_s).include?(current_env)
|
146
|
+
end
|
147
|
+
|
148
|
+
filtered_names || []
|
149
|
+
end
|
150
|
+
|
151
|
+
def current_env
|
152
|
+
Settings.current_environment.to_s
|
153
|
+
end
|
154
|
+
|
155
|
+
def names_with_exclude_env_option(names, env)
|
156
|
+
envs = env[ENV_OPTION_EXCLUDE_KEY]
|
157
|
+
excluded_envs = [envs].flat_map(&:to_s)
|
158
|
+
names if excluded_envs.none?(current_env)
|
159
|
+
end
|
160
|
+
|
137
161
|
def required_attributes
|
138
162
|
return @required_attributes if instance_variable_defined?(:@required_attributes)
|
139
163
|
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
require "anyway/ext/hash"
|
5
|
+
|
6
|
+
using RubyNext
|
7
|
+
using Anyway::Ext::Hash
|
8
|
+
|
9
|
+
module Anyway
|
10
|
+
module Loaders
|
11
|
+
class YAML < Base
|
12
|
+
def call(config_path:, **_options)
|
13
|
+
rel_config_path = relative_config_path(config_path).to_s
|
14
|
+
base_config = trace!(:yml, path: rel_config_path) do
|
15
|
+
config = load_base_yml(config_path)
|
16
|
+
environmental?(config) ? config_with_env(config) : config
|
17
|
+
end
|
18
|
+
|
19
|
+
return base_config unless use_local?
|
20
|
+
|
21
|
+
local_path = local_config_path(config_path)
|
22
|
+
local_config = trace!(:yml, path: relative_config_path(local_path).to_s) { load_local_yml(local_path) }
|
23
|
+
Utils.deep_merge!(base_config, local_config)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def environmental?(parsed_yml)
|
29
|
+
# strange, but still possible
|
30
|
+
return true if Settings.default_environmental_key? && parsed_yml.key?(Settings.default_environmental_key)
|
31
|
+
# possible
|
32
|
+
return true if !Settings.future.unwrap_known_environments && Settings.current_environment
|
33
|
+
# for other environments
|
34
|
+
return true if Settings.known_environments&.any? { |_1| parsed_yml.key?(_1) }
|
35
|
+
# preferred
|
36
|
+
parsed_yml.key?(Settings.current_environment)
|
37
|
+
end
|
38
|
+
|
39
|
+
def config_with_env(config)
|
40
|
+
env_config = config[Settings.current_environment] || {}
|
41
|
+
return env_config unless Settings.default_environmental_key?
|
42
|
+
|
43
|
+
default_config = config[Settings.default_environmental_key] || {}
|
44
|
+
Utils.deep_merge!(default_config, env_config)
|
45
|
+
end
|
46
|
+
|
47
|
+
def parse_yml(path)
|
48
|
+
return {} unless File.file?(path)
|
49
|
+
require "yaml" unless defined?(::YAML)
|
50
|
+
|
51
|
+
# By default, YAML load will return `false` when the yaml document is
|
52
|
+
# empty. When this occurs, we return an empty hash instead, to match
|
53
|
+
# the interface when no config file is present.
|
54
|
+
begin
|
55
|
+
if defined?(ERB)
|
56
|
+
::YAML.load(ERB.new(File.read(path)).result, aliases: true) || {} # rubocop:disable Security/YAMLLoad
|
57
|
+
else
|
58
|
+
::YAML.load_file(path, aliases: true) || {}
|
59
|
+
end
|
60
|
+
rescue ArgumentError
|
61
|
+
if defined?(ERB)
|
62
|
+
::YAML.load(ERB.new(File.read(path)).result) || {} # rubocop:disable Security/YAMLLoad
|
63
|
+
else
|
64
|
+
::YAML.load_file(path) || {}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
alias_method :load_base_yml, :parse_yml
|
70
|
+
alias_method :load_local_yml, :parse_yml
|
71
|
+
|
72
|
+
def local_config_path(path)
|
73
|
+
path.sub(/\.yml/, ".local.yml")
|
74
|
+
end
|
75
|
+
|
76
|
+
def relative_config_path(path)
|
77
|
+
Pathname.new(path).then do |path|
|
78
|
+
return path if path.relative?
|
79
|
+
path.relative_path_from(Settings.app_root)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "pathname"
|
4
|
+
|
3
5
|
module Anyway
|
4
6
|
# Use Settings name to not confuse with Config.
|
5
7
|
#
|
@@ -35,6 +37,8 @@ module Anyway
|
|
35
37
|
names.each { |_1| store[_1] = self.class.settings[_1] }
|
36
38
|
end
|
37
39
|
|
40
|
+
setting :unwrap_known_environments, true
|
41
|
+
|
38
42
|
private
|
39
43
|
|
40
44
|
attr_reader :store
|
@@ -43,7 +47,10 @@ module Anyway
|
|
43
47
|
class << self
|
44
48
|
# Define whether to load data from
|
45
49
|
# *.yml.local (or credentials/local.yml.enc)
|
46
|
-
attr_accessor :use_local_files
|
50
|
+
attr_accessor :use_local_files,
|
51
|
+
:current_environment,
|
52
|
+
:default_environmental_key,
|
53
|
+
:known_environments
|
47
54
|
|
48
55
|
# A proc returning a path to YML config file given the config name
|
49
56
|
attr_reader :default_config_path
|
@@ -65,6 +72,14 @@ module Anyway
|
|
65
72
|
def future
|
66
73
|
@future ||= Future.new
|
67
74
|
end
|
75
|
+
|
76
|
+
def app_root
|
77
|
+
Pathname.new(Dir.pwd)
|
78
|
+
end
|
79
|
+
|
80
|
+
def default_environmental_key?
|
81
|
+
!default_environmental_key.nil?
|
82
|
+
end
|
68
83
|
end
|
69
84
|
|
70
85
|
# By default, use local files only in development (that's the purpose if the local files)
|
@@ -6,12 +6,6 @@ module Anyway
|
|
6
6
|
using Anyway::Ext::DeepDup
|
7
7
|
|
8
8
|
using(Module.new do
|
9
|
-
refine Hash do
|
10
|
-
def inspect
|
11
|
-
"{#{map { |k, v| "#{k}: #{v.inspect}" }.join(", ")}}"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
9
|
refine Thread::Backtrace::Location do
|
16
10
|
def path_lineno() ; "#{path}:#{lineno}"; end
|
17
11
|
end
|
@@ -100,8 +94,15 @@ module Anyway
|
|
100
94
|
q.group do
|
101
95
|
q.text k
|
102
96
|
q.text " =>"
|
103
|
-
|
104
|
-
|
97
|
+
if v.trace?
|
98
|
+
q.text " { "
|
99
|
+
q.pp v
|
100
|
+
q.breakable " "
|
101
|
+
q.text "}"
|
102
|
+
else
|
103
|
+
q.breakable " "
|
104
|
+
q.pp v
|
105
|
+
end
|
105
106
|
end
|
106
107
|
end
|
107
108
|
end
|
@@ -47,6 +47,8 @@ module Anyway # :nodoc:
|
|
47
47
|
__type_caster__
|
48
48
|
].freeze
|
49
49
|
|
50
|
+
ENV_OPTION_EXCLUDE_KEY = :except
|
51
|
+
|
50
52
|
class Error < StandardError; end
|
51
53
|
|
52
54
|
class ValidationError < Error; end
|
@@ -126,14 +128,36 @@ module Anyway # :nodoc:
|
|
126
128
|
end
|
127
129
|
end
|
128
130
|
|
129
|
-
def required(*names)
|
130
|
-
|
131
|
-
|
132
|
-
end
|
131
|
+
def required(*names, env: nil)
|
132
|
+
unknown_names = names - config_attributes
|
133
|
+
raise ArgumentError, "Unknown config param: #{unknown_names.join(",")}" if unknown_names.any?
|
133
134
|
|
135
|
+
names = filter_by_env(names, env)
|
134
136
|
required_attributes.push(*names)
|
135
137
|
end
|
136
138
|
|
139
|
+
def filter_by_env(names, env)
|
140
|
+
return names if env.nil? || env.to_s == current_env
|
141
|
+
|
142
|
+
filtered_names = if env.is_a?(Hash)
|
143
|
+
names_with_exclude_env_option(names, env)
|
144
|
+
elsif env.is_a?(Array)
|
145
|
+
names if env.flat_map(&:to_s).include?(current_env)
|
146
|
+
end
|
147
|
+
|
148
|
+
filtered_names || []
|
149
|
+
end
|
150
|
+
|
151
|
+
def current_env
|
152
|
+
Settings.current_environment.to_s
|
153
|
+
end
|
154
|
+
|
155
|
+
def names_with_exclude_env_option(names, env)
|
156
|
+
envs = env[ENV_OPTION_EXCLUDE_KEY]
|
157
|
+
excluded_envs = [envs].flat_map(&:to_s)
|
158
|
+
names if excluded_envs.none?(current_env)
|
159
|
+
end
|
160
|
+
|
137
161
|
def required_attributes
|
138
162
|
return @required_attributes if instance_variable_defined?(:@required_attributes)
|
139
163
|
|
@@ -6,12 +6,6 @@ module Anyway
|
|
6
6
|
using Anyway::Ext::DeepDup
|
7
7
|
|
8
8
|
using(Module.new do
|
9
|
-
refine Hash do
|
10
|
-
def inspect
|
11
|
-
"{#{map { |k, v| "#{k}: #{v.inspect}" }.join(", ")}}"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
9
|
refine Thread::Backtrace::Location do
|
16
10
|
def path_lineno() ; "#{path}:#{lineno}"; end
|
17
11
|
end
|
@@ -100,8 +94,15 @@ module Anyway
|
|
100
94
|
q.group do
|
101
95
|
q.text k
|
102
96
|
q.text " =>"
|
103
|
-
|
104
|
-
|
97
|
+
if v.trace?
|
98
|
+
q.text " { "
|
99
|
+
q.pp v
|
100
|
+
q.breakable " "
|
101
|
+
q.text "}"
|
102
|
+
else
|
103
|
+
q.breakable " "
|
104
|
+
q.pp v
|
105
|
+
end
|
105
106
|
end
|
106
107
|
end
|
107
108
|
end
|
@@ -47,6 +47,8 @@ module Anyway # :nodoc:
|
|
47
47
|
__type_caster__
|
48
48
|
].freeze
|
49
49
|
|
50
|
+
ENV_OPTION_EXCLUDE_KEY = :except
|
51
|
+
|
50
52
|
class Error < StandardError; end
|
51
53
|
|
52
54
|
class ValidationError < Error; end
|
@@ -126,14 +128,36 @@ module Anyway # :nodoc:
|
|
126
128
|
end
|
127
129
|
end
|
128
130
|
|
129
|
-
def required(*names)
|
130
|
-
|
131
|
-
|
132
|
-
end
|
131
|
+
def required(*names, env: nil)
|
132
|
+
unknown_names = names - config_attributes
|
133
|
+
raise ArgumentError, "Unknown config param: #{unknown_names.join(",")}" if unknown_names.any?
|
133
134
|
|
135
|
+
names = filter_by_env(names, env)
|
134
136
|
required_attributes.push(*names)
|
135
137
|
end
|
136
138
|
|
139
|
+
def filter_by_env(names, env)
|
140
|
+
return names if env.nil? || env.to_s == current_env
|
141
|
+
|
142
|
+
filtered_names = if env.is_a?(Hash)
|
143
|
+
names_with_exclude_env_option(names, env)
|
144
|
+
elsif env.is_a?(Array)
|
145
|
+
names if env.flat_map(&:to_s).include?(current_env)
|
146
|
+
end
|
147
|
+
|
148
|
+
filtered_names || []
|
149
|
+
end
|
150
|
+
|
151
|
+
def current_env
|
152
|
+
Settings.current_environment.to_s
|
153
|
+
end
|
154
|
+
|
155
|
+
def names_with_exclude_env_option(names, env)
|
156
|
+
envs = env[ENV_OPTION_EXCLUDE_KEY]
|
157
|
+
excluded_envs = [envs].flat_map(&:to_s)
|
158
|
+
names if excluded_envs.none?(current_env)
|
159
|
+
end
|
160
|
+
|
137
161
|
def required_attributes
|
138
162
|
return @required_attributes if instance_variable_defined?(:@required_attributes)
|
139
163
|
|
@@ -6,12 +6,6 @@ module Anyway
|
|
6
6
|
using Anyway::Ext::DeepDup
|
7
7
|
|
8
8
|
using(Module.new do
|
9
|
-
refine Hash do
|
10
|
-
def inspect
|
11
|
-
"{#{map { |k, v| "#{k}: #{v.inspect}" }.join(", ")}}"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
9
|
refine Thread::Backtrace::Location do
|
16
10
|
def path_lineno() = "#{path}:#{lineno}"
|
17
11
|
end
|
@@ -100,8 +94,15 @@ module Anyway
|
|
100
94
|
q.group do
|
101
95
|
q.text k
|
102
96
|
q.text " =>"
|
103
|
-
|
104
|
-
|
97
|
+
if v.trace?
|
98
|
+
q.text " { "
|
99
|
+
q.pp v
|
100
|
+
q.breakable " "
|
101
|
+
q.text "}"
|
102
|
+
else
|
103
|
+
q.breakable " "
|
104
|
+
q.pp v
|
105
|
+
end
|
105
106
|
end
|
106
107
|
end
|
107
108
|
end
|
data/lib/anyway/config.rb
CHANGED
@@ -47,6 +47,8 @@ module Anyway # :nodoc:
|
|
47
47
|
__type_caster__
|
48
48
|
].freeze
|
49
49
|
|
50
|
+
ENV_OPTION_EXCLUDE_KEY = :except
|
51
|
+
|
50
52
|
class Error < StandardError; end
|
51
53
|
|
52
54
|
class ValidationError < Error; end
|
@@ -126,14 +128,36 @@ module Anyway # :nodoc:
|
|
126
128
|
end
|
127
129
|
end
|
128
130
|
|
129
|
-
def required(*names)
|
130
|
-
|
131
|
-
|
132
|
-
end
|
131
|
+
def required(*names, env: nil)
|
132
|
+
unknown_names = names - config_attributes
|
133
|
+
raise ArgumentError, "Unknown config param: #{unknown_names.join(",")}" if unknown_names.any?
|
133
134
|
|
135
|
+
names = filter_by_env(names, env)
|
134
136
|
required_attributes.push(*names)
|
135
137
|
end
|
136
138
|
|
139
|
+
def filter_by_env(names, env)
|
140
|
+
return names if env.nil? || env.to_s == current_env
|
141
|
+
|
142
|
+
filtered_names = if env.is_a?(Hash)
|
143
|
+
names_with_exclude_env_option(names, env)
|
144
|
+
elsif env.is_a?(Array)
|
145
|
+
names if env.flat_map(&:to_s).include?(current_env)
|
146
|
+
end
|
147
|
+
|
148
|
+
filtered_names || []
|
149
|
+
end
|
150
|
+
|
151
|
+
def current_env
|
152
|
+
Settings.current_environment.to_s
|
153
|
+
end
|
154
|
+
|
155
|
+
def names_with_exclude_env_option(names, env)
|
156
|
+
envs = env[ENV_OPTION_EXCLUDE_KEY]
|
157
|
+
excluded_envs = [envs].flat_map(&:to_s)
|
158
|
+
names if excluded_envs.none?(current_env)
|
159
|
+
end
|
160
|
+
|
137
161
|
def required_attributes
|
138
162
|
return @required_attributes if instance_variable_defined?(:@required_attributes)
|
139
163
|
|
data/lib/anyway/loaders/yaml.rb
CHANGED
@@ -10,18 +10,40 @@ module Anyway
|
|
10
10
|
module Loaders
|
11
11
|
class YAML < Base
|
12
12
|
def call(config_path:, **_options)
|
13
|
-
|
13
|
+
rel_config_path = relative_config_path(config_path).to_s
|
14
|
+
base_config = trace!(:yml, path: rel_config_path) do
|
15
|
+
config = load_base_yml(config_path)
|
16
|
+
environmental?(config) ? config_with_env(config) : config
|
17
|
+
end
|
14
18
|
|
15
19
|
return base_config unless use_local?
|
16
20
|
|
17
21
|
local_path = local_config_path(config_path)
|
18
22
|
local_config = trace!(:yml, path: relative_config_path(local_path).to_s) { load_local_yml(local_path) }
|
19
|
-
|
20
23
|
Utils.deep_merge!(base_config, local_config)
|
21
24
|
end
|
22
25
|
|
23
26
|
private
|
24
27
|
|
28
|
+
def environmental?(parsed_yml)
|
29
|
+
# strange, but still possible
|
30
|
+
return true if Settings.default_environmental_key? && parsed_yml.key?(Settings.default_environmental_key)
|
31
|
+
# possible
|
32
|
+
return true if !Settings.future.unwrap_known_environments && Settings.current_environment
|
33
|
+
# for other environments
|
34
|
+
return true if Settings.known_environments&.any? { parsed_yml.key?(_1) }
|
35
|
+
# preferred
|
36
|
+
parsed_yml.key?(Settings.current_environment)
|
37
|
+
end
|
38
|
+
|
39
|
+
def config_with_env(config)
|
40
|
+
env_config = config[Settings.current_environment] || {}
|
41
|
+
return env_config unless Settings.default_environmental_key?
|
42
|
+
|
43
|
+
default_config = config[Settings.default_environmental_key] || {}
|
44
|
+
Utils.deep_merge!(default_config, env_config)
|
45
|
+
end
|
46
|
+
|
25
47
|
def parse_yml(path)
|
26
48
|
return {} unless File.file?(path)
|
27
49
|
require "yaml" unless defined?(::YAML)
|
@@ -54,7 +76,7 @@ module Anyway
|
|
54
76
|
def relative_config_path(path)
|
55
77
|
Pathname.new(path).then do |path|
|
56
78
|
return path if path.relative?
|
57
|
-
path.relative_path_from(
|
79
|
+
path.relative_path_from(Settings.app_root)
|
58
80
|
end
|
59
81
|
end
|
60
82
|
end
|
@@ -3,34 +3,7 @@
|
|
3
3
|
module Anyway
|
4
4
|
module Rails
|
5
5
|
module Loaders
|
6
|
-
class YAML < Anyway::Loaders::YAML
|
7
|
-
def load_base_yml(*)
|
8
|
-
parsed_yml = super
|
9
|
-
return parsed_yml unless environmental?(parsed_yml)
|
10
|
-
|
11
|
-
env_config = parsed_yml[::Rails.env] || {}
|
12
|
-
return env_config if Anyway::Settings.default_environmental_key.blank?
|
13
|
-
|
14
|
-
default_config = parsed_yml[Anyway::Settings.default_environmental_key] || {}
|
15
|
-
Utils.deep_merge!(default_config, env_config)
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def environmental?(parsed_yml)
|
21
|
-
return true unless Settings.future.unwrap_known_environments
|
22
|
-
# likely
|
23
|
-
return true if parsed_yml.key?(::Rails.env)
|
24
|
-
# less likely
|
25
|
-
return true if ::Rails.application.config.anyway_config.known_environments.any? { parsed_yml.key?(_1) }
|
26
|
-
# strange, but still possible
|
27
|
-
Anyway::Settings.default_environmental_key.present? && parsed_yml.key?(Anyway::Settings.default_environmental_key)
|
28
|
-
end
|
29
|
-
|
30
|
-
def relative_config_path(path)
|
31
|
-
Pathname.new(path).relative_path_from(::Rails.root)
|
32
|
-
end
|
33
|
-
end
|
6
|
+
class YAML < Anyway::Loaders::YAML; end
|
34
7
|
end
|
35
8
|
end
|
36
9
|
end
|
@@ -9,16 +9,8 @@ end
|
|
9
9
|
|
10
10
|
module Anyway
|
11
11
|
class Settings
|
12
|
-
class Future
|
13
|
-
setting :unwrap_known_environments, true
|
14
|
-
end
|
15
|
-
|
16
12
|
class << self
|
17
13
|
attr_reader :autoload_static_config_path, :autoloader
|
18
|
-
attr_accessor :known_environments
|
19
|
-
|
20
|
-
# Define a key for environmental yaml files to read default values from
|
21
|
-
attr_accessor :default_environmental_key
|
22
14
|
|
23
15
|
if defined?(::Zeitwerk)
|
24
16
|
def autoload_static_config_path=(val)
|
@@ -62,6 +54,14 @@ module Anyway
|
|
62
54
|
:no_op
|
63
55
|
end
|
64
56
|
end
|
57
|
+
|
58
|
+
def current_environment
|
59
|
+
::Rails.env.to_s
|
60
|
+
end
|
61
|
+
|
62
|
+
def app_root
|
63
|
+
::Rails.root
|
64
|
+
end
|
65
65
|
end
|
66
66
|
|
67
67
|
self.default_config_path = ->(name) { ::Rails.root.join("config", "#{name}.yml") }
|
data/lib/anyway/settings.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "pathname"
|
4
|
+
|
3
5
|
module Anyway
|
4
6
|
# Use Settings name to not confuse with Config.
|
5
7
|
#
|
@@ -35,6 +37,8 @@ module Anyway
|
|
35
37
|
names.each { store[_1] = self.class.settings[_1] }
|
36
38
|
end
|
37
39
|
|
40
|
+
setting :unwrap_known_environments, true
|
41
|
+
|
38
42
|
private
|
39
43
|
|
40
44
|
attr_reader :store
|
@@ -43,7 +47,10 @@ module Anyway
|
|
43
47
|
class << self
|
44
48
|
# Define whether to load data from
|
45
49
|
# *.yml.local (or credentials/local.yml.enc)
|
46
|
-
attr_accessor :use_local_files
|
50
|
+
attr_accessor :use_local_files,
|
51
|
+
:current_environment,
|
52
|
+
:default_environmental_key,
|
53
|
+
:known_environments
|
47
54
|
|
48
55
|
# A proc returning a path to YML config file given the config name
|
49
56
|
attr_reader :default_config_path
|
@@ -65,6 +72,14 @@ module Anyway
|
|
65
72
|
def future
|
66
73
|
@future ||= Future.new
|
67
74
|
end
|
75
|
+
|
76
|
+
def app_root
|
77
|
+
Pathname.new(Dir.pwd)
|
78
|
+
end
|
79
|
+
|
80
|
+
def default_environmental_key?
|
81
|
+
!default_environmental_key.nil?
|
82
|
+
end
|
68
83
|
end
|
69
84
|
|
70
85
|
# By default, use local files only in development (that's the purpose if the local files)
|
data/lib/anyway/tracing.rb
CHANGED
@@ -6,12 +6,6 @@ module Anyway
|
|
6
6
|
using Anyway::Ext::DeepDup
|
7
7
|
|
8
8
|
using(Module.new do
|
9
|
-
refine Hash do
|
10
|
-
def inspect
|
11
|
-
"{#{map { |k, v| "#{k}: #{v.inspect}" }.join(", ")}}"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
9
|
refine Thread::Backtrace::Location do
|
16
10
|
def path_lineno() = "#{path}:#{lineno}"
|
17
11
|
end
|
@@ -100,8 +94,15 @@ module Anyway
|
|
100
94
|
q.group do
|
101
95
|
q.text k
|
102
96
|
q.text " =>"
|
103
|
-
|
104
|
-
|
97
|
+
if v.trace?
|
98
|
+
q.text " { "
|
99
|
+
q.pp v
|
100
|
+
q.breakable " "
|
101
|
+
q.text "}"
|
102
|
+
else
|
103
|
+
q.breakable " "
|
104
|
+
q.pp v
|
105
|
+
end
|
105
106
|
end
|
106
107
|
end
|
107
108
|
end
|
data/lib/anyway/version.rb
CHANGED
data/sig/anyway_config.rbs
CHANGED
@@ -3,8 +3,11 @@ module Anyway
|
|
3
3
|
def self.loaders: -> Loaders::Registry
|
4
4
|
|
5
5
|
class Settings
|
6
|
-
def self.default_config_path=: (^(untyped) -> String val) ->
|
6
|
+
def self.default_config_path=: (String | Pathname | ^(untyped) -> String val) -> void
|
7
7
|
def self.future: -> Future
|
8
|
+
def self.current_environment: -> String?
|
9
|
+
def self.default_environmental_key: -> String?
|
10
|
+
def self.known_environments: -> Array[String]?
|
8
11
|
|
9
12
|
class Future
|
10
13
|
def self.setting: (untyped name, untyped default_value) -> untyped
|
@@ -19,14 +22,14 @@ module Anyway
|
|
19
22
|
end
|
20
23
|
|
21
24
|
def inspect: -> String
|
22
|
-
def self.capture: ?{ -> Hash[untyped, untyped] } ->
|
25
|
+
def self.capture: ?{ -> Hash[untyped, untyped]? } -> Trace
|
23
26
|
def self.trace_stack: -> Array[untyped]
|
24
27
|
def self.current_trace: -> Trace?
|
25
28
|
def self.source_stack: -> Array[untyped]
|
26
|
-
def self.current_trace_source: -> {type:
|
27
|
-
def self.with_trace_source: (untyped src) -> untyped
|
28
|
-
def trace!: (Symbol, *
|
29
|
-
def self.trace!: (Symbol, *
|
29
|
+
def self.current_trace_source: -> ({type: Symbol} & Hash[Symbol, untyped])
|
30
|
+
def self.with_trace_source: (untyped src) { -> void } -> untyped
|
31
|
+
def trace!: [V] (Symbol, *String paths, **untyped) ?{ -> V} -> V
|
32
|
+
def self.trace!: [V] (Symbol, *String paths, **untyped) ?{ -> V} -> V
|
30
33
|
end
|
31
34
|
|
32
35
|
module RBSGenerator
|
@@ -56,6 +59,7 @@ module Anyway
|
|
56
59
|
type hashType = Hash[Symbol, valueType | arrayType | hashType]
|
57
60
|
|
58
61
|
type mappingType = valueType | arrayType | hashType
|
62
|
+
type envType = String | Symbol | Array[String | Symbol] | {except: String | Symbol | Array[String | Symbol]}
|
59
63
|
|
60
64
|
class Config
|
61
65
|
extend RBSGenerator
|
@@ -67,7 +71,7 @@ module Anyway
|
|
67
71
|
def self.attr_config: (*Symbol args, **untyped) -> void
|
68
72
|
def self.defaults: -> Hash[String, untyped]
|
69
73
|
def self.config_attributes: -> Array[Symbol]?
|
70
|
-
def self.required: (*Symbol names) -> void
|
74
|
+
def self.required: (*Symbol names, ?env: envType) -> void
|
71
75
|
def self.required_attributes: -> Array[Symbol]
|
72
76
|
def self.on_load: (*Symbol callbacks) ?{ () -> void } -> void
|
73
77
|
def self.config_name: (?(Symbol | String) val) -> String?
|
@@ -80,9 +84,11 @@ module Anyway
|
|
80
84
|
attr_reader env_prefix: String
|
81
85
|
|
82
86
|
def initialize: (?Hash[Symbol | String, untyped] overrides) -> void
|
87
|
+
| (NilClass) -> void
|
83
88
|
def reload: (?Hash[Symbol | String, untyped] overrides) -> Config
|
84
89
|
def clear: -> void
|
85
90
|
def load: (Hash[Symbol | String, untyped] overrides) -> Config
|
91
|
+
| (NilClass) -> Config
|
86
92
|
def dig: (*(Symbol | String) keys) -> untyped
|
87
93
|
def to_h: -> Hash[untyped, untyped]
|
88
94
|
def dup: -> Config
|
@@ -117,12 +123,21 @@ module Anyway
|
|
117
123
|
def use_local?: -> bool
|
118
124
|
end
|
119
125
|
|
126
|
+
interface _Loader
|
127
|
+
def call: (**untyped) -> Hash[untyped, untyped]
|
128
|
+
end
|
129
|
+
|
120
130
|
class Registry
|
121
|
-
def prepend: (Symbol id,
|
122
|
-
|
123
|
-
def
|
124
|
-
|
125
|
-
def
|
131
|
+
def prepend: (Symbol id, _Loader loader) -> void
|
132
|
+
| (Symbol id) { (**untyped) -> Hash[untyped, untyped] } -> void
|
133
|
+
def append: (Symbol id, _Loader loader) -> void
|
134
|
+
| (Symbol id) { (**untyped) -> Hash[untyped, untyped] } -> void
|
135
|
+
def insert_before: (Symbol another_id, Symbol id, _Loader loader) -> void
|
136
|
+
| (Symbol another_id, Symbol id) { (**untyped) -> Hash[untyped, untyped] } -> void
|
137
|
+
def insert_after: (Symbol another_id, Symbol id, _Loader loader) -> void
|
138
|
+
| (Symbol another_id, Symbol id) { (**untyped) -> Hash[untyped, untyped] } -> void
|
139
|
+
def override: (Symbol id, _Loader loader) -> void
|
140
|
+
| (Symbol id) { (**untyped) -> Hash[untyped, untyped] } -> void
|
126
141
|
def delete: (Symbol id) -> void
|
127
142
|
end
|
128
143
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: anyway_config
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Dementyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-next-core
|
@@ -108,7 +108,7 @@ files:
|
|
108
108
|
- README.md
|
109
109
|
- lib/.rbnext/2.7/anyway/auto_cast.rb
|
110
110
|
- lib/.rbnext/2.7/anyway/config.rb
|
111
|
-
- lib/.rbnext/2.7/anyway/
|
111
|
+
- lib/.rbnext/2.7/anyway/loaders/yaml.rb
|
112
112
|
- lib/.rbnext/2.7/anyway/rbs.rb
|
113
113
|
- lib/.rbnext/2.7/anyway/settings.rb
|
114
114
|
- lib/.rbnext/2.7/anyway/tracing.rb
|
@@ -1,36 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Anyway
|
4
|
-
module Rails
|
5
|
-
module Loaders
|
6
|
-
class YAML < Anyway::Loaders::YAML
|
7
|
-
def load_base_yml(*)
|
8
|
-
parsed_yml = super
|
9
|
-
return parsed_yml unless environmental?(parsed_yml)
|
10
|
-
|
11
|
-
env_config = parsed_yml[::Rails.env] || {}
|
12
|
-
return env_config if Anyway::Settings.default_environmental_key.blank?
|
13
|
-
|
14
|
-
default_config = parsed_yml[Anyway::Settings.default_environmental_key] || {}
|
15
|
-
Utils.deep_merge!(default_config, env_config)
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def environmental?(parsed_yml)
|
21
|
-
return true unless Settings.future.unwrap_known_environments
|
22
|
-
# likely
|
23
|
-
return true if parsed_yml.key?(::Rails.env)
|
24
|
-
# less likely
|
25
|
-
return true if ::Rails.application.config.anyway_config.known_environments.any? { |_1| parsed_yml.key?(_1) }
|
26
|
-
# strange, but still possible
|
27
|
-
Anyway::Settings.default_environmental_key.present? && parsed_yml.key?(Anyway::Settings.default_environmental_key)
|
28
|
-
end
|
29
|
-
|
30
|
-
def relative_config_path(path)
|
31
|
-
Pathname.new(path).relative_path_from(::Rails.root)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|