anyway_config 2.4.0 → 2.4.2

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: 44a860f50ae339b170da1a4ea99a7c6125b8ddcf2e25269c7341150bb8b8cf1f
4
- data.tar.gz: f39c3ff413a1f334ad85a8f3eb0dfabca16dfc0c18c7f8719236607a777f947d
3
+ metadata.gz: 822e17fb52f85c3f3066322083d1d2d30265bb58fbce6f50e88590ebea140ba4
4
+ data.tar.gz: c3cfd97af9fe5de290b8a378517b3f11a7a020e550929c7e3765e34411988246
5
5
  SHA512:
6
- metadata.gz: 6b903f239c176e8c031fdea2d81f9d6d46d0657c2b5525f7e36fed495ab2410dc017bbe676fdc8c633d6b303c619e5caeb109d8c172d172720bfb3417746c612
7
- data.tar.gz: 7bbb6db11016ce9c9473009c49aa676e3121ab921a2493ceb6d8e0e270cf75369935678bb1a2e5f69ebe387be1d5a44d159df819dcfab4a591aa67bab2e757fa
6
+ metadata.gz: 8fabe569de72f9a65d22a4a69a8b2b4cad0d97ef2dc62f245133352b142402ec2eb2b6f9492c713aceaac6518ca1453e1527855e6eaf5b4adb12ec0b2c2c1b50
7
+ data.tar.gz: 2fe2eef92329925f2626a501bd34c0081170e507f30214b9199710e509f208b0f3df7bfda163b304304e1fda58c8b4f757f527e748afd21708514877e4a1765c
data/CHANGELOG.md CHANGED
@@ -2,9 +2,21 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 2.4.2 (2023-06-07)
6
+
7
+ - Use ANYWAY_ENV as the current environment if defined. ([@palkan][])
8
+
9
+ It can be used to specify environment for configs independently of Rails environment.
10
+
11
+ ## 2.4.1 (2023-05-04)
12
+
13
+ - Add custom namespace support via `ejson_namespace` ([@bessey])
14
+
15
+ - Add arbitrary custom loader options support via `loader_options` ([@bessey])
16
+
5
17
  ## 2.4.0 (2023-04-04)
6
18
 
7
- - Add `Confi#as_env` to convert config into a ENV-like HASH. ([@tagirahmad][])
19
+ - Added `Confi#as_env` to convert config into a ENV-like Hash. ([@tagirahmad][])
8
20
 
9
21
  - Added experimental support for sub-configs via coercion. ([@palkan][])
10
22
 
@@ -517,3 +529,4 @@ No we're dependency-free!
517
529
  [@prog-supdex]: https://github.com/prog-supdex
518
530
  [@inner-whisper]: https://github.com/inner-whisper
519
531
  [@tagirahmad]: https://github.com/tagirahmad
532
+ [@bessey]: https://github.com/bessey
data/README.md CHANGED
@@ -367,6 +367,8 @@ development:
367
367
  port: 3000
368
368
  ```
369
369
 
370
+ **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"`.
371
+
370
372
  ### Multi-env configuration
371
373
 
372
374
  _⚡️ 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`._
@@ -544,6 +546,8 @@ Would you like to generate a heroku.yml file? (Y/n) n
544
546
  You can also specify the `--app` option to put the newly created class into `app/configs` folder.
545
547
  Alternatively, you can call `rails g anyway:app_config name param1 param2 ...`.
546
548
 
549
+ **NOTE:** The generated `ApplicationConfig` class uses a singleton pattern along with `delegate_missing_to` to re-use the same instance across the application. However, the delegation can lead to unexpected behaviour and break Anyway Config internals if you have attributes named as `Anyway::Config` class methods. See [#120](https://github.com/palkan/anyway_config/issues/120).
550
+
547
551
  ## Using with Ruby
548
552
 
549
553
  The default data loading mechanism for non-Rails applications is the following (ordered by priority from low to high):
@@ -557,6 +561,8 @@ If you want to enable this feature you must specify `Anyway::Settings.current_en
557
561
  Anyway::Settings.current_environment = "development"
558
562
  ```
559
563
 
564
+ You can also specify the `ANYWAY_ENV=development` environment variable to set the current environment for configuration.
565
+
560
566
  YAML files should be in this format:
561
567
 
562
568
  ```yml
@@ -790,6 +796,18 @@ To debug any problems with loading configurations from `.ejson` files you can di
790
796
  ejson decrypt config/secrets.ejson
791
797
  ```
792
798
 
799
+ You can customize the JSON namespace under which a loader searches for configuration via `loader_options`:
800
+
801
+ ```ruby
802
+ class MyConfig < Anyway::Config
803
+ # To look under the key "foo" instead of the default key of "my"
804
+ loader_options ejson_namespace: "foo"
805
+
806
+ # Or to disable namespacing entirely, and instead search in the root object
807
+ loader_options ejson_namespace: false
808
+ end
809
+ ```
810
+
793
811
  ### Custom loaders
794
812
 
795
813
  You can provide your own data loaders or change the existing ones using the Loaders API (which is very similar to Rack middleware builder):
@@ -810,7 +828,8 @@ def call(
810
828
  name:, # config name
811
829
  env_prefix:, # prefix for env vars if any
812
830
  config_path:, # path to YML config
813
- local: # true|false, whether to load local configuration
831
+ local:, # true|false, whether to load local configuration
832
+ **options # custom options can be passed via Anyway::Config.loader_options example: "custom", option: "blah"
814
833
  )
815
834
  #=> must return Hash with configuration data
816
835
  end
@@ -199,6 +199,18 @@ module Anyway # :nodoc:
199
199
  end
200
200
  end
201
201
 
202
+ def loader_options(val = nil)
203
+ return (@loader_options = val) unless val.nil?
204
+
205
+ return @loader_options if instance_variable_defined?(:@loader_options)
206
+
207
+ @loader_options = if superclass < Anyway::Config
208
+ superclass.loader_options
209
+ else
210
+ {}
211
+ end
212
+ end
213
+
202
214
  def new_empty_config() ; {}; end
203
215
 
204
216
  def coerce_types(mapping)
@@ -343,7 +355,13 @@ module Anyway # :nodoc:
343
355
 
344
356
  config_path = resolve_config_path(config_name, env_prefix)
345
357
 
346
- load_from_sources(base_config, name: config_name, env_prefix: env_prefix, config_path: config_path)
358
+ load_from_sources(
359
+ base_config,
360
+ name: config_name,
361
+ env_prefix: env_prefix,
362
+ config_path: config_path,
363
+ **self.class.loader_options
364
+ )
347
365
 
348
366
  if overrides
349
367
  Tracing.trace!(:load) { overrides }
@@ -96,8 +96,11 @@ module Anyway
96
96
  end
97
97
  end
98
98
 
99
+ # By default, use ANYWAY_ENV
100
+ self.current_environment = ENV["ANYWAY_ENV"]
101
+
99
102
  # By default, use local files only in development (that's the purpose if the local files)
100
- self.use_local_files = (ENV["RACK_ENV"] == "development" || ENV["RAILS_ENV"] == "development")
103
+ self.use_local_files = (ENV["ANYWAY_ENV"] == "development" || ENV["RACK_ENV"] == "development" || ENV["RAILS_ENV"] == "development")
101
104
 
102
105
  # By default, consider configs are stored in the ./config folder
103
106
  self.default_config_path = ->(name) { "./config/#{name}.yml" }
@@ -199,6 +199,18 @@ module Anyway # :nodoc:
199
199
  end
200
200
  end
201
201
 
202
+ def loader_options(val = nil)
203
+ return (@loader_options = val) unless val.nil?
204
+
205
+ return @loader_options if instance_variable_defined?(:@loader_options)
206
+
207
+ @loader_options = if superclass < Anyway::Config
208
+ superclass.loader_options
209
+ else
210
+ {}
211
+ end
212
+ end
213
+
202
214
  def new_empty_config() ; {}; end
203
215
 
204
216
  def coerce_types(mapping)
@@ -343,7 +355,13 @@ module Anyway # :nodoc:
343
355
 
344
356
  config_path = resolve_config_path(config_name, env_prefix)
345
357
 
346
- load_from_sources(base_config, name: config_name, env_prefix: env_prefix, config_path: config_path)
358
+ load_from_sources(
359
+ base_config,
360
+ name: config_name,
361
+ env_prefix: env_prefix,
362
+ config_path: config_path,
363
+ **self.class.loader_options
364
+ )
347
365
 
348
366
  if overrides
349
367
  Tracing.trace!(:load) { overrides }
@@ -199,6 +199,18 @@ module Anyway # :nodoc:
199
199
  end
200
200
  end
201
201
 
202
+ def loader_options(val = nil)
203
+ return (@loader_options = val) unless val.nil?
204
+
205
+ return @loader_options if instance_variable_defined?(:@loader_options)
206
+
207
+ @loader_options = if superclass < Anyway::Config
208
+ superclass.loader_options
209
+ else
210
+ {}
211
+ end
212
+ end
213
+
202
214
  def new_empty_config() = {}
203
215
 
204
216
  def coerce_types(mapping)
@@ -343,7 +355,13 @@ module Anyway # :nodoc:
343
355
 
344
356
  config_path = resolve_config_path(config_name, env_prefix)
345
357
 
346
- load_from_sources(base_config, name: config_name, env_prefix: env_prefix, config_path: config_path)
358
+ load_from_sources(
359
+ base_config,
360
+ name: config_name,
361
+ env_prefix: env_prefix,
362
+ config_path: config_path,
363
+ **self.class.loader_options
364
+ )
347
365
 
348
366
  if overrides
349
367
  Tracing.trace!(:load) { overrides }
data/lib/anyway/config.rb CHANGED
@@ -199,6 +199,18 @@ module Anyway # :nodoc:
199
199
  end
200
200
  end
201
201
 
202
+ def loader_options(val = nil)
203
+ return (@loader_options = val) unless val.nil?
204
+
205
+ return @loader_options if instance_variable_defined?(:@loader_options)
206
+
207
+ @loader_options = if superclass < Anyway::Config
208
+ superclass.loader_options
209
+ else
210
+ {}
211
+ end
212
+ end
213
+
202
214
  def new_empty_config() = {}
203
215
 
204
216
  def coerce_types(mapping)
@@ -343,7 +355,13 @@ module Anyway # :nodoc:
343
355
 
344
356
  config_path = resolve_config_path(config_name, env_prefix)
345
357
 
346
- load_from_sources(base_config, name: config_name, env_prefix:, config_path:)
358
+ load_from_sources(
359
+ base_config,
360
+ name: config_name,
361
+ env_prefix:,
362
+ config_path:,
363
+ **self.class.loader_options
364
+ )
347
365
 
348
366
  if overrides
349
367
  Tracing.trace!(:load) { overrides }
@@ -11,7 +11,7 @@ module Anyway
11
11
 
12
12
  self.bin_path = "ejson"
13
13
 
14
- def call(name:, ejson_parser: Anyway::EJSONParser.new(EJSON.bin_path), **_options)
14
+ def call(name:, ejson_namespace: name, ejson_parser: Anyway::EJSONParser.new(EJSON.bin_path), **_options)
15
15
  configs = []
16
16
 
17
17
  rel_config_paths.each do |rel_config_path|
@@ -23,7 +23,11 @@ module Anyway
23
23
 
24
24
  next unless secrets_hash
25
25
 
26
- config_hash = secrets_hash[name]
26
+ config_hash = if ejson_namespace
27
+ secrets_hash[ejson_namespace]
28
+ else
29
+ secrets_hash.except("_public_key")
30
+ end
27
31
 
28
32
  next unless config_hash.is_a?(Hash)
29
33
 
@@ -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,14 +50,23 @@ 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
61
- ::Rails.env.to_s
69
+ @current_environment || ::Rails.env.to_s
62
70
  end
63
71
 
64
72
  def app_root
@@ -68,6 +76,7 @@ module Anyway
68
76
 
69
77
  self.default_config_path = ->(name) { ::Rails.root.join("config", "#{name}.yml") }
70
78
  self.known_environments = %w[test development production]
79
+ self.use_local_files ||= ::Rails.env.development?
71
80
  # Don't try read defaults when no key defined
72
81
  self.default_environmental_key = nil
73
82
  end
@@ -96,8 +96,11 @@ module Anyway
96
96
  end
97
97
  end
98
98
 
99
+ # By default, use ANYWAY_ENV
100
+ self.current_environment = ENV["ANYWAY_ENV"]
101
+
99
102
  # By default, use local files only in development (that's the purpose if the local files)
100
- self.use_local_files = (ENV["RACK_ENV"] == "development" || ENV["RAILS_ENV"] == "development")
103
+ self.use_local_files = (ENV["ANYWAY_ENV"] == "development" || ENV["RACK_ENV"] == "development" || ENV["RAILS_ENV"] == "development")
101
104
 
102
105
  # By default, consider configs are stored in the ./config folder
103
106
  self.default_config_path = ->(name) { "./config/#{name}.yml" }
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "anyway/testing/helpers"
4
4
 
5
- if defined?(RSpec::Core)
5
+ if defined?(RSpec::Core) && RSpec.respond_to?(:configure)
6
6
  RSpec.configure do |config|
7
7
  config.include(
8
8
  Anyway::Testing::Helpers,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Anyway # :nodoc:
4
- VERSION = "2.4.0"
4
+ VERSION = "2.4.2"
5
5
  end
data/sig/manifest.yml CHANGED
@@ -4,4 +4,3 @@ dependencies:
4
4
  - name: pathname
5
5
  - name: date
6
6
  - name: time
7
- - name: set
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.0
4
+ version: 2.4.2
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-04-05 00:00:00.000000000 Z
11
+ date: 2023-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-next-core