# 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 * 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 * https://github.com/flori/complex_config ## Author [Florian Frank](mailto:flori@ping.de) ## License This software is licensed under the Apache 2.0 license.