Gonfic
Tool-oriented configuration: merge config from ~/, ./, ENV, and OptionParser, access as Hashie::Mash
Installation
Add gem 'gonfic'
to your application's Gemfile
, then run bundle install
.
Usage
CONFIGURATION_FILENAME = '.my_tool' # YAML config file format, by default
CONFIGURATION_DEFAULTS = {a: 1, b: {c: 2}} # will deep_merge! using Hashie magic
CONFIG = Gonfic.new(filename: CONFIGURATION_FILENAME, defaults: CONFIGURATION_DEFAULTS)
puts CONFIG.b.c
Design
Gonfic
is intended to be used with tools - small, often commandline programs.
It will merge configuration from multiple sources, in increasing order of specificity.
You can also think about these sources in terms of how long-lived they are:
config_defaults:
: this is what you determine when writing the tool - lasts as long as this particular tool,~/$CONFIGURATION_FILENAME
: this will be applied every time a particular user uses your tool,./$CONFIGURATION_FILENAME
: every time that user uses your tool, in a particular directory (e.g. source code checkout),ENV
variables: every time your tool is used during a particular session (so it can override directory settings, but persists over multiple runs),OptionParser
'd settings: during a single, particular run.
In the intended scenario (where you allow the config to be slightly flexible) you will barely need to configure your tool's config, aside from providing config_defaults:
once. No listing of allowed setting readers, no spelling out options and types, no mapping to formats - Gonfic
takes care of all that's needed.
Why not...?
These are application-oriented: they have robust support for multiple environments and integration with frameworks.
This is more for library developers: allows you to add configurable settings to an object, which other code will later use.
This one is actually kind of cool, in its minimalism - and intended for similar usage scenarios. But it doesn't seem to be actively developed nowadays, and I wanted a few more features, mostly around some opinionated/automagical defaults.
Advanced scenarios
As 90+% of the functionality is configured by different ways of calling Gonfic.new
, this section delves into possible variants you might want to consider - to fine-tune Gonfic
to your needs.
Deferring dangerous operations
The Gonfic.new
call will peform file I/O and other operations, which can potentially fail and raise errors. Doing things like that is generally frowned upon in initializers and immediately when files are require
d - so CONFIG = Gonfic.new
might not be the best practice ever, succinct as it is. A more prudent approach would be:
module MyTool
def self.config
@config ||= Gonfic.new(...)
end
end
In this way you are lazily deferring the "dangerous" operations until first usage, then memoizing.
Additionally, with access to your config via a method that's easy to stub, your test suite will be happy :)
Providing custom list of directories
By default, Gonfic.new
will look for filename:
in ~/
and ./
(merging them, if both are present).
If you want to load from other directories, just set the directories:
parameter to your list.
Loading configuration from ENV
If you provide filename:
, Gonfic.new
will also check ENV
for variables it considers relevant.
See EnvExtractor.env_prefix_from_filename
for what it will scan - either in source code, or in bin/console
.
The pattern, in general, is that .tool-name
becomes TOOL_NAME_*
- and any variables matching the pattern, and present in defaults:
(again, converted to upcase with underscores), will be merged into resulting configuration.
To disable this behavior, set env_variable_prefix:
to falsey (nil
will do).
You can also override the prefix. Underscore at the end is optional.
Source code
https://gitlab.com/tanstaafl/gonfic
Development
Your first steps should be:
git clone git@gitlab.com:tanstaafl/gonfic.git
cd gonfic
bundle install
bundle exec rake
This will run tests (Minitest) and linter (Rubocop, custom config, see .rubocop.yml
).
Note: the repo does not force the bundle to be vendorized, but should work fine if you set BUNDLE_PATH: "vendor"
in your ~/.bundle/config
. Hint, hint ;)
You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine from sources, run bundle exec rake install
.
Contributing
Bug reports and merge requests are welcome on GitLab at https://gitlab.com/tanstaafl/gonfic.
Name
Yeah, it's not great. As in: not obvious.
If you have an idea how to make it better:
- Go to https://rubygems.org/gems?letter=C
- Binary-search to
conf*
(at this stage you might begin to appreciate how hard naming is in this particular case, I hope). - Send me an issue (or a merge request, or something) with a better name that's available on RubyGems! :D
License
The gem is available as open source under the terms of the MIT License.