anyway_config 2.6.1 → 2.6.3

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 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