anyway_config 2.3.1 → 2.4.1

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.
@@ -11,9 +11,10 @@ module Anyway
11
11
  class Settings
12
12
  class << self
13
13
  attr_reader :autoload_static_config_path, :autoloader
14
+ attr_writer :autoload_via_zeitwerk
14
15
 
15
- if defined?(::Zeitwerk)
16
- def autoload_static_config_path=(val)
16
+ def autoload_static_config_path=(val)
17
+ if autoload_via_zeitwerk
17
18
  raise "Cannot setup autoloader after application has been initialized" if ::Rails.application.initialized?
18
19
 
19
20
  return unless ::Rails.root.join(val).exist?
@@ -28,18 +29,16 @@ module Anyway
28
29
  # and Rails 7 https://github.com/rails/rails/blob/5462fbd5de1900c1b1ce1c9dc11c1a2d8cdcd809/railties/lib/rails/autoloaders.rb#L15
29
30
  @autoloader = Zeitwerk::Loader.new.tap do |loader|
30
31
  loader.tag = "anyway.config"
31
- loader.inflector = defined?(ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector) ? ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector : ::Rails::Autoloaders::Inflector
32
+
33
+ if defined?(ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector)
34
+ loader.inflector = ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector
35
+ elsif defined?(::Rails::Autoloaders::Inflector)
36
+ loader.inflector = ::Rails::Autoloaders::Inflector
37
+ end
32
38
  loader.push_dir(::Rails.root.join(val))
33
39
  loader.setup
34
40
  end
35
- end
36
-
37
- def cleanup_autoload_paths
38
- return unless autoload_static_config_path
39
- ActiveSupport::Dependencies.autoload_paths.delete(::Rails.root.join(autoload_static_config_path).to_s)
40
- end
41
- else
42
- def autoload_static_config_path=(val)
41
+ else
43
42
  if autoload_static_config_path
44
43
  old_path = ::Rails.root.join(autoload_static_config_path).to_s
45
44
  ActiveSupport::Dependencies.autoload_paths.delete(old_path)
@@ -51,10 +50,19 @@ module Anyway
51
50
  ActiveSupport::Dependencies.autoload_paths << new_path
52
51
  ::Rails.application.config.eager_load_paths << new_path
53
52
  end
53
+ end
54
54
 
55
- def cleanup_autoload_paths
56
- :no_op
57
- end
55
+ def cleanup_autoload_paths
56
+ return unless autoload_via_zeitwerk
57
+
58
+ return unless autoload_static_config_path
59
+ ActiveSupport::Dependencies.autoload_paths.delete(::Rails.root.join(autoload_static_config_path).to_s)
60
+ end
61
+
62
+ def autoload_via_zeitwerk
63
+ return @autoload_via_zeitwerk if instance_variable_defined?(:@autoload_via_zeitwerk)
64
+
65
+ @autoload_via_zeitwerk = defined?(::Zeitwerk)
58
66
  end
59
67
 
60
68
  def current_environment
@@ -80,6 +80,20 @@ module Anyway
80
80
  def default_environmental_key?
81
81
  !default_environmental_key.nil?
82
82
  end
83
+
84
+ def matching_env?(env)
85
+ return true if env.nil? || env.to_s == current_environment
86
+
87
+ if env.is_a?(::Hash)
88
+ envs = env[:except]
89
+ excluded_envs = [envs].flat_map(&:to_s)
90
+ excluded_envs.none?(current_environment)
91
+ elsif env.is_a?(::Array)
92
+ env.flat_map(&:to_s).include?(current_environment)
93
+ else
94
+ false
95
+ end
96
+ end
83
97
  end
84
98
 
85
99
  # By default, use local files only in development (that's the purpose if the local files)
@@ -19,7 +19,7 @@ module Anyway
19
19
  def initialize(type = :trace, value = UNDEF, **source)
20
20
  @type = type
21
21
  @source = source
22
- @value = value == UNDEF ? Hash.new { |h, k| h[k] = Trace.new(:trace) } : value
22
+ @value = (value == UNDEF) ? Hash.new { |h, k| h[k] = Trace.new(:trace) } : value
23
23
  end
24
24
 
25
25
  def dig(...)
@@ -35,7 +35,7 @@ module Anyway
35
35
  end
36
36
 
37
37
  target_trace = path.empty? ? self : value.dig(*path)
38
- target_trace.value[key.to_s] = trace
38
+ target_trace.record_key(key.to_s, trace)
39
39
 
40
40
  val
41
41
  end
@@ -54,6 +54,12 @@ module Anyway
54
54
  hash
55
55
  end
56
56
 
57
+ def record_key(key, key_trace)
58
+ @value = Hash.new { |h, k| h[k] = Trace.new(:trace) } unless value.is_a?(::Hash)
59
+
60
+ value[key] = key_trace
61
+ end
62
+
57
63
  def merge!(another_trace)
58
64
  raise ArgumentError, "You can only merge into a :trace type, and this is :#{type}" unless trace?
59
65
  raise ArgumentError, "You can only merge a :trace type, but trying :#{type}" unless another_trace.trace?
@@ -90,6 +90,11 @@ module Anyway
90
90
  end
91
91
  end
92
92
 
93
+ unless "".respond_to?(:safe_constantize)
94
+ require "anyway/ext/string_constantize"
95
+ using Anyway::Ext::StringConstantize
96
+ end
97
+
93
98
  # TypeCaster is an object responsible for type-casting.
94
99
  # It uses a provided types registry and mapping, and also
95
100
  # accepts a fallback typecaster.
@@ -109,8 +114,13 @@ module Anyway
109
114
  return fallback.coerce(key, val) unless caster_config
110
115
 
111
116
  case caster_config
112
- in array:, type:, **nil
117
+ in Hash[array:, type:, **nil]
113
118
  registry.deserialize(val, type, array: array)
119
+ in Hash[config: subconfig]
120
+ subconfig = subconfig.safe_constantize if subconfig.is_a?(::String)
121
+ raise ArgumentError, "Config is not found: #{subconfig}" unless subconfig
122
+
123
+ subconfig.new(val)
114
124
  in Hash
115
125
  return val unless val.is_a?(Hash)
116
126
 
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anyway
4
+ module Utils
5
+ # Cross-platform solution
6
+ # taken from https://stackoverflow.com/a/5471032
7
+ def self.which(cmd)
8
+ exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""]
9
+ ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
10
+ exts.each do |ext|
11
+ exe = File.join(path, "#{cmd}#{ext}")
12
+ return exe if File.executable?(exe) && !File.directory?(exe)
13
+ end
14
+ end
15
+ nil
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Anyway # :nodoc:
4
- VERSION = "2.3.1"
4
+ VERSION = "2.4.1"
5
5
  end
data/lib/anyway_config.rb CHANGED
@@ -10,8 +10,10 @@ require "anyway/version"
10
10
  require "anyway/ext/deep_dup"
11
11
  require "anyway/ext/deep_freeze"
12
12
  require "anyway/ext/hash"
13
+ require "anyway/ext/flatten_names"
13
14
 
14
15
  require "anyway/utils/deep_merge"
16
+ require "anyway/utils/which"
15
17
 
16
18
  require "anyway/settings"
17
19
  require "anyway/tracing"
@@ -35,7 +37,12 @@ module Anyway # :nodoc:
35
37
 
36
38
  # Configure default loaders
37
39
  loaders.append :yml, Loaders::YAML
40
+ loaders.append :ejson, Loaders::EJSON if Utils.which("ejson")
38
41
  loaders.append :env, Loaders::Env
42
+
43
+ if ENV.key?("DOPPLER_TOKEN") && ENV["ANYWAY_CONFIG_DISABLE_DOPPLER"] != "true"
44
+ loaders.append :doppler, Loaders::Doppler
45
+ end
39
46
  end
40
47
 
41
48
  require "anyway/rails" if defined?(::Rails::VERSION)
@@ -56,11 +56,14 @@ module Anyway
56
56
 
57
57
  type valueType = Symbol | nil
58
58
  type arrayType = {array: bool, type: valueType}
59
+ type configType = {config: Class | String}
59
60
  type hashType = Hash[Symbol, valueType | arrayType | hashType]
60
61
 
61
- type mappingType = valueType | arrayType | hashType
62
+ type mappingType = valueType | arrayType | hashType | configType
62
63
  type envType = String | Symbol | Array[String | Symbol] | {except: String | Symbol | Array[String | Symbol]}
63
64
 
65
+ type requiredType = Array[Symbol | Hash[Symbol, requiredType]]
66
+
64
67
  class Config
65
68
  extend RBSGenerator
66
69
  extend DynamicConfig::ClassMethods
@@ -71,7 +74,7 @@ module Anyway
71
74
  def self.attr_config: (*Symbol args, **untyped) -> void
72
75
  def self.defaults: -> Hash[String, untyped]
73
76
  def self.config_attributes: -> Array[Symbol]?
74
- def self.required: (*Symbol names, ?env: envType) -> void
77
+ def self.required: (*Symbol names, ?env: envType, **requiredType) -> void
75
78
  def self.required_attributes: -> Array[Symbol]
76
79
  def self.on_load: (*Symbol callbacks) ?{ () [self: instance] -> void } -> void
77
80
  def self.config_name: (?(Symbol | String) val) -> String?
@@ -96,10 +99,12 @@ module Anyway
96
99
  def to_source_trace: -> Hash[String, untyped]
97
100
  def inspect: -> String
98
101
  def pretty_print: (untyped q) -> untyped
102
+ def as_env: -> Hash[String, String]
99
103
 
100
104
  private
101
105
  attr_reader values: Hash[untyped, untyped]
102
106
  def raise_validation_error: (String msg) -> void
107
+ def flatten_hash: (Hash[untyped, untyped], String, Hash[String, String]) -> Hash[String, String]
103
108
 
104
109
  class Error < StandardError
105
110
  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.3.1
4
+ version: 2.4.1
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-01-18 00:00:00.000000000 Z
11
+ date: 2023-05-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-next-core
@@ -39,61 +39,75 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: 1.1.3
41
41
  - !ruby/object:Gem::Dependency
42
- name: bundler
42
+ name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '1.15'
47
+ version: '13.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '1.15'
54
+ version: '13.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rake
56
+ name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '13.0'
61
+ version: '3.8'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '13.0'
68
+ version: '3.8'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rspec
70
+ name: ruby-next
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '3.8'
75
+ version: 0.14.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '3.8'
82
+ version: 0.14.0
83
83
  - !ruby/object:Gem::Dependency
84
- name: ruby-next
84
+ name: webmock
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.18'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.18'
97
+ - !ruby/object:Gem::Dependency
98
+ name: ejson
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - ">="
88
102
  - !ruby/object:Gem::Version
89
- version: 0.14.0
103
+ version: 1.3.1
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - ">="
95
109
  - !ruby/object:Gem::Version
96
- version: 0.14.0
110
+ version: 1.3.1
97
111
  description: "\n Configuration DSL for Ruby libraries and applications.\n Allows
98
112
  you to easily follow the twelve-factor application principles (https://12factor.net/config).\n
99
113
  \ "
@@ -106,6 +120,7 @@ files:
106
120
  - CHANGELOG.md
107
121
  - LICENSE.txt
108
122
  - README.md
123
+ - lib/.rbnext/2.6/anyway/ejson_parser.rb
109
124
  - lib/.rbnext/2.7/anyway/auto_cast.rb
110
125
  - lib/.rbnext/2.7/anyway/config.rb
111
126
  - lib/.rbnext/2.7/anyway/loaders/yaml.rb
@@ -127,12 +142,17 @@ files:
127
142
  - lib/anyway/auto_cast.rb
128
143
  - lib/anyway/config.rb
129
144
  - lib/anyway/dynamic_config.rb
145
+ - lib/anyway/ejson_parser.rb
130
146
  - lib/anyway/env.rb
131
147
  - lib/anyway/ext/deep_dup.rb
132
148
  - lib/anyway/ext/deep_freeze.rb
149
+ - lib/anyway/ext/flatten_names.rb
133
150
  - lib/anyway/ext/hash.rb
151
+ - lib/anyway/ext/string_constantize.rb
134
152
  - lib/anyway/loaders.rb
135
153
  - lib/anyway/loaders/base.rb
154
+ - lib/anyway/loaders/doppler.rb
155
+ - lib/anyway/loaders/ejson.rb
136
156
  - lib/anyway/loaders/env.rb
137
157
  - lib/anyway/loaders/yaml.rb
138
158
  - lib/anyway/option_parser_builder.rb
@@ -152,6 +172,7 @@ files:
152
172
  - lib/anyway/tracing.rb
153
173
  - lib/anyway/type_casting.rb
154
174
  - lib/anyway/utils/deep_merge.rb
175
+ - lib/anyway/utils/which.rb
155
176
  - lib/anyway/version.rb
156
177
  - lib/anyway_config.rb
157
178
  - lib/generators/anyway/app_config/USAGE
@@ -174,6 +195,7 @@ metadata:
174
195
  documentation_uri: http://github.com/palkan/anyway_config
175
196
  homepage_uri: http://github.com/palkan/anyway_config
176
197
  source_code_uri: http://github.com/palkan/anyway_config
198
+ funding_uri: https://github.com/sponsors/palkan
177
199
  post_install_message:
178
200
  rdoc_options: []
179
201
  require_paths:
@@ -189,7 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
189
211
  - !ruby/object:Gem::Version
190
212
  version: '0'
191
213
  requirements: []
192
- rubygems_version: 3.3.11
214
+ rubygems_version: 3.4.8
193
215
  signing_key:
194
216
  specification_version: 4
195
217
  summary: Configuration DSL for Ruby libraries and applications