ConfigReader loads environment-specific settings from YAML, merges each
environment with defaults, and exposes the result through method access,
hash access, and dig.
Add the gem to your application's Gemfile:
gem "config_reader"If you use encrypted config files with sekrets_file, add sekrets too:
gem "sekrets", "~> 1.14"defaults is required. config.environment must match one of the top-level
environment keys in the file.
defaults:
site_url: http://localhost:3000
host_name: example.com
mail_from: noreply@example.com
features:
search: true
production:
site_url: http://example.com
test:
features:
search: falseclass MyConfig < ConfigReader
configure do |config|
config.environment = Rails.env
config.config_file = "config/my_config.yml"
config.sekrets_file = "config/my_config.yml.enc" # optional
config.ignore_missing_keys = false # default
config.permitted_classes = [] # optional
end
endconfig_file may be an exact path. If that path does not exist, ConfigReader
also checks the current directory and config/.
Top-level and nested values are available through methods, [], and dig:
MyConfig.mail_from
MyConfig[:mail_from]
MyConfig["mail_from"]
MyConfig.features.search
MyConfig[:features][:search]
MyConfig.dig(:features, :search)Arrays work with dig too:
MyConfig.dig(:servers, 0, :host)If you want to read a dotted path from user input, use dig_path:
#!/usr/bin/env ruby
require "bundler/setup"
require_relative "../app/lib/config"
print Config.dig_path(ARGV.fetch(0))parse_path is also public if you need the normalized path segments:
MyConfig.parse_path("servers.0.host")
# => [:servers, 0, :host]String paths treat numeric segments as array indexes. If you need a literal key
that contains . or looks numeric, pass an array instead:
MyConfig.dig_path([:numeric_keys, "0"])
MyConfig.dig_path(["smtp.example.com"])You can inspect the resolved config for all environments and reload it at runtime:
MyConfig.envs["production"]
MyConfig.reloadBy default, missing keys raise KeyError. To return nil instead:
class LenientConfig < ConfigReader
configure do |config|
config.environment = Rails.env
config.config_file = "config/my_config.yml"
config.ignore_missing_keys = true
end
endConfigReader supports Sekrets integration, but only loads the sekrets gem
when sekrets_file is configured.
The sekrets file uses the same structure as the main config file. Sekrets values are merged after the normal defaults plus environment merge, so matching sekrets values override plain YAML values.
class SecureConfig < ConfigReader
configure do |config|
config.environment = Rails.env
config.config_file = "config/my_config.yml"
config.sekrets_file = "config/my_config.yml.enc"
end
endSee https://github.com/ahoward/sekrets for more information.
ERB is evaluated before the YAML is parsed:
defaults:
cache_url: <%= ENV.fetch("CACHE_URL", "redis://localhost:6379/0") %>YAML is loaded with Psych.safe_load. Symbol is always permitted, and you
can allow additional classes through permitted_classes:
class TypedConfig < ConfigReader
configure do |config|
config.environment = Rails.env
config.config_file = "config/my_config.yml"
config.permitted_classes = [Date, Time]
end
end- Fork the project.
- Make your change.
- Add or update tests.
- Open a pull request.
Copyright (c) Michael Moen. See LICENSE for details.