diff --git a/config.gemspec b/config.gemspec index d59ced0c..104548af 100644 --- a/config.gemspec +++ b/config.gemspec @@ -37,9 +37,15 @@ Donate: \e[34mhttps://opencollective.com/rubyconfig/donate\e[0m\n" # Default RSpec run will test against latest Rails app unless ENV['APPRAISAL_INITIALIZED'] || ENV['GITHUB_ACTIONS'] - gems_to_install = /gem "(.*?)", "(.*?)"(?!, platform: (?!\[:ruby\]))/ - File.read(Dir['gemfiles/rails*.gemfile'].sort.last).scan(gems_to_install) do |name, version| - s.add_development_dependency name, version + gems_to_install = /gem "(.*?)", "(.*?)"(, platform: \:(.*))?/ + File.read(Dir['gemfiles/rails*.gemfile'].sort.last).scan(gems_to_install) do |name, version, _, platform| + if platform.nil? + s.add_development_dependency name, version + else + if platform.to_s == RUBY_ENGINE + s.add_development_dependency name, version + end + end end end diff --git a/lib/config.rb b/lib/config.rb index 471b113d..24b24918 100644 --- a/lib/config.rb +++ b/lib/config.rb @@ -23,7 +23,8 @@ module Config merge_nil_values: true, overwrite_arrays: true, merge_hash_arrays: false, - validation_contract: nil + validation_contract: nil, + environment: nil ) def self.setup diff --git a/lib/config/integrations/rails/railtie.rb b/lib/config/integrations/rails/railtie.rb index 460fa5f3..6748c116 100644 --- a/lib/config/integrations/rails/railtie.rb +++ b/lib/config/integrations/rails/railtie.rb @@ -9,7 +9,7 @@ def preload # Parse the settings before any of the initializers Config.load_and_set_settings( - Config.setting_files(::Rails.root.join('config'), ::Rails.env) + Config.setting_files(::Rails.root.join('config'), Config.environment.nil? ? ::Rails.env : Config.environment.to_sym) ) end diff --git a/lib/config/options.rb b/lib/config/options.rb index b139a26c..4810ed00 100644 --- a/lib/config/options.rb +++ b/lib/config/options.rb @@ -38,13 +38,13 @@ def reload_env! ENV.each do |variable, value| separator = Config.env_separator - prefix = (Config.env_prefix || Config.const_name).to_s.split(separator) + prefix = (Config.env_prefix || Config.const_name).to_s + + new_keys = variable.to_s.split(separator) + prefix_array = prefix.split(separator) + next if new_keys.shift(prefix_array.size) != prefix_array - keys = variable.to_s.split(separator) - - next if keys.shift(prefix.size) != prefix - - keys.map! { |key| + new_keys.map! { |key| case Config.env_converter when :downcase then key.downcase.to_sym @@ -55,11 +55,17 @@ def reload_env! end } - leaf = keys[0...-1].inject(hash) { |h, key| + # split the environment variable name based on the keys we have in our config + transformed_keys = __lookup_keys(new_keys, separator) + if transformed_keys.length > 0 + new_keys = transformed_keys + end + + leaf = new_keys[0...-1].inject(hash) { |h, key| h[key] ||= {} } - leaf[keys.last] = Config.env_parse_values ? __value(value) : value + leaf[new_keys.last] = Config.env_parse_values ? __value(value) : value end merge!(hash) @@ -226,5 +232,48 @@ def __value(v) Integer(v) rescue Float(v) rescue v end end + + def __lookup_keys(source_keys, separator, found_keys = []) + # if we've got no source keys, we must have got to the end of our search + return found_keys if source_keys.nil? || source_keys.length == 0 + + # To allow us to prefix keys with the same seperation character that exists in the config key, we need to search for the keys + lookup_key = nil + lookup_config = marshal_dump + # if we've passed in some found keys, we want to get the config keys from the appropriate level in our config + found_keys.each do |k| + lookup_config = lookup_config[k] + end + + # we can find a config entry for the keys that have been found, so return what we have so they can be created + return found_keys if lookup_config.nil? + + config_keys = lookup_config.keys + + search_keys = source_keys.dup + (0..(search_keys.length - 1)).each do + lookup_key = config_keys.find{|k| k.to_sym == search_keys.join(separator).to_sym } + break if !lookup_key.nil? + + search_keys.pop + end + + found_keys ||= [] + if !lookup_key.nil? + # we've found a key in our config that matches our env key, store this, and look inside this for the rest + found_keys << lookup_key + # get the new search keys + # do this by taking the original environment variable keys, and removing the key we've found in our config + env_key = source_keys.join(separator) + # replace "our_key_" first, then "our_key" + # leaving us with the remaining keys to search + env_key = env_key.gsub(lookup_key.to_s + separator, "").gsub(lookup_key.to_s, "") + search_keys = env_key.split(separator) + + # call the same function again to get the next config key + found_keys = __lookup_keys(search_keys, separator, found_keys) + end + found_keys + end end end diff --git a/lib/config/version.rb b/lib/config/version.rb index c011340c..13c361d0 100644 --- a/lib/config/version.rb +++ b/lib/config/version.rb @@ -1,3 +1,3 @@ module Config - VERSION = '2.2.1'.freeze + VERSION = '2.3.0'.freeze end diff --git a/lib/generators/config/templates/config.rb b/lib/generators/config/templates/config.rb index 7c82c5f8..426d3805 100644 --- a/lib/generators/config/templates/config.rb +++ b/lib/generators/config/templates/config.rb @@ -15,6 +15,10 @@ # # config.overwrite_arrays = true + # Use a different method of determining the current environment + # defaults to ::Rails.env + # config.environment = ENV.fetch('ENVIRONMENT', :development) + # Load environment variables from the `ENV` object and override any settings defined in files. # # config.use_env = false diff --git a/spec/config_env_spec.rb b/spec/config_env_spec.rb index 0906eec8..ad7626fd 100644 --- a/spec/config_env_spec.rb +++ b/spec/config_env_spec.rb @@ -178,6 +178,13 @@ expect(config.key).to eq(nil) end + + it 'should recognise a key name if it contains a character which is the same as the custom separator' do + ENV['MY_CONFIG_QUERY_SERVICE_API_KEY'] = "value" + expect(config.query_service.api_key).to eq('value') + expect(config.query).to be_nil + expect(config['query_service_api_key']).to be_nil + end end context 'and variable names conversion' do diff --git a/spec/fixtures/settings.yml b/spec/fixtures/settings.yml index 2d04b728..67f14718 100644 --- a/spec/fixtures/settings.yml +++ b/spec/fixtures/settings.yml @@ -18,4 +18,7 @@ photo_sizes: avatar: [60, 60] root: yahoo.com: 2 - 'google.com': 3 + "google.com": 3 + +query_service: + api_key: "theapikey" diff --git a/spec/options_spec.rb b/spec/options_spec.rb index 0a94061c..18d0e5d7 100644 --- a/spec/options_spec.rb +++ b/spec/options_spec.rb @@ -218,7 +218,7 @@ expect(config.array[1].b).to eq("two") end end - + end end