ComplexConfig

Description

This library makes your YAML configuration files available via a nice API. It also supports different configurations for each RAILS_ENV environment and using plugins to return more complex settings values.

Installation

You can use rubygems to fetch the gem and install it for you:

# gem install complex_config

You can also put this line into your Gemfile

gem 'complex_config', require: 'complex_config/rude'

and bundle. This command will enable all the default plugins and make the cc and complex_config shortcuts available. The configurations are expected to be in the config subdirectory according to the rails convention.

Usage

Given a config file like this and named config/products.yml

development:
  flux_capacitor:
    version_20:
      name: Flux Capacitor Version 2.0
      price_in_cents: 12_000_00
      manual_pdf_url: "http://brown-inc.com/manuals/fc_20.pdf"
    pro_version:
      name: Flux Capacitor Professional
      price_in_cents: 23_000_00
      manual_pdf_url: "http://brown-inc.com/manuals/fc_pro.pdf"
    enterprise_version:
      name: Flux Capacitor Enterpise
      price_in_cents: 1_600_000_00
      manual_pdf_url: "http://brown-inc.com/manuals/fc_enterprise.pdf"

test:
  flux_capacitor:
    test_version:
      name: Yadayada
      price_in_cents: 6_66
      manual_pdf_url: "http://staging.brown-inc.com/manuals/fc_10.pdf"

and using require "complex_config/rude" in the "development" environment you can now access the configuration.

Accessing configuration settings

Fetching the name of a product:

> cc.products.flux_capacitor.enterprise_version.name => "Flux Capacitor Enterpise"

If the name of configuration file isn't valid ruby method name syntax you can also use cc(:products).flux_capacitor… to avoid this problem.

Fetching the price of a product in cents:

> cc.products.flux_capacitor.enterprise_version.price_in_cents => 160000000

Fetching the price of a product and using the ComplexConfig::Plugins::MONEY plugin to format it:

> cc.products.flux_capacitor.enterprise_version.price.format => "€1,600,000.00"

Fetching the URL of a product manual as a string:

> cc.products.flux_capacitor.enterprise_version.manual_pdf_url => "http://brown-inc.com/manuals/fc_enterprise.pdf"

Fetching the URL of a product manual and using the ComplexConfig::Plugins::URI plugin return an URI instance:

> cc.products.flux_capacitor.enterprise_version.manual_pdf_uri => #<URI::HTTP:0x007ff626d2a2e8 URL:http://brown-inc.com/manuals/fc_enterprise.pdf>

You can also fetch config settings from a different environment:

>> pp cc.products(:test); nil
products.flux_capacitor.test_version.name = "Yadayada"
products.flux_capacitor.test_version.price_in_cents = 666
products.flux_capacitor.test_version.manual_pdf_url = "http://staging.brown-inc.com/manuals/fc_10.pdf"

Calling complex_config.products. instead of cc(…) would skip the implicite namespacing via the RAILS_ENV environment, so complex_config(:products).test.flux_capacitor returns the same settings object.

Configuration

You can complex_config by passing a block to its configure method, which you can for example do in a rails config/initializers file:

ComplexConfig.configure do |config|
  config.deep_freeze = !Rails.env.test? # allow modification during tests b/c of stubs etc.

  # config.env = 'some_environment'

  # config.config_dir = Rails.root + 'config'

  config.add_plugin -> id do
    if base64_string = ask_and_send("#{id}_base64")
      Base64.decode64 base64_string
    else
      skip
    end
  end
end

Adding plugins

You can add your own plugins by calling

ComplexConfig::Provider.add_plugin SomeNamespace::PLUGIN

or in the configuration block by calling

ComplexConfig.configure do |config|
  config.add_plugin SomeNamespace::PLUGIN
end

Implementing your own plugins

A plugin is just a lambda expression with a single argument id which identifies the attribute that is being accessed. If it calls skip it won't apply and the following plugins are tried until one doesn't call skip and returns a value instead.

Here is the ComplexConfig::Plugins::MONEY plugin for example:

require 'monetize'

module ComplexConfig::Plugins
  MONEY = -> id do
    if cents = ask_and_send("#{id}_in_cents")
      Money.new(cents)
    else
      skip
    end
  end
end

Changes

  • 2019-03-18 Release 0.17.0
    • Improve error message for missing encryption key
  • 2019-03-14 Release 0.16.0
    • Enable - trim_mode for ERB in yml files
    • Allow to_json calls on settings
  • 2019-03-14 Release 0.15.1
    • Fix shared feature for empy top level settings
  • 2018-12-07 Release 0.15.0
    • Allow inplace recrypt for encrypted files
  • 2018-07-06 Release 0.14.0
    • Better support for rails encryption
    • Adds complex_config executable.
  • 2018-02-23 Release 0.13.3 Change evaluation order of key sources
  • 2018-02-23 Release 0.13.2 Refactor key sources
  • 2018-02-09 Release 0.13.1 Improve error reporting for encrypted files (missing key)
  • 2018-01-26 Release 0.13.0 Improve write_config interface and more tests
  • 2017-11-17 Release 0.12.2 Output string keys on top level configs, Rails don't like it otherwise.
  • 2017-11-17 Release 0.12.1 Do not output newlines when writing encrypted configs, Rails don't like it.
  • 2017-11-16 Release 0.12.0
    • Supports writing of configurations (encrypted or unencrypted)
  • 2017-11-16 Release 0.11.3
    • Small bugfix
  • 2017-10-30 Release 0.11.2
    • Small bugfix
  • 2017-10-27 Release 0.11.1
    • Small bugfix
  • 2017-10-27 Release 0.11.0
    • Support encrypted config files a la rails
  • 2017-02-02 Release 0.10.0
    • cc.foo?/complex_config.foo? returns config or nil (when not existant)
  • 2017-01-23 Release 0.9.2
    • Improve performance for proxy objects
  • 2016-11-22 Release 0.9.1
    • Fix travis builds
  • 2016-11-22 Release 0.9.0
    • Extract ComplexConfig::Provider::Shortcuts into its own module
  • 2016-07-21 Release 0.8.0
    • ComplexConfig::Settings can be replaced with replace_attributes which allows for easier testing by calling: cc.foo.replace_attributes(new: 'settings').
  • 2016-07-15 Release 0.7.0
    • Slim down ComplexConfig::Settings interface to avoid clashes with methods mixed into Object class or Enumerable#instance_methods
  • 2016-07-15 Release 0.6.0
    • Depend on mize gem for caching.
  • 2016-06-23 Release 0.5.2
    • Resolve index access via the plugin code path, so foo.bar and foo[:bar] have the same result for a plugin key.
  • 2015-11-19 Release 0.5.0
    • Support rails reloading behaviour.
    • Allow configuration via ComplexConfig.configure(&block) method.
  • 2015-11-17 Release 0.4.0
    • Add root object for configuration, e. g. cc.name instead of cc(name).
  • 2015-11-03 Release 0.3.1
    • Add missing dependency to tins.
  • 2015-11-03 Release 0.3.0
    • Add nicer default output for settings.
  • 2015-03-24 Release 0.2.3
    • Fix typo in load error case of money.
  • 2015-02-25 Release 0.2.2
    • Fix an issue with path interpolation.
  • 2015-01-28 Release 0.2.1
    • Turn monetize into a runtime dependency for the plugin.
  • 2015-01-27 Release 0.2.0
    • Fix for attributes named like Enumerable methods
    • Make tests run on JRuby
  • 2015-01-01 Release 0.1.1
    • Some small fixes for handling of arrays
  • 2014-12-15 Release 0.1.0
    • Freeze configuration by default.
  • 2014-12-12 Release 0.0.0

Download

The homepage of this library is located at

Author

Florian Frank

License

This software is licensed under the Apache 2.0 license.