{"id":21888683,"url":"https://github.com/swisscom/hfc","last_synced_at":"2026-04-13T12:31:45.257Z","repository":{"id":73689799,"uuid":"177584440","full_name":"swisscom/hfc","owner":"swisscom","description":null,"archived":false,"fork":false,"pushed_at":"2019-08-22T15:33:06.000Z","size":36,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-03-04T22:02:06.027Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/swisscom.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-25T12:43:04.000Z","updated_at":"2019-08-22T15:33:09.000Z","dependencies_parsed_at":"2023-02-24T01:16:04.782Z","dependency_job_id":null,"html_url":"https://github.com/swisscom/hfc","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/swisscom/hfc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swisscom%2Fhfc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swisscom%2Fhfc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swisscom%2Fhfc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swisscom%2Fhfc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/swisscom","download_url":"https://codeload.github.com/swisscom/hfc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swisscom%2Fhfc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31753067,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T09:16:15.125Z","status":"ssl_error","status_checked_at":"2026-04-13T09:16:05.023Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-28T11:16:37.772Z","updated_at":"2026-04-13T12:31:45.226Z","avatar_url":"https://github.com/swisscom.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# (H)ierarchical(F)acts(C)onfig\n\n## Installation\n\n\n### Gem\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'hfc'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install hfc\n\n\n### config\n\ndownload the example config from the \"config\" directory and store it at /opt/hfc/ or set ``env HFC=/my/path\n\nSetup the hierarchy according to your preference and start generating the config based on the facts you give it.\n\n### Supported extensions\n\n - .rb\n - .yaml\n - .yml\n - .json\n\n### Versioning\n\nYou can either version your own config folder using git or you can gemify it:\n\n```\nbundle exec gem Company-Config\n```\n\n```ruby\n# company-config/lib/company/config.rb \nrequire 'hfc'\nmodule Company\n  module Config\n    def self.dir\n      File.join(__dir__,\"..\",\"..\",\"hfc\")\n    end\n    Dir = File.join(__dir__,\"..\",\"..\",\"hfc\")\n  end\n\n  class HFC\n    include ::HFC_Base\n    def initialize(lookup_paths: [::Company::Config::Dir, File.join(ENV['HOME'].to_s, '.config', 'hfc')], **opts)\n      super(lookup_paths: lookup_paths, **opts)\n    end\n  end\nend\n```\n \n```ruby\nrequire 'company/config' \ncompany_hfc = Company::Config.new\n```\n\nNow you have your own config gem which includes your config data. You can version it and include it in any project.\nThe biggest advantage is the semantic versioningi. You can declare now breaking changes of your config.\n\n## Idea\n\n(H)ierarchical (F)acts (C)onfiguration\n\n### Facts\n\nIn 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.\n\nNo facts: \n```\n|\n|- {}\n|- merge: config/common.(yaml|rb|*)\n|- {...}\n```\n\nFacts: {domain: \"com\"}\n```\n|\n|- {}\n|- merge: common.(yaml|rb|*)\n|- merge: domain/com.(yaml|rb|*) \n|- merge: domain/com/*.(yaml|rb|*) \n|- {...}\n```\n\nFacts: {hostname: \"localhost\", domain: \"com\"}\n```\n|\n|- {}\n|- merge: common.(yaml|rb|*)\n|- merge: domain/com.(yaml|rb|*)\n|- merge: domain/com/*.(yaml|rb|*)\n|- merge: hostname/localhost.(yaml|rb|*) \n|- merge: hostname/localhost/*(yaml|rb|*) \n|- {...}\n```\n\nYou can build up this hierarchy of facts with as many facts as you wish.\n\n### Facts Hierachy\n\nThe lookup order of facts itself can defined in hfc.yaml, but can be also set anywhere else.\n\nSee `config/hfc.yaml` for example.\n\n```yaml\n---\nhfc:\n  hierarchy:\n    - :domain\n    - :hostname\n```\n\n### Facts by name\n\nFacts can also be extracted by using named matches of a regex.\n\n```yaml\nhfc:\n  by_name:\n    hostname:  !ruby/regexp '/(?\u003cfqdn\u003e(?\u003chostname\u003e[a-z0-9]+)\\.?(?\u003cdomain\u003e.*))/i'\n```\n\n```ruby\nfacts = HFC.facts_by_name(\"gitlab.com\")\n# =\u003e {fqdn: \"gitlab.com\", hostname: \"gitlab\", domain: \"com\"}\n```\n\n### Join Facts\n\nIt's also possible to join facts to create a new fact.\n\n```yaml\nhfc:\n  join_facts:\n    reverse-hostname:\n      - :domain\n      - :hostname\n```\n\n```\nreverse-hostname = \"#{domain}-#{hostname}\"\n```\n\n### Facts by Facts\n\nFacts can also create new facts\n\n```yaml\nhfc:\n  by_facts:\n    fqdn:\n      \"127.0.0.1\":\n        hostname: \"localhost\"\n```\n\nIf the fact \"fqdn\" equals to \"127.0.0.1\", then the fact \"hostname\" will be set to \"localhost\"\n\n## Usage\n\n```\nhfc  --name gitlab.com\n```\n\n```ruby\nfacts = HFC.facts_by_name(\"gitlab.com\")\nconfig = HFC.lookup(facts)\n```\n\n### HFC#fetch\n\n```ruby\nfacts = HFC.facts_by_name(\"127.0.0.1\")\nconfig = HFC.lookup(facts: facts)\nconfig.fetch()\n# =\u003e {my: {nested: {setting: true}}}\nconfig.fetch(:my)\n# =\u003e {nested: {setting: true}}\nconfig.fetch(:my, \"nested\")\n# =\u003e {setting: true}\nconfig.fetch(:my, :nested, :setting)\n# =\u003e true\n```\n### HFC#fetch uses internally HashWithIndifferentAccess\n\n```ruby\nconfig.fetch(:my, \"nested\")\n# =\u003e {setting: true}\n```\n```ruby\nconfig.fetch(:my, :nested)\n# =\u003e {setting: true}\n```\n\n### HFC#[]\n\nhfc#`[]` is an alias of hfc#`fetch`\n\n```ruby\nconfig[:my, :nested]\n# =\u003e {setting: true}\n```\n\n\n## Why not use ___ ?\n\nThis gem is inspired by\n - hiera https://github.com/puppetlabs/hiera\n - tty-config https://github.com/piotrmurach/tty-config\n\n## Development\n\nAfter 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.\n\nTo 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](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/swisscom/hfc.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswisscom%2Fhfc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswisscom%2Fhfc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswisscom%2Fhfc/lists"}