anyway_config 2.6.1 → 2.6.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ddc4b1bdc750d6aa71030a8140e25127d20ec041254bdf79e239c44d1804d5eb
4
- data.tar.gz: 42be794c396f2c861707560b8d63e6d51350f458c4da10e650006f2e6b6cbf0e
3
+ metadata.gz: 9272986ff4c206ffad5c0877ca80e7506568f37ec5bce4d2d21de72c4892780e
4
+ data.tar.gz: b2437f38022bb345cee5d4d92f482ff3ca0e4789420c68a8f8c3121b27e92403
5
5
  SHA512:
6
- metadata.gz: 3a8ef640dd47a01fa5bf5fb6d755b46996286ab772ae094e3ccc1bede6156f16259296e9f2a48766c1debc7052e83c8ffd3ed1de329642264295bcb0b934b5bc
7
- data.tar.gz: 1822daadbcb3ffcfdf4cae76bf306396aa794d2fbea2f13191e76b0320443a839af5aeeab3cfd44077a327ddc8d21fb3710adc81947bb8df9e551a9b09e8691d
6
+ metadata.gz: b2081d401c0f624420ee215c3d5941e17c2e7a0180e8e803830442ed284e5316631be8f458f903a61c6c234e94d05c1a4fb9c3e6f52f9e03435cea4db466806d
7
+ data.tar.gz: 36cff9c0ad7a1c0f6c5a5ff9b601f31dd559936fdb6edcbd50457f3c65a8337e5dc68c185e7888a46e7ae89909aab9d2aa3cc3ef7fe1949d6d21057bcc731584
data/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 2.6.3 (2024-02-06)
6
+
7
+ - Add `permitted_classes` configuration for YAML loaders. ([@palkan][])
8
+
9
+ ## 2.6.2 (2024-01-08)
10
+
11
+ - Fix Ruby 3.3.0 compatibility issues (caused by [Ruby bug](https://bugs.ruby-lang.org/issues/20090)) ([@palkan][])
12
+
5
13
  ## 2.6.1 (2023-12-22)
6
14
 
7
15
  - Fix Ruby Next version requirements. ([@palkan][])
@@ -334,7 +342,7 @@ attr_config :host, :port, :url, :meta
334
342
 
335
343
  # override writer to handle type coercion
336
344
  def meta=(val)
337
- super JSON.parse(val)
345
+ super(JSON.parse(val))
338
346
  end
339
347
 
340
348
  # or override reader to handle missing values
data/README.md CHANGED
@@ -158,7 +158,7 @@ class MyConfig < Anyway::Config
158
158
 
159
159
  # override writer to handle type coercion
160
160
  def meta=(val)
161
- super JSON.parse(val)
161
+ super(JSON.parse(val))
162
162
  end
163
163
 
164
164
  # or override reader to handle missing values
@@ -370,6 +370,12 @@ development:
370
370
 
371
371
  **NOTE:** You can override the environment name for configuration files via the `ANYWAY_ENV` environment variable or by setting it explicitly in the code: `Anyway::Settings.current_environment = "some_other_env"`.
372
372
 
373
+ You can also configure additional Ruby classes that you want to deserialized from YAML (`permitted_classes` option). For example:
374
+
375
+ ```ruby
376
+ Anyway::Loaders::YAML.permitted_classes << Date
377
+ ```
378
+
373
379
  ### Multi-env configuration
374
380
 
375
381
  _⚡️ This feature will be turned on by default in the future releases. You can turn it on now via `config.anyway_config.future.use :unwrap_known_environments`._
@@ -389,9 +389,9 @@ module Anyway # :nodoc:
389
389
  self
390
390
  end
391
391
 
392
- def load_from_sources(base_config, **__kwrest__)
392
+ def load_from_sources(base_config, **opts)
393
393
  Anyway.loaders.each do |(_id, loader)|
394
- Utils.deep_merge!(base_config, loader.call(**__kwrest__))
394
+ Utils.deep_merge!(base_config, loader.call(**opts))
395
395
  end
396
396
  base_config
397
397
  end
@@ -9,6 +9,12 @@ using Anyway::Ext::Hash
9
9
  module Anyway
10
10
  module Loaders
11
11
  class YAML < Base
12
+ @@permitted_classes = []
13
+
14
+ class << self
15
+ def permitted_classes ; @@permitted_classes; end
16
+ end
17
+
12
18
  def call(config_path:, **_options)
13
19
  rel_config_path = relative_config_path(config_path).to_s
14
20
  base_config = trace!(:yml, path: rel_config_path) do
@@ -53,9 +59,9 @@ module Anyway
53
59
  # the interface when no config file is present.
54
60
  begin
55
61
  if defined?(ERB)
56
- ::YAML.load(ERB.new(File.read(path)).result, aliases: true) || {}
62
+ ::YAML.load(ERB.new(File.read(path)).result, aliases: true, permitted_classes: self.class.permitted_classes) || {}
57
63
  else
58
- ::YAML.load_file(path, aliases: true) || {}
64
+ ::YAML.load_file(path, aliases: true, permitted_classes: self.class.permitted_classes) || {}
59
65
  end
60
66
  rescue ArgumentError
61
67
  if defined?(ERB)
@@ -26,12 +26,12 @@ module Anyway
26
26
  value.dig(*__rest__, &__block__)
27
27
  end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :dig)
28
28
 
29
- def record_value(val, *path, **__kwrest__)
29
+ def record_value(val, *path, **opts)
30
30
  key = path.pop
31
31
  trace = if val.is_a?(Hash)
32
- Trace.new.tap { |_1| it = _1;it.merge_values(val, **__kwrest__) }
32
+ Trace.new.tap { |_1| it = _1;it.merge_values(val, **opts) }
33
33
  else
34
- Trace.new(:value, val, **__kwrest__)
34
+ Trace.new(:value, val, **opts)
35
35
  end
36
36
 
37
37
  target_trace = path.empty? ? self : value.dig(*path)
@@ -40,14 +40,14 @@ module Anyway
40
40
  val
41
41
  end
42
42
 
43
- def merge_values(hash, **__kwrest__)
43
+ def merge_values(hash, **opts)
44
44
  return hash unless hash
45
45
 
46
46
  hash.each do |key, val|
47
47
  if val.is_a?(Hash)
48
- value[key.to_s].merge_values(val, **__kwrest__)
48
+ value[key.to_s].merge_values(val, **opts)
49
49
  else
50
- value[key.to_s] = Trace.new(:value, val, **__kwrest__)
50
+ value[key.to_s] = Trace.new(:value, val, **opts)
51
51
  end
52
52
  end
53
53
 
@@ -389,9 +389,9 @@ module Anyway # :nodoc:
389
389
  self
390
390
  end
391
391
 
392
- def load_from_sources(base_config, **__kwrest__)
392
+ def load_from_sources(base_config, **opts)
393
393
  Anyway.loaders.each do |(_id, loader)|
394
- Utils.deep_merge!(base_config, loader.call(**__kwrest__))
394
+ Utils.deep_merge!(base_config, loader.call(**opts))
395
395
  end
396
396
  base_config
397
397
  end
@@ -0,0 +1,90 @@
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
+ @@permitted_classes = []
13
+
14
+ class << self
15
+ def permitted_classes ; @@permitted_classes; end
16
+ end
17
+
18
+ def call(config_path:, **_options)
19
+ rel_config_path = relative_config_path(config_path).to_s
20
+ base_config = trace!(:yml, path: rel_config_path) do
21
+ config = load_base_yml(config_path)
22
+ environmental?(config) ? config_with_env(config) : config
23
+ end
24
+
25
+ return base_config unless use_local?
26
+
27
+ local_path = local_config_path(config_path)
28
+ local_config = trace!(:yml, path: relative_config_path(local_path).to_s) { load_local_yml(local_path) }
29
+ Utils.deep_merge!(base_config, local_config)
30
+ end
31
+
32
+ private
33
+
34
+ def environmental?(parsed_yml)
35
+ # strange, but still possible
36
+ return true if Settings.default_environmental_key? && parsed_yml.key?(Settings.default_environmental_key)
37
+ # possible
38
+ return true if !Settings.future.unwrap_known_environments && Settings.current_environment
39
+ # for other environments
40
+ return true if Settings.known_environments&.any? { parsed_yml.key?(_1) }
41
+ # preferred
42
+ parsed_yml.key?(Settings.current_environment)
43
+ end
44
+
45
+ def config_with_env(config)
46
+ env_config = config[Settings.current_environment] || {}
47
+ return env_config unless Settings.default_environmental_key?
48
+
49
+ default_config = config[Settings.default_environmental_key] || {}
50
+ Utils.deep_merge!(default_config, env_config)
51
+ end
52
+
53
+ def parse_yml(path)
54
+ return {} unless File.file?(path)
55
+ require "yaml" unless defined?(::YAML)
56
+
57
+ # By default, YAML load will return `false` when the yaml document is
58
+ # empty. When this occurs, we return an empty hash instead, to match
59
+ # the interface when no config file is present.
60
+ begin
61
+ if defined?(ERB)
62
+ ::YAML.load(ERB.new(File.read(path)).result, aliases: true, permitted_classes: self.class.permitted_classes) || {}
63
+ else
64
+ ::YAML.load_file(path, aliases: true, permitted_classes: self.class.permitted_classes) || {}
65
+ end
66
+ rescue ArgumentError
67
+ if defined?(ERB)
68
+ ::YAML.load(ERB.new(File.read(path)).result) || {}
69
+ else
70
+ ::YAML.load_file(path) || {}
71
+ end
72
+ end
73
+ end
74
+
75
+ alias_method :load_base_yml, :parse_yml
76
+ alias_method :load_local_yml, :parse_yml
77
+
78
+ def local_config_path(path)
79
+ path.sub(".yml", ".local.yml")
80
+ end
81
+
82
+ def relative_config_path(path)
83
+ Pathname.new(path).then do |path|
84
+ return path if path.relative?
85
+ path.relative_path_from(Settings.app_root)
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -26,12 +26,12 @@ module Anyway
26
26
  value.dig(...)
27
27
  end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :dig)
28
28
 
29
- def record_value(val, *path, **__kwrest__)
29
+ def record_value(val, *path, **opts)
30
30
  key = path.pop
31
31
  trace = if val.is_a?(Hash)
32
- Trace.new.tap { it = _1;it.merge_values(val, **__kwrest__) }
32
+ Trace.new.tap { it = _1;it.merge_values(val, **opts) }
33
33
  else
34
- Trace.new(:value, val, **__kwrest__)
34
+ Trace.new(:value, val, **opts)
35
35
  end
36
36
 
37
37
  target_trace = path.empty? ? self : value.dig(*path)
@@ -40,14 +40,14 @@ module Anyway
40
40
  val
41
41
  end
42
42
 
43
- def merge_values(hash, **__kwrest__)
43
+ def merge_values(hash, **opts)
44
44
  return hash unless hash
45
45
 
46
46
  hash.each do |key, val|
47
47
  if val.is_a?(Hash)
48
- value[key.to_s].merge_values(val, **__kwrest__)
48
+ value[key.to_s].merge_values(val, **opts)
49
49
  else
50
- value[key.to_s] = Trace.new(:value, val, **__kwrest__)
50
+ value[key.to_s] = Trace.new(:value, val, **opts)
51
51
  end
52
52
  end
53
53
 
@@ -389,9 +389,9 @@ module Anyway # :nodoc:
389
389
  self
390
390
  end
391
391
 
392
- def load_from_sources(base_config, **__kwrest__)
392
+ def load_from_sources(base_config, **opts)
393
393
  Anyway.loaders.each do |(_id, loader)|
394
- Utils.deep_merge!(base_config, loader.call(**__kwrest__))
394
+ Utils.deep_merge!(base_config, loader.call(**opts))
395
395
  end
396
396
  base_config
397
397
  end
@@ -26,12 +26,12 @@ module Anyway
26
26
  value.dig(...)
27
27
  end
28
28
 
29
- def record_value(val, *path, **__kwrest__)
29
+ def record_value(val, *path, **opts)
30
30
  key = path.pop
31
31
  trace = if val.is_a?(Hash)
32
- Trace.new.tap { it = _1;it.merge_values(val, **__kwrest__) }
32
+ Trace.new.tap { it = _1;it.merge_values(val, **opts) }
33
33
  else
34
- Trace.new(:value, val, **__kwrest__)
34
+ Trace.new(:value, val, **opts)
35
35
  end
36
36
 
37
37
  target_trace = path.empty? ? self : value.dig(*path)
@@ -40,14 +40,14 @@ module Anyway
40
40
  val
41
41
  end
42
42
 
43
- def merge_values(hash, **__kwrest__)
43
+ def merge_values(hash, **opts)
44
44
  return hash unless hash
45
45
 
46
46
  hash.each do |key, val|
47
47
  if val.is_a?(Hash)
48
- value[key.to_s].merge_values(val, **__kwrest__)
48
+ value[key.to_s].merge_values(val, **opts)
49
49
  else
50
- value[key.to_s] = Trace.new(:value, val, **__kwrest__)
50
+ value[key.to_s] = Trace.new(:value, val, **opts)
51
51
  end
52
52
  end
53
53
 
@@ -389,9 +389,9 @@ module Anyway # :nodoc:
389
389
  self
390
390
  end
391
391
 
392
- def load_from_sources(base_config, **__kwrest__)
392
+ def load_from_sources(base_config, **opts)
393
393
  Anyway.loaders.each do |(_id, loader)|
394
- Utils.deep_merge!(base_config, loader.call(**__kwrest__))
394
+ Utils.deep_merge!(base_config, loader.call(**opts))
395
395
  end
396
396
  base_config
397
397
  end
@@ -26,12 +26,12 @@ module Anyway
26
26
  value.dig(...)
27
27
  end
28
28
 
29
- def record_value(val, *path, **__kwrest__)
29
+ def record_value(val, *path, **opts)
30
30
  key = path.pop
31
31
  trace = if val.is_a?(Hash)
32
- Trace.new.tap { it = _1;it.merge_values(val, **__kwrest__) }
32
+ Trace.new.tap { it = _1;it.merge_values(val, **opts) }
33
33
  else
34
- Trace.new(:value, val, **__kwrest__)
34
+ Trace.new(:value, val, **opts)
35
35
  end
36
36
 
37
37
  target_trace = path.empty? ? self : value.dig(*path)
@@ -40,14 +40,14 @@ module Anyway
40
40
  val
41
41
  end
42
42
 
43
- def merge_values(hash, **__kwrest__)
43
+ def merge_values(hash, **opts)
44
44
  return hash unless hash
45
45
 
46
46
  hash.each do |key, val|
47
47
  if val.is_a?(Hash)
48
- value[key.to_s].merge_values(val, **__kwrest__)
48
+ value[key.to_s].merge_values(val, **opts)
49
49
  else
50
- value[key.to_s] = Trace.new(:value, val, **__kwrest__)
50
+ value[key.to_s] = Trace.new(:value, val, **opts)
51
51
  end
52
52
  end
53
53
 
@@ -389,9 +389,9 @@ module Anyway # :nodoc:
389
389
  self
390
390
  end
391
391
 
392
- def load_from_sources(base_config, **)
392
+ def load_from_sources(base_config, **opts)
393
393
  Anyway.loaders.each do |(_id, loader)|
394
- Utils.deep_merge!(base_config, loader.call(**))
394
+ Utils.deep_merge!(base_config, loader.call(**opts))
395
395
  end
396
396
  base_config
397
397
  end
@@ -26,12 +26,12 @@ module Anyway
26
26
  value.dig(...)
27
27
  end
28
28
 
29
- def record_value(val, *path, **)
29
+ def record_value(val, *path, **opts)
30
30
  key = path.pop
31
31
  trace = if val.is_a?(Hash)
32
- Trace.new.tap { it = _1;it.merge_values(val, **) }
32
+ Trace.new.tap { it = _1;it.merge_values(val, **opts) }
33
33
  else
34
- Trace.new(:value, val, **)
34
+ Trace.new(:value, val, **opts)
35
35
  end
36
36
 
37
37
  target_trace = path.empty? ? self : value.dig(*path)
@@ -40,14 +40,14 @@ module Anyway
40
40
  val
41
41
  end
42
42
 
43
- def merge_values(hash, **)
43
+ def merge_values(hash, **opts)
44
44
  return hash unless hash
45
45
 
46
46
  hash.each do |key, val|
47
47
  if val.is_a?(Hash)
48
- value[key.to_s].merge_values(val, **)
48
+ value[key.to_s].merge_values(val, **opts)
49
49
  else
50
- value[key.to_s] = Trace.new(:value, val, **)
50
+ value[key.to_s] = Trace.new(:value, val, **opts)
51
51
  end
52
52
  end
53
53
 
data/lib/anyway/config.rb CHANGED
@@ -389,9 +389,9 @@ module Anyway # :nodoc:
389
389
  self
390
390
  end
391
391
 
392
- def load_from_sources(base_config, **)
392
+ def load_from_sources(base_config, **opts)
393
393
  Anyway.loaders.each do |(_id, loader)|
394
- Utils.deep_merge!(base_config, loader.call(**))
394
+ Utils.deep_merge!(base_config, loader.call(**opts))
395
395
  end
396
396
  base_config
397
397
  end
@@ -9,6 +9,12 @@ using Anyway::Ext::Hash
9
9
  module Anyway
10
10
  module Loaders
11
11
  class YAML < Base
12
+ @@permitted_classes = []
13
+
14
+ class << self
15
+ def permitted_classes = @@permitted_classes
16
+ end
17
+
12
18
  def call(config_path:, **_options)
13
19
  rel_config_path = relative_config_path(config_path).to_s
14
20
  base_config = trace!(:yml, path: rel_config_path) do
@@ -53,9 +59,9 @@ module Anyway
53
59
  # the interface when no config file is present.
54
60
  begin
55
61
  if defined?(ERB)
56
- ::YAML.load(ERB.new(File.read(path)).result, aliases: true) || {}
62
+ ::YAML.load(ERB.new(File.read(path)).result, aliases: true, permitted_classes: self.class.permitted_classes) || {}
57
63
  else
58
- ::YAML.load_file(path, aliases: true) || {}
64
+ ::YAML.load_file(path, aliases: true, permitted_classes: self.class.permitted_classes) || {}
59
65
  end
60
66
  rescue ArgumentError
61
67
  if defined?(ERB)
@@ -26,12 +26,12 @@ module Anyway
26
26
  value.dig(...)
27
27
  end
28
28
 
29
- def record_value(val, *path, **)
29
+ def record_value(val, *path, **opts)
30
30
  key = path.pop
31
31
  trace = if val.is_a?(Hash)
32
- Trace.new.tap { it.merge_values(val, **) }
32
+ Trace.new.tap { it.merge_values(val, **opts) }
33
33
  else
34
- Trace.new(:value, val, **)
34
+ Trace.new(:value, val, **opts)
35
35
  end
36
36
 
37
37
  target_trace = path.empty? ? self : value.dig(*path)
@@ -40,14 +40,14 @@ module Anyway
40
40
  val
41
41
  end
42
42
 
43
- def merge_values(hash, **)
43
+ def merge_values(hash, **opts)
44
44
  return hash unless hash
45
45
 
46
46
  hash.each do |key, val|
47
47
  if val.is_a?(Hash)
48
- value[key.to_s].merge_values(val, **)
48
+ value[key.to_s].merge_values(val, **opts)
49
49
  else
50
- value[key.to_s] = Trace.new(:value, val, **)
50
+ value[key.to_s] = Trace.new(:value, val, **opts)
51
51
  end
52
52
  end
53
53
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Anyway # :nodoc:
4
- VERSION = "2.6.1"
4
+ VERSION = "2.6.3"
5
5
  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.6.1
4
+ version: 2.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-22 00:00:00.000000000 Z
11
+ date: 2024-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-next-core
@@ -132,6 +132,7 @@ files:
132
132
  - lib/.rbnext/3.0/anyway/config.rb
133
133
  - lib/.rbnext/3.0/anyway/loaders.rb
134
134
  - lib/.rbnext/3.0/anyway/loaders/base.rb
135
+ - lib/.rbnext/3.0/anyway/loaders/yaml.rb
135
136
  - lib/.rbnext/3.0/anyway/tracing.rb
136
137
  - lib/.rbnext/3.1/anyway/config.rb
137
138
  - lib/.rbnext/3.1/anyway/dynamic_config.rb