runger_config 3.0.1 → 5.0.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.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -35
  3. data/README.md +83 -83
  4. data/lib/generators/runger/app_config/app_config_generator.rb +13 -0
  5. data/lib/generators/runger/config/config_generator.rb +49 -0
  6. data/lib/generators/runger/install/install_generator.rb +45 -0
  7. data/lib/generators/{anyway → runger}/install/templates/application_config.rb.tt +1 -1
  8. data/lib/{anyway → runger}/auto_cast.rb +4 -4
  9. data/lib/{anyway → runger}/config.rb +124 -104
  10. data/lib/runger/dynamic_config.rb +29 -0
  11. data/lib/runger/ejson_parser.rb +40 -0
  12. data/lib/runger/env.rb +70 -0
  13. data/lib/runger/ext/deep_dup.rb +45 -0
  14. data/lib/runger/ext/deep_freeze.rb +40 -0
  15. data/lib/runger/ext/flatten_names.rb +33 -0
  16. data/lib/runger/ext/hash.rb +37 -0
  17. data/lib/runger/ext/string_constantize.rb +21 -0
  18. data/lib/runger/loaders/base.rb +17 -0
  19. data/lib/runger/loaders/doppler.rb +57 -0
  20. data/lib/runger/loaders/ejson.rb +91 -0
  21. data/lib/runger/loaders/env.rb +12 -0
  22. data/lib/runger/loaders/yaml.rb +86 -0
  23. data/lib/runger/loaders.rb +75 -0
  24. data/lib/runger/option_parser_builder.rb +27 -0
  25. data/lib/{anyway → runger}/optparse_config.rb +15 -14
  26. data/lib/runger/rails/autoload.rb +38 -0
  27. data/lib/runger/rails/config.rb +19 -0
  28. data/lib/runger/rails/loaders/credentials.rb +58 -0
  29. data/lib/runger/rails/loaders/secrets.rb +31 -0
  30. data/lib/runger/rails/loaders/yaml.rb +4 -0
  31. data/lib/runger/rails/loaders.rb +5 -0
  32. data/lib/runger/rails/settings.rb +83 -0
  33. data/lib/runger/rails.rb +22 -0
  34. data/lib/{anyway → runger}/railtie.rb +9 -8
  35. data/lib/{anyway → runger}/rbs.rb +30 -30
  36. data/lib/runger/settings.rb +109 -0
  37. data/lib/runger/testing/helpers.rb +34 -0
  38. data/lib/{anyway → runger}/testing.rb +3 -3
  39. data/lib/runger/tracing.rb +195 -0
  40. data/lib/{anyway → runger}/type_casting.rb +19 -14
  41. data/lib/{anyway → runger}/utils/deep_merge.rb +2 -2
  42. data/lib/runger/utils/which.rb +16 -0
  43. data/lib/runger/version.rb +5 -0
  44. data/lib/{anyway.rb → runger.rb} +1 -1
  45. data/lib/runger_config.rb +56 -0
  46. data/sig/{anyway_config.rbs → runger_config.rbs} +1 -1
  47. metadata +68 -68
  48. data/lib/anyway/dynamic_config.rb +0 -31
  49. data/lib/anyway/ejson_parser.rb +0 -40
  50. data/lib/anyway/env.rb +0 -72
  51. data/lib/anyway/ext/deep_dup.rb +0 -48
  52. data/lib/anyway/ext/deep_freeze.rb +0 -44
  53. data/lib/anyway/ext/flatten_names.rb +0 -37
  54. data/lib/anyway/ext/hash.rb +0 -40
  55. data/lib/anyway/ext/string_constantize.rb +0 -24
  56. data/lib/anyway/loaders/base.rb +0 -21
  57. data/lib/anyway/loaders/doppler.rb +0 -61
  58. data/lib/anyway/loaders/ejson.rb +0 -89
  59. data/lib/anyway/loaders/env.rb +0 -16
  60. data/lib/anyway/loaders/yaml.rb +0 -83
  61. data/lib/anyway/loaders.rb +0 -77
  62. data/lib/anyway/option_parser_builder.rb +0 -29
  63. data/lib/anyway/rails/autoload.rb +0 -40
  64. data/lib/anyway/rails/config.rb +0 -23
  65. data/lib/anyway/rails/loaders/credentials.rb +0 -62
  66. data/lib/anyway/rails/loaders/secrets.rb +0 -35
  67. data/lib/anyway/rails/loaders/yaml.rb +0 -9
  68. data/lib/anyway/rails/loaders.rb +0 -5
  69. data/lib/anyway/rails/settings.rb +0 -83
  70. data/lib/anyway/rails.rb +0 -24
  71. data/lib/anyway/settings.rb +0 -111
  72. data/lib/anyway/testing/helpers.rb +0 -36
  73. data/lib/anyway/tracing.rb +0 -188
  74. data/lib/anyway/utils/which.rb +0 -18
  75. data/lib/anyway/version.rb +0 -5
  76. data/lib/anyway_config.rb +0 -49
  77. data/lib/generators/anyway/app_config/app_config_generator.rb +0 -17
  78. data/lib/generators/anyway/config/config_generator.rb +0 -46
  79. data/lib/generators/anyway/install/install_generator.rb +0 -47
  80. /data/lib/generators/{anyway → runger}/app_config/USAGE +0 -0
  81. /data/lib/generators/{anyway → runger}/config/USAGE +0 -0
  82. /data/lib/generators/{anyway → runger}/config/templates/config.rb.tt +0 -0
  83. /data/lib/generators/{anyway → runger}/config/templates/config.yml.tt +0 -0
  84. /data/lib/generators/{anyway → runger}/install/USAGE +0 -0
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Anyway
3
+ module Runger
4
4
  # Contains a mapping between type IDs/names and deserializers
5
5
  class TypeRegistry
6
6
  class << self
@@ -15,7 +15,8 @@ module Anyway
15
15
 
16
16
  def accept(name_or_object, &block)
17
17
  if !block && !name_or_object.respond_to?(:call)
18
- raise ArgumentError, "Please, provide a type casting block or an object implementing #call(val) method"
18
+ raise(ArgumentError,
19
+ 'Please, provide a type casting block or an object implementing #call(val) method')
19
20
  end
20
21
 
21
22
  registry[name_or_object] = block || name_or_object
@@ -26,9 +27,13 @@ module Anyway
26
27
 
27
28
  caster =
28
29
  if type_id.is_a?(Symbol) || type_id.nil?
29
- registry.fetch(type_id) { raise ArgumentError, "Unknown type: #{type_id}" }
30
+ registry.fetch(type_id) { raise(ArgumentError, "Unknown type: #{type_id}") }
30
31
  else
31
- raise ArgumentError, "Type must implement #call(val): #{type_id}" unless type_id.respond_to?(:call)
32
+ unless type_id.respond_to?(:call)
33
+ raise(ArgumentError,
34
+ "Type must implement #call(val): #{type_id}")
35
+ end
36
+
32
37
  type_id
33
38
  end
34
39
 
@@ -58,7 +63,7 @@ module Anyway
58
63
  obj.accept(:float, &:to_f)
59
64
 
60
65
  obj.accept(:date) do
61
- require "date" unless defined?(::Date)
66
+ require 'date' unless defined?(::Date)
62
67
 
63
68
  next _1 if _1.is_a?(::Date)
64
69
 
@@ -68,7 +73,7 @@ module Anyway
68
73
  end
69
74
 
70
75
  obj.accept(:datetime) do
71
- require "date" unless defined?(::Date)
76
+ require 'date' unless defined?(::Date)
72
77
 
73
78
  next _1 if _1.is_a?(::DateTime)
74
79
 
@@ -78,7 +83,7 @@ module Anyway
78
83
  end
79
84
 
80
85
  obj.accept(:uri) do
81
- require "uri" unless defined?(::URI)
86
+ require 'uri' unless defined?(::URI)
82
87
 
83
88
  next _1 if _1.is_a?(::URI)
84
89
 
@@ -90,9 +95,9 @@ module Anyway
90
95
  end
91
96
  end
92
97
 
93
- unless "".respond_to?(:safe_constantize)
94
- require "anyway/ext/string_constantize"
95
- using Anyway::Ext::StringConstantize
98
+ unless ''.respond_to?(:safe_constantize)
99
+ require 'runger/ext/string_constantize'
100
+ using Runger::Ext::StringConstantize
96
101
  end
97
102
 
98
103
  # TypeCaster is an object responsible for type-casting.
@@ -102,7 +107,7 @@ module Anyway
102
107
  using Ext::DeepDup
103
108
  using Ext::Hash
104
109
 
105
- def initialize(mapping, registry: TypeRegistry.default, fallback: ::Anyway::AutoCast)
110
+ def initialize(mapping, registry: TypeRegistry.default, fallback: ::Runger::AutoCast)
106
111
  @mapping = mapping.deep_dup
107
112
  @registry = registry
108
113
  @fallback = fallback
@@ -115,16 +120,16 @@ module Anyway
115
120
 
116
121
  case caster_config
117
122
  in Hash[array:, type:, **nil]
118
- registry.deserialize(val, type, array: array)
123
+ registry.deserialize(val, type, array:)
119
124
  in Hash[config: subconfig]
120
125
  subconfig = subconfig.safe_constantize if subconfig.is_a?(::String)
121
- raise ArgumentError, "Config is not found: #{subconfig}" unless subconfig
126
+ raise(ArgumentError, "Config is not found: #{subconfig}") unless subconfig
122
127
 
123
128
  subconfig.new(val)
124
129
  in Hash
125
130
  return val unless val.is_a?(Hash)
126
131
 
127
- caster_config.each do |k, v|
132
+ caster_config.each_key do |k|
128
133
  ks = k.to_s
129
134
  next unless val.key?(ks)
130
135
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Anyway
4
- using Anyway::Ext::DeepDup
3
+ module Runger
4
+ using Runger::Ext::DeepDup
5
5
 
6
6
  module Utils
7
7
  def self.deep_merge!(source, other)
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Runger::Utils
4
+ # Cross-platform solution
5
+ # taken from https://stackoverflow.com/a/5471032
6
+ def self.which(cmd)
7
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
8
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
9
+ exts.each do |ext|
10
+ exe = File.join(path, "#{cmd}#{ext}")
11
+ return exe if File.executable?(exe) && !File.directory?(exe)
12
+ end
13
+ end
14
+ nil
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Runger # :nodoc:
4
+ VERSION = '5.0.0'
5
+ end
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "anyway_config"
3
+ require 'runger_config'
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'runger/version'
4
+
5
+ module Runger ; end
6
+ module Runger::Ext ; end
7
+ module Runger::Utils ; end
8
+ module Runger::Tracing ; end
9
+ module Runger::Loaders ; end
10
+ module Runger::Testing ; end
11
+
12
+ require 'runger/ext/deep_dup'
13
+ require 'runger/ext/deep_freeze'
14
+ require 'runger/ext/flatten_names'
15
+ require 'runger/ext/hash'
16
+
17
+ require 'runger/utils/deep_merge'
18
+ require 'runger/utils/which'
19
+
20
+ require 'runger/auto_cast'
21
+ require 'runger/config'
22
+ require 'runger/env'
23
+ require 'runger/loaders'
24
+ require 'runger/rbs'
25
+ require 'runger/settings'
26
+ require 'runger/tracing'
27
+ require 'runger/type_casting'
28
+
29
+ module Runger # :nodoc:
30
+ class << self
31
+ def env
32
+ @env ||= ::Runger::Env.new
33
+ end
34
+
35
+ def loaders
36
+ @loaders ||= ::Runger::Loaders::Registry.new
37
+ end
38
+ end
39
+
40
+ # Configure default loaders
41
+ loaders.append(:yml, Loaders::YAML)
42
+ loaders.append(:ejson, Loaders::EJSON) if Utils.which('ejson')
43
+ loaders.append(:env, Loaders::Env)
44
+
45
+ if ENV.key?('DOPPLER_TOKEN') && ENV['RUNGER_CONFIG_DISABLE_DOPPLER'] != 'true'
46
+ loaders.append(:doppler, Loaders::Doppler)
47
+ end
48
+ end
49
+
50
+ if defined?(Rails::VERSION)
51
+ require 'runger/rails'
52
+ else
53
+ require 'runger/rails/autoload'
54
+ end
55
+
56
+ require 'runger/testing' if ENV['RACK_ENV'] == 'test' || ENV['RAILS_ENV'] == 'test'
@@ -1,4 +1,4 @@
1
- module Anyway
1
+ module Runger
2
2
  def self.env: -> Env
3
3
  def self.loaders: -> Loaders::Registry
4
4
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runger_config
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
- - Vladimir Dementyev
7
+ - David Runger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-20 00:00:00.000000000 Z
11
+ date: 2023-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 1.1.3
41
+ - !ruby/object:Gem::Dependency
42
+ name: ejson
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 1.3.1
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 1.3.1
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rake
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -80,25 +94,11 @@ dependencies:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
96
  version: '3.18'
83
- - !ruby/object:Gem::Dependency
84
- name: ejson
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: 1.3.1
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: 1.3.1
97
97
  description: "\n Configuration DSL for Ruby libraries and applications.\n Allows
98
98
  you to easily follow the twelve-factor application principles (https://12factor.net/config).\n
99
99
  \ "
100
100
  email:
101
- - dementiev.vm@gmail.com
101
+ - davidjrunger@gmail.com
102
102
  executables: []
103
103
  extensions: []
104
104
  extra_rdoc_files: []
@@ -106,55 +106,55 @@ files:
106
106
  - CHANGELOG.md
107
107
  - LICENSE.txt
108
108
  - README.md
109
- - lib/anyway.rb
110
- - lib/anyway/auto_cast.rb
111
- - lib/anyway/config.rb
112
- - lib/anyway/dynamic_config.rb
113
- - lib/anyway/ejson_parser.rb
114
- - lib/anyway/env.rb
115
- - lib/anyway/ext/deep_dup.rb
116
- - lib/anyway/ext/deep_freeze.rb
117
- - lib/anyway/ext/flatten_names.rb
118
- - lib/anyway/ext/hash.rb
119
- - lib/anyway/ext/string_constantize.rb
120
- - lib/anyway/loaders.rb
121
- - lib/anyway/loaders/base.rb
122
- - lib/anyway/loaders/doppler.rb
123
- - lib/anyway/loaders/ejson.rb
124
- - lib/anyway/loaders/env.rb
125
- - lib/anyway/loaders/yaml.rb
126
- - lib/anyway/option_parser_builder.rb
127
- - lib/anyway/optparse_config.rb
128
- - lib/anyway/rails.rb
129
- - lib/anyway/rails/autoload.rb
130
- - lib/anyway/rails/config.rb
131
- - lib/anyway/rails/loaders.rb
132
- - lib/anyway/rails/loaders/credentials.rb
133
- - lib/anyway/rails/loaders/secrets.rb
134
- - lib/anyway/rails/loaders/yaml.rb
135
- - lib/anyway/rails/settings.rb
136
- - lib/anyway/railtie.rb
137
- - lib/anyway/rbs.rb
138
- - lib/anyway/settings.rb
139
- - lib/anyway/testing.rb
140
- - lib/anyway/testing/helpers.rb
141
- - lib/anyway/tracing.rb
142
- - lib/anyway/type_casting.rb
143
- - lib/anyway/utils/deep_merge.rb
144
- - lib/anyway/utils/which.rb
145
- - lib/anyway/version.rb
146
- - lib/anyway_config.rb
147
- - lib/generators/anyway/app_config/USAGE
148
- - lib/generators/anyway/app_config/app_config_generator.rb
149
- - lib/generators/anyway/config/USAGE
150
- - lib/generators/anyway/config/config_generator.rb
151
- - lib/generators/anyway/config/templates/config.rb.tt
152
- - lib/generators/anyway/config/templates/config.yml.tt
153
- - lib/generators/anyway/install/USAGE
154
- - lib/generators/anyway/install/install_generator.rb
155
- - lib/generators/anyway/install/templates/application_config.rb.tt
156
- - sig/anyway_config.rbs
109
+ - lib/generators/runger/app_config/USAGE
110
+ - lib/generators/runger/app_config/app_config_generator.rb
111
+ - lib/generators/runger/config/USAGE
112
+ - lib/generators/runger/config/config_generator.rb
113
+ - lib/generators/runger/config/templates/config.rb.tt
114
+ - lib/generators/runger/config/templates/config.yml.tt
115
+ - lib/generators/runger/install/USAGE
116
+ - lib/generators/runger/install/install_generator.rb
117
+ - lib/generators/runger/install/templates/application_config.rb.tt
118
+ - lib/runger.rb
119
+ - lib/runger/auto_cast.rb
120
+ - lib/runger/config.rb
121
+ - lib/runger/dynamic_config.rb
122
+ - lib/runger/ejson_parser.rb
123
+ - lib/runger/env.rb
124
+ - lib/runger/ext/deep_dup.rb
125
+ - lib/runger/ext/deep_freeze.rb
126
+ - lib/runger/ext/flatten_names.rb
127
+ - lib/runger/ext/hash.rb
128
+ - lib/runger/ext/string_constantize.rb
129
+ - lib/runger/loaders.rb
130
+ - lib/runger/loaders/base.rb
131
+ - lib/runger/loaders/doppler.rb
132
+ - lib/runger/loaders/ejson.rb
133
+ - lib/runger/loaders/env.rb
134
+ - lib/runger/loaders/yaml.rb
135
+ - lib/runger/option_parser_builder.rb
136
+ - lib/runger/optparse_config.rb
137
+ - lib/runger/rails.rb
138
+ - lib/runger/rails/autoload.rb
139
+ - lib/runger/rails/config.rb
140
+ - lib/runger/rails/loaders.rb
141
+ - lib/runger/rails/loaders/credentials.rb
142
+ - lib/runger/rails/loaders/secrets.rb
143
+ - lib/runger/rails/loaders/yaml.rb
144
+ - lib/runger/rails/settings.rb
145
+ - lib/runger/railtie.rb
146
+ - lib/runger/rbs.rb
147
+ - lib/runger/settings.rb
148
+ - lib/runger/testing.rb
149
+ - lib/runger/testing/helpers.rb
150
+ - lib/runger/tracing.rb
151
+ - lib/runger/type_casting.rb
152
+ - lib/runger/utils/deep_merge.rb
153
+ - lib/runger/utils/which.rb
154
+ - lib/runger/version.rb
155
+ - lib/runger_config.rb
157
156
  - sig/manifest.yml
157
+ - sig/runger_config.rbs
158
158
  homepage: http://github.com/davidrunger/runger_config
159
159
  licenses:
160
160
  - MIT
@@ -174,14 +174,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
174
174
  requirements:
175
175
  - - ">="
176
176
  - !ruby/object:Gem::Version
177
- version: 3.2.2
177
+ version: 3.3.0
178
178
  required_rubygems_version: !ruby/object:Gem::Requirement
179
179
  requirements:
180
180
  - - ">="
181
181
  - !ruby/object:Gem::Version
182
182
  version: '0'
183
183
  requirements: []
184
- rubygems_version: 3.4.22
184
+ rubygems_version: 3.5.3
185
185
  signing_key:
186
186
  specification_version: 4
187
187
  summary: Configuration DSL for Ruby libraries and applications
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Anyway
4
- # Adds ability to generate anonymous (class-less) config dynamicly
5
- # (like Rails.application.config_for but using more data sources).
6
- module DynamicConfig
7
- module ClassMethods
8
- # Load config as Hash by any name
9
- #
10
- # Example:
11
- #
12
- # my_config = Anyway::Config.for(:my_app)
13
- # # will load data from config/my_app.yml, secrets.my_app, ENV["MY_APP_*"]
14
- #
15
- def for(name, auto_cast: true, **options)
16
- config = allocate
17
- options[:env_prefix] ||= name.to_s.upcase
18
- options[:config_path] ||= config.resolve_config_path(name, options[:env_prefix])
19
-
20
- raw_config = config.load_from_sources(new_empty_config, name:, **options)
21
- return raw_config unless auto_cast
22
-
23
- AutoCast.call(raw_config)
24
- end
25
- end
26
-
27
- def self.included(base)
28
- base.extend ClassMethods
29
- end
30
- end
31
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "open3"
4
- require "anyway/ext/hash"
5
-
6
- using Anyway::Ext::Hash
7
-
8
- module Anyway
9
- class EJSONParser
10
- attr_reader :bin_path
11
-
12
- def initialize(bin_path = "ejson")
13
- @bin_path = bin_path
14
- end
15
-
16
- def call(file_path)
17
- return unless File.exist?(file_path)
18
-
19
- raw_content = nil
20
-
21
- stdout, stderr, status = Open3.capture3("#{bin_path} decrypt #{file_path}")
22
-
23
- if status.success?
24
- raw_content = JSON.parse(stdout.chomp)
25
- else
26
- Kernel.warn "Failed to decrypt #{file_path}: #{stderr}"
27
- end
28
-
29
- return unless raw_content
30
-
31
- raw_content.deep_transform_keys do |key|
32
- if key[0] == "_"
33
- key[1..]
34
- else
35
- key
36
- end
37
- end
38
- end
39
- end
40
- end
data/lib/anyway/env.rb DELETED
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Anyway
4
- # Parses environment variables and provides
5
- # method-like access
6
- class Env
7
- using Anyway::Ext::DeepDup
8
- using Anyway::Ext::Hash
9
-
10
- class << self
11
- def from_hash(hash, prefix: nil, memo: {})
12
- hash.each do |key, value|
13
- prefix_with_key = (prefix && !prefix.empty?) ? "#{prefix}_#{key.to_s.upcase}" : key.to_s.upcase
14
-
15
- if value.is_a?(Hash)
16
- from_hash(value, prefix: "#{prefix_with_key}_", memo:)
17
- else
18
- memo[prefix_with_key] = value.to_s
19
- end
20
- end
21
-
22
- memo
23
- end
24
- end
25
-
26
- include Tracing
27
-
28
- attr_reader :data, :traces, :type_cast, :env_container
29
-
30
- def initialize(type_cast: AutoCast, env_container: ENV)
31
- @type_cast = type_cast
32
- @data = {}
33
- @traces = {}
34
- @env_container = env_container
35
- end
36
-
37
- def clear
38
- data.clear
39
- traces.clear
40
- end
41
-
42
- def fetch(prefix)
43
- return data[prefix].deep_dup if data.key?(prefix)
44
-
45
- Tracing.capture do
46
- data[prefix] = parse_env(prefix)
47
- end.then do |trace|
48
- traces[prefix] = trace
49
- end
50
-
51
- data[prefix].deep_dup
52
- end
53
-
54
- def fetch_with_trace(prefix)
55
- [fetch(prefix), traces[prefix]]
56
- end
57
-
58
- private
59
-
60
- def parse_env(prefix)
61
- match_prefix = prefix.empty? ? prefix : "#{prefix}_"
62
- env_container.each_pair.with_object({}) do |(key, val), data|
63
- next unless key.start_with?(match_prefix)
64
-
65
- path = key.sub(/^#{match_prefix}/, "").downcase
66
-
67
- paths = path.split("__")
68
- trace!(:env, *paths, key:) { data.bury(type_cast.call(val), *paths) }
69
- end
70
- end
71
- end
72
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Anyway
4
- module Ext
5
- # Extend Object through refinements
6
- module DeepDup
7
- refine ::Hash do
8
- # Based on ActiveSupport http://api.rubyonrails.org/classes/Hash.html#method-i-deep_dup
9
- def deep_dup
10
- each_with_object(dup) do |(key, value), hash|
11
- hash[key] = if value.is_a?(::Hash) || value.is_a?(::Array)
12
- value.deep_dup
13
- else
14
- value
15
- end
16
- end
17
- end
18
- end
19
-
20
- refine ::Array do
21
- # From ActiveSupport http://api.rubyonrails.org/classes/Array.html#method-i-deep_dup
22
- def deep_dup
23
- map do |value|
24
- if value.is_a?(::Hash) || value.is_a?(::Array)
25
- value.deep_dup
26
- else
27
- value
28
- end
29
- end
30
- end
31
- end
32
-
33
- refine ::Object do
34
- def deep_dup
35
- dup
36
- end
37
- end
38
-
39
- refine ::Module do
40
- def deep_dup
41
- self
42
- end
43
- end
44
-
45
- using self
46
- end
47
- end
48
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Anyway
4
- module Ext
5
- # Add #deep_freeze to hashes and arrays
6
- module DeepFreeze
7
- refine ::Hash do
8
- def deep_freeze
9
- freeze
10
- each_value do |value|
11
- value.deep_freeze if value.is_a?(::Hash) || value.is_a?(::Array)
12
- end
13
- end
14
- end
15
-
16
- refine ::Array do
17
- def deep_freeze
18
- freeze
19
- each do |value|
20
- value.deep_freeze if value.is_a?(::Hash) || value.is_a?(::Array)
21
- end
22
- end
23
- end
24
-
25
- begin
26
- require "active_support/core_ext/hash/indifferent_access"
27
- rescue LoadError
28
- end
29
-
30
- if defined?(::ActiveSupport::HashWithIndifferentAccess)
31
- refine ::ActiveSupport::HashWithIndifferentAccess do
32
- def deep_freeze
33
- freeze
34
- each_value do |value|
35
- value.deep_freeze if value.is_a?(::Hash) || value.is_a?(::Array)
36
- end
37
- end
38
- end
39
- end
40
-
41
- using self
42
- end
43
- end
44
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Anyway
4
- module Ext
5
- # Convert Hash with mixed array and hash values to an
6
- # array of paths.
7
- module FlattenNames
8
- refine ::Array do
9
- def flatten_names(prefix, buf)
10
- if empty?
11
- buf << :"#{prefix}"
12
- return buf
13
- end
14
-
15
- each_with_object(buf) do |name, acc|
16
- if name.is_a?(::Symbol)
17
- acc << :"#{prefix}.#{name}"
18
- else
19
- name.flatten_names(prefix, acc)
20
- end
21
- end
22
- end
23
- end
24
-
25
- refine ::Hash do
26
- def flatten_names(prefix = nil, buf = [])
27
- each_with_object(buf) do |(k, v), acc|
28
- parent = prefix ? "#{prefix}.#{k}" : k
29
- v.flatten_names(parent, acc)
30
- end
31
- end
32
- end
33
-
34
- using self
35
- end
36
- end
37
- end