Add this line to your application's Gemfile:
gem 'hfc'
And then execute:
$ bundle
Or install it yourself as:
$ gem install hfc
download the example config from the "config" directory and store it at /opt/hfc/ or set ``env HFC=/my/path
Setup the hierarchy according to your preference and start generating the config based on the facts you give it.
- .rb
- .yaml
- .yml
- .json
You can either version your own config folder using git or you can gemify it:
bundle exec gem Company-Config
# company-config/lib/company/config.rb
require 'hfc'
module Company
module Config
def self.dir
File.join(__dir__,"..","..","hfc")
end
Dir = File.join(__dir__,"..","..","hfc")
end
class HFC
include ::HFC_Base
def initialize(lookup_paths: [::Company::Config::Dir, File.join(ENV['HOME'].to_s, '.config', 'hfc')], **opts)
super(lookup_paths: lookup_paths, **opts)
end
end
end
require 'company/config'
company_hfc = Company::Config.new
Now you have your own config gem which includes your config data. You can version it and include it in any project. The biggest advantage is the semantic versioningi. You can declare now breaking changes of your config.
(H)ierarchical (F)acts (C)onfiguration
In HFC, the facts decide which files get deep-merged into one giant configuration. For every Fact it will try to find the corresponding file in the fact-folder.
No facts:
|
|- {}
|- merge: config/common.(yaml|rb|*)
|- {...}
Facts: {domain: "com"}
|
|- {}
|- merge: common.(yaml|rb|*)
|- merge: domain/com.(yaml|rb|*)
|- merge: domain/com/*.(yaml|rb|*)
|- {...}
Facts: {hostname: "localhost", domain: "com"}
|
|- {}
|- merge: common.(yaml|rb|*)
|- merge: domain/com.(yaml|rb|*)
|- merge: domain/com/*.(yaml|rb|*)
|- merge: hostname/localhost.(yaml|rb|*)
|- merge: hostname/localhost/*(yaml|rb|*)
|- {...}
You can build up this hierarchy of facts with as many facts as you wish.
The lookup order of facts itself can defined in hfc.yaml, but can be also set anywhere else.
See config/hfc.yaml
for example.
---
hfc:
hierarchy:
- :domain
- :hostname
Facts can also be extracted by using named matches of a regex.
hfc:
by_name:
hostname: !ruby/regexp '/(?<fqdn>(?<hostname>[a-z0-9]+)\.?(?<domain>.*))/i'
facts = HFC.facts_by_name("gitlab.com")
# => {fqdn: "gitlab.com", hostname: "gitlab", domain: "com"}
It's also possible to join facts to create a new fact.
hfc:
join_facts:
reverse-hostname:
- :domain
- :hostname
reverse-hostname = "#{domain}-#{hostname}"
Facts can also create new facts
hfc:
by_facts:
fqdn:
"127.0.0.1":
hostname: "localhost"
If the fact "fqdn" equals to "127.0.0.1", then the fact "hostname" will be set to "localhost"
hfc --name gitlab.com
facts = HFC.facts_by_name("gitlab.com")
config = HFC.lookup(facts)
facts = HFC.facts_by_name("127.0.0.1")
config = HFC.lookup(facts: facts)
config.fetch()
# => {my: {nested: {setting: true}}}
config.fetch(:my)
# => {nested: {setting: true}}
config.fetch(:my, "nested")
# => {setting: true}
config.fetch(:my, :nested, :setting)
# => true
config.fetch(:my, "nested")
# => {setting: true}
config.fetch(:my, :nested)
# => {setting: true}
hfc#[]
is an alias of hfc#fetch
config[:my, :nested]
# => {setting: true}
This gem is inspired by
After checking out the repo, run bin/setup
to install dependencies. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/swisscom/hfc.