Blog-Icon_5_100x385

mixlib-config 2.0

mixlib-config is getting an update! We use mixlib-config in Chef to drive the knife.rb and client.rb files (as well as Omnibus config). For a quick overview, to use mixlib-config in your project, you do something like this:

[sourcecode language="ruby"]
  require 'mixlib/config'
  module MyConfig
    extend Mixlib::Config

    default :log_level, 'debug'
    default :max_files, 10
  end

  MyConfig.from_file('~/myconfig.rb') # Run this at startup
[/sourcecode]

Users will be able to have a ~/myconfig.rb file that looks like this:

[sourcecode language="ruby"]
  log_level 'error'
  max_files 5
[/sourcecode]

In 2.0 we’ve added three features to make the user and developer experience that much better:

Nested Configuration

A lot of times, you have related groups of configuration values that you handle with hashes. You can model this in Mixlib::Config with config\_context:

[sourcecode language="ruby"]
  require 'mixlib/config'
  module MyConfig
    extend Mixlib::Config

    config_context :log do
      default :base_name, 'log'
      default :max_files, 10
      default :max_file_size, 1024*1024
    end
  end
[/sourcecode]

Now the user can write this in their configuration file:

[sourcecode language="ruby"]
  log.base_name 'mylog'
  log.max_file_size 2048
[/sourcecode]

Default Values

To do defaults before 2.0, you had to actually write some initialization code that set default values on startup before reading the user’s config file. Now you can declare defaults explicitly, using values or code blocks, and you can even reset configuration back to its default!

[sourcecode language="ruby"]
  require 'mixlib/config'
  module MyConfig
    extend Mixlib::Config

    default :verbose, false # You can set defaults by value
    default(:log_level) { verbose ? 'debug' : 'info' }
  end
[/sourcecode]

In this code, if the user sets verbose to true, MyConfig.log\_level will be debug. But they can still override the log\_level themselves if they want.

To reset everything to default (super useful in tests!) call MyConfig.reset.

Strict Mode

The final new feature is strict mode. A common configuration problem is when a user misspells a config value (‘log\_levl’ instead of ‘log\_level’). You’d like to give some useful feedback to the user at the point where they set or use it. Strict mode does that by throwing Mixlib::Config::UnknownConfigOptionError when an undeclared config option exists.

To enable this: put config\_strict\_mode true in your class:

[sourcecode language="ruby"]
  require 'mixlib/config'
  module MyConfig
    extend Mixlib::Config

    config_strict_mode true

    default :verbose, false
    configurable :name # This is how you declare a config option with no default
  end
[/sourcecode]

The Future

This new syntax opens up a lot of possibilities, like validation, required config parameters, etc. I’m sure you can think of other things–if you do, you can contribute or file feature requests.

Right now mixlib-config 2.0 is in pre-release state, but is backwards-compatible. Give it a shot and let us know what you think!

gem install --pre mixlib-config

John Keiser

John is a Principal Mad Scientist at Chef, has contributed code that will be worked around for years to nearly every piece of software Chef ships. Specific credits include chef-zero, chef-provisioning, and the ChefFS tools (knife diff, upload, and download).