# frozen_string_literal: true require "active_support/core_ext/hash/indifferent_access" module Anyway module Rails # Enhance config to be more Railsy-like: # – accept hashes with indeferent access # - load data from secrets # - recognize Rails env when loading from YML module Config module ClassMethods # Make defaults to be a Hash with indifferent access def defaults return @defaults if instance_variable_defined?(:@defaults) @defaults = super.with_indifferent_access end end def load_from_sources(**options) base_config = {}.with_indifferent_access each_source(options) do |config| base_config.deep_merge!(config) if config end base_config end def each_source(options) yield load_from_file(options) yield load_from_secrets(options) yield load_from_credentials(options) yield load_from_env(options) end def load_from_file(name:, config_path:, env_prefix:, **_options) file_config = load_from_yml(config_path)[::Rails.env] || {} if Anyway::Settings.use_local_files local_config_path = config_path.sub(/\.yml/, ".local.yml") file_config.deep_merge!(load_from_yml(local_config_path) || {}) end file_config end def load_from_secrets(name:, **_options) return unless ::Rails.application.respond_to?(:secrets) ::Rails.application.secrets.public_send(name) end def load_from_credentials(name:, **_options) # do not load from credentials if we're in the context # of the `credentials:edit` command return if defined?(::Rails::Command::CredentialsCommand) return unless ::Rails.application.respond_to?(:credentials) # Create a new hash cause credentials are mutable! creds_config = {} creds_config.deep_merge!(::Rails.application.credentials.public_send(name) || {}) creds_config.deep_merge!(load_from_local_credentials(name: name) || {}) if Anyway::Settings.use_local_files creds_config end def load_from_local_credentials(name:) local_creds_path = ::Rails.root.join("config/credentials/local.yml.enc").to_s return unless File.file?(local_creds_path) creds = ::Rails.application.encrypted( local_creds_path, key_path: ::Rails.root.join("config/credentials/local.key") ) creds.public_send(name) end def default_config_path(name) ::Rails.root.join("config", "#{name}.yml") end end end end Anyway::Config.prepend Anyway::Rails::Config Anyway::Config.singleton_class.prepend Anyway::Rails::Config::ClassMethods