README.md in qonfig-0.24.1 vs README.md in qonfig-0.25.0
- old
+ new
@@ -38,10 +38,13 @@
- [using a hash](#using-a-hash)
- [using both hash and proc](#using-both-hash-and-proc-proc-has-higher-priority)
- [Inheritance](#inheritance)
- [Composition](#composition)
- [Hash representation](#hash-representation)
+ - [Default behaviour (without options)](#default-behavior-without-options)
+ - [With transformations](#with-transformations)
+ - [Dot-style format](#dot-style-format)
- [Smart Mixin](#smart-mixin) (`Qonfig::Configurable`)
- [Instantiation without class definition](#instantiation-without-class-definition) (`Qonfig::DataSet.build(&definitions)`)
- [Compacted config](#compacted-config)
- [Definition and instantiation](#definition-and-instantiation)
- [by raw initialization](#by-raw-initialization)
@@ -100,10 +103,11 @@
- [Save to JSON file](#save-to-json-file) (`#save_to_json`)
- [Save to YAML file](#save-to-yaml-file) (`#save_to_yaml`)
- [Plugins](#plugins)
- [toml](#plugins-toml) (support for `TOML` format)
- [pretty_print](#plugins-pretty_print) (beautified/prettified console output)
+ - [vault](#plugins-vault) (support for `Vault` store)
- [Roadmap](#roadmap)
- [Build](#build)
---
## Definition
@@ -186,10 +190,14 @@
config.settings['project_id'] # => nil
config.settings['vendor_api']['domain'] # => 'app.service.com'
config.settings['vendor_api']['login'] # => 'test_user'
config.settings['enable_graphql'] # => false
+# dig to value
+config.settings[:vendor_api, :domain] # => 'app.service.com'
+config.settings[:vendor_api, 'login'] # => 'test_user'
+
# get option value directly via index (with indifferent access)
config['project_id'] # => nil
config['enable_graphql'] # => false
config[:project_id] # => nil
config[:enable_graphql] # => false
@@ -269,11 +277,11 @@
```ruby
# - get a subset (a set of sets) of config settings represented as a hash;
# - each key (or key set) represents a requirement of a certain setting key;
-config.subet(:vendor_api, :enable_graphql)
+config.subset(:vendor_api, :enable_graphql)
# => { 'vendor_api' => { 'login' => ..., 'domain' => ... }, 'enable_graphql' => false }
config.subset(:project_id, [:vendor_api, :domain], [:credentials, :user, :login])
# => { 'project_id' => nil, 'domain' => 'app.service.com', 'login' => 'D@iVeR' }
```
@@ -434,10 +442,16 @@
---
### Hash representation
+- works via `#to_h` and `#to_hash`;
+- supported options:
+ - `key_transformer:` - an optional proc that accepts setting key and makes your custom transformations;
+ - `value_transformer:` - an optional proc that accepts setting value and makes your custom transformations;
+ - `dot_style:` - (`false` by default) represent setting keys in dot-notation (transformations are supported too);
+
```ruby
class Config < Qonfig::DataSet
setting :serializers do
setting :json do
setting :engine, :ok
@@ -452,23 +466,76 @@
setting :default, :memory_sync
end
setting :logger, Logger.new(STDOUT)
end
+```
-Config.new.to_h
+#### Default behavior (without-options)
+```ruby
+Config.new.to_h
+# =>
{
"serializers": {
"json" => { "engine" => :ok },
"hash" => { "engine" => :native },
},
"adapter" => { "default" => :memory_sync },
"logger" => #<Logger:0x4b0d79fc>
}
```
+#### With transformations
+
+- with `key_transformer` and/or `value_transformer`;
+
+```ruby
+key_transformer = -> (key) { "#{key}!!" }
+value_transformer = -> (value) { "#{value}??" }
+
+Config.new.to_h(key_transformer: key_transformer, value_transformer: value_transformer)
+# =>
+{
+ "serializers!!": {
+ "json!!" => { "engine!!" => "ok??" },
+ "hash!!" => { "engine!!" => "native??" },
+ },
+ "adapter!!" => { "default!!" => "memory_sync??" },
+ "logger!!" => "#<Logger:0x00007fcde799f158>??"
+}
+```
+
+#### Dot-style format
+
+- transformations are supported too (`key_transformer` and `value_transformer`);
+
+```ruby
+Config.new.to_h(dot_style: true)
+# =>
+{
+ "serializers.json.engine" => :ok,
+ "serializers.hash.engine" => :native,
+ "adapter.default" => :memory_sync,
+ "logger" => #<Logger:0x4b0d79fc>,
+}
+```
+
+```ruby
+transformer = -> (value) { "$$#{value}$$" }
+
+Config.new.to_h(dot_style: true, key_transformer: transformer, value_transformer: transformer)
+
+# => "#<Logger:0x00007fcde799f158>??"
+{
+ "$$serializers.json.engine$$" => "$$ok$$",
+ "$$serializers.hash.engine$$" => "$$native$$",
+ "$$adapter.default$$" => "$$memory_sync$$",
+ "$$logger$$" => "$$#<Logger:0x00007fcde799f158>$$",
+}
+```
+
---
### Smart Mixin
- class-level:
@@ -3089,10 +3156,11 @@
### Plugins
- [toml](#plugins-toml) (provides `load_from_toml`, `save_to_toml`, `expose_toml`);
- [pretty_print](#plugins-pretty_print) (beautified/prettified console output);
+- [vault](#plugins-vault) (provides `load_from_vault`, `expose_vault`)
---
#### Usage
@@ -3212,19 +3280,47 @@
=> #<Config:0x00007f9b6c01dab0 api.domain: "google.ru", api.creds.account: "D@iVeR", api.creds.password: "test123", log_requests: true, use_proxy: true>
```
---
+### Plugins: vault
+
+- `Qonfig.plugin(:vault)`
+- adds support for `vault kv store`, [more info](https://www.vaultproject.io/docs/secrets/kv/kv-v2)
+- depends on `vault` gem ([link](https://github.com/hashicorp/vault-ruby)) (tested on `>= 0.1`);
+- provides `.load_from_vault` (works in `.load_from_yaml` manner ([doc](#load-from-yaml-file)));
+- provides `.expose_vault` (works in `.expose_yaml` manner ([doc](#expose-yaml)));
+
+```ruby
+# 1) require external dependency
+require 'vault'
+
+# 2) Setup vault client
+
+Vault.address = 'http://localhost:8200'
+Vault.token = 'super-duper-token-here'
+
+# 3) enable plugin
+Qonfig.plugin(:vault)
+
+# 3) use vault :)
+```
+
+---
+
## Roadmap
- **Major**:
- support for Rails-like secrets;
- support for persistent data storages (we want to store configs in multiple databases and files);
- rails plugin;
- support for pattern matching;
- **Minor**:
- An ability to flag `Qonfig::Configurable`'s config object as `compacted` (`Qonfig::Compacted`);
+ - Instance-based behavior for `Vault` plugin, also use instance of `Vault` client instead of `Singleton`;
- External validation class with an importing api for better custom validations;
+ - Setting value changement trace (in `anyway_config` manner);
+ - Instantiation and reloading callbacks;
## Build
```shell
bin/rspec -w # test the core functionality and plugins