README.md in qonfig-0.13.0 vs README.md in qonfig-0.14.0
- old
+ new
@@ -34,28 +34,41 @@
- [Config reloading](#config-reloading) (reload config definitions and option values)
- [Clear options](#clear-options) (set to nil)
- [State freeze](#state-freeze)
- [Settings as Predicates](#settings-as-predicates)
- [Validation](#validation)
+ - [Introduction](#introdaction)
- [Key search pattern](#key-search-pattern)
- [Proc-based validation](#proc-based-validation)
- [Method-based validation](#method-based-validation)
- [Predefined validations](#predefined-validations)
- [Work with files](#work-with-files)
- [Load from YAML file](#load-from-yaml-file)
- [Expose YAML](#expose-yaml) (`Rails`-like environment-based YAML configs)
- [Load from JSON file](#load-from-json-file)
+ - [Expose JSON](#expose-json) (`Rails`-like environment-based JSON configs)
- [Load from ENV](#load-from-env)
- [Load from \_\_END\_\_](#load-from-__end__) (aka `load_from_self`)
+ - [Expose \_\_END\_\_](#expose-__end__) (aka `expose_self`)
- [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) (provides `load_from_toml`, `save_to_toml`, `expose_toml`)
+- [Roadmap](#roadmap)
---
## Definition
+- [Definition and Settings Access](#definition-and-access)
+- [Configuration](#configuration)
+- [Inheritance](#inheritance)
+- [Composition](#composition)
+- [Hash representation](#hash-representation)
+- [Smart Mixin](#smart-mixin) (`Qonfig::Configurable`)
+
+---
+
### Definition and Access
```ruby
# --- definition ---
class Config < Qonfig::DataSet
@@ -394,23 +407,29 @@
# and etc... (all Qonfig-related features)
```
---
-
## Interaction
+- [Iteration over setting keys](#iteration-over-setting-keys) (`#each_setting`, `#deep_each_setting`)
+- [Config reloading](#config-reloading) (reload config definitions and option values)
+- [Clear options](#clear-options) (set to nil)
+- [State freeze](#state-freeze)
+- [Settings as Predicates](#settings-as-predicates)
+
---
### Iteration over setting keys
- `#each_setting { |key, value| }`
- iterates over the root setting keys;
- `#deep_each_setting { |key, value| }`
- iterates over all setting keys (deep inside);
- - key object is represented as a string of `.`-joined keys;
+ - key object is represented as a string of `.`-joined setting key names;
+
```ruby
class Config < Qonfig::DataSet
setting :db do
setting :creds do
setting :user, 'D@iVeR'
@@ -422,20 +441,28 @@
setting :telegraf_url, 'udp://localhost:8094'
setting :telegraf_prefix, 'test'
end
config = Config.new
+```
-# 1. #each_setting
+#### .each_setting
+
+```ruby
config.each_setting { |key, value| { key => value } }
+
# result of each step:
{ 'db' => <Qonfig::Settings:0x00007ff8> }
{ 'telegraf_url' => 'udp://localhost:8094' }
{ 'telegraf_prefix' => 'test' }
+```
-# 2. #deep_each_setting
+#### .deep_each_setting
+
+```ruby
config.deep_each_setting { |key, value| { key => value } }
+
# result of each step:
{ 'db.creds.user' => 'D@iveR' }
{ 'db.creds.password' => 'test123' }
{ 'db.creds.data' => { test: false } }
{ 'telegraf_url' => 'udp://localhost:8094' }
@@ -593,29 +620,36 @@
---
## Validation
+- [Introduction](#introduction)
+- [Key Search Pattern](#key-search-pattern)
+- [Proc-based validation](#proc-based-validation)
+- [Method-based validation](#method-based-validation)
+- [Predefined validations](#predefined-validations)
+
+---
+
+### Introduction
+
Qonfig provides a lightweight DSL for defining validations and works in all cases when setting values are initialized or mutated.
-Settings are validated as keys (matched with a [specific string pattern](#key-search-patern)).
+Settings are validated as keys (matched with a [specific string pattern](#key-search-pattern)).
You can validate both a set of keys and each key separately.
If you want to check the config object completely you can define a custom validation.
**Features**:
-
-- is invoked on any mutation of any setting key
+- validation is invoked on any mutation of any setting:
- during dataset instantiation;
- when assigning new values;
- when calling `#reload!`;
- when calling `#clear!`;
-
- provides special [key search pattern](#key-search-pattern) for matching setting key names;
- uses the [key search pattern](#key-search-pattern) for definging what the setting key should be validated;
- you can define your own custom validation logic and validate dataset instance completely;
- validation logic should return **truthy** or **falsy** value;
-
-- supprots two validation techniques (**proc-based** and **dataset-method-based**)
+- supprots two validation techniques (**proc-based** ([doc](#proc-based-validation)) and **dataset-method-based** ([doc](#method-based-validation))):
- **proc-based** (`setting validation`)
```ruby
validate 'db.user' do |value|
value.is_a?(String)
end
@@ -640,27 +674,28 @@
def check_config
settings.user == User[1]
end
```
+- provides a **set of standard validations** ([doc](#predefined-validations)):
+ - DSL: `validate 'key.pattern', :predefned_validator`;
+ - validators:
+ - `integer`
+ - `float`
+ - `numeric`
+ - `big_decimal`
+ - `boolean`
+ - `string`
+ - `symbol`
+ - `text` (string or symbol)
+ - `array`
+ - `hash`
+ - `proc`
+ - `class`
+ - `module`
+ - `not_nil`
-- provides a set of standard validations:
- - `integer`
- - `float`
- - `numeric`
- - `big_decimal`
- - `boolean`
- - `string`
- - `symbol`
- - `text` (string or symbol)
- - `array`
- - `hash`
- - `proc`
- - `class`
- - `module`
- - `not_nil`
-
---
### Key search pattern
**Key search pattern** works according to the following rules:
@@ -816,16 +851,16 @@
- `:module`
- `:proc`
```ruby
class Config < Qonfig::DataSet
- setting :user
- setting :password
+ setting :user, 'empty'
+ setting :password, 'empty'
setting :service do
- setting :provider
- setting :protocol
+ setting :provider, :empty
+ setting :protocol, :empty
setting :on_fail, -> { puts 'atata!' }
end
setting :ignorance, false
@@ -849,10 +884,22 @@
---
## Work with files
+- [Load from YAML file](#load-from-yaml-file)
+- [Expose YAML](#expose-yaml) (`Rails`-like environment-based YAML configs)
+- [Load from JSON file](#load-from-json-file)
+- [Expose JSON](#expose-json) (`Rails`-like environment-based JSON configs)
+- [Load from ENV](#load-from-env)
+- [Load from \_\_END\_\_](#load-from-__end__) (aka `load_from_self`)
+- [Expose \_\_END\_\_](#expose-__end__) (aka `expose_self`)
+- [Save to JSON file](#save-to-json-file) (`save_to_json`)
+- [Save to YAML file](#save-to-yaml-file) (`save_to_yaml`)
+
+---
+
### Load from YAML file
- supports `ERB`;
- `:strict` mode (fail behaviour when the required yaml file doesnt exist):
- `true` (by default) - causes `Qonfig::FileNotFoundError`;
@@ -1095,10 +1142,124 @@
Config.new.to_h # => { "nonexistent_json" => {}, "another_key" => nil }
```
---
+### Expose JSON
+
+- load configurations from JSON file in Rails-like manner (with environments);
+- works in `load_from_jsom`/`expose_yaml` manner;
+- `via:` - how an environment will be determined:
+ - `:file_name`
+ - load configuration from JSON file that have an `:env` part in it's name;
+ - `:env_key`
+ - load configuration from JSON file;
+ - concrete configuration should be defined in the root key with `:env` name;
+- `env:` - your environment name (must be a type of `String`, `Symbol` or `Numeric`);
+- `strict:` - requires the existence of the file and/or key with the name of the used environment:
+ - `true`:
+ - file should exist;
+ - root key with `:env` name should exist (if `via: :env_key` is used);
+ - raises `Qonfig::ExposeError` if file does not contain the required env key (if `via: :env` key is used);
+ - raises `Qonfig::FileNotFoundError` if the required file does not exist;
+ - `false`:
+ - file is not required;
+ - root key with `:env` name is not required (if `via: :env_key` is used);
+
+#### Environment is defined as a root key of JSON file
+
+```json
+// config/project.json
+
+{
+ "development": {
+ "api_mode_enabled": true,
+ "logging": false,
+ "db_driver": "sequel",
+ "throttle_requests": false,
+ "credentials": {}
+ },
+ "test": {
+ "api_mode_enabled": true,
+ "logging": false,
+ "db_driver": "in_memory",
+ "throttle_requests": false,
+ "credentials": {}
+ },
+ "staging": {
+ "api_mode_enabled": true,
+ "logging": true,
+ "db_driver": "active_record",
+ "throttle_requests": true,
+ "credentials": {}
+ },
+ "production": {
+ "api_mode_enabled": true,
+ "logging": true,
+ "db_driver": "rom",
+ "throttle_requests": true,
+ "credentials": {}
+ }
+}
+```
+
+```ruby
+class Config < Qonfig::DataSet
+ expose_json 'config/project.json', via: :env_key, env: :production # load from production env
+
+ # NOTE: in rails-like application you can use this:
+ expose_json 'config/project.json', via: :env_key, env: Rails.env
+end
+
+config = Config.new
+
+config.settings.api_mode_enabled # => true (from :production subset of keys)
+config.settings.logging # => true (from :production subset of keys)
+config.settings.db_driver # => "rom" (from :production subset of keys)
+config.settings.throttle_requests # => true (from :production subset of keys)
+config.settings.credentials # => {} (from :production subset of keys)
+```
+
+#### Environment is defined as a part of JSON file name
+
+```json
+// config/sidekiq.staging.json
+{
+ "web": {
+ "username": "staging_admin",
+ "password": "staging_password"
+ }
+}
+```
+
+```json
+// config/sidekiq.production.json
+{
+ "web": {
+ "username": "urj1o2",
+ "password": "u192jd0ixz0"
+ }
+}
+```
+
+```ruby
+class SidekiqConfig < Qonfig::DataSet
+ # NOTE: file name should be described WITHOUT environment part (in file name attribute)
+ expose_json 'config/sidekiq.json', via: :file_name, env: :staging # load from staging env
+
+ # NOTE: in rails-like application you can use this:
+ expose_json 'config/sidekiq.json', via: :file_name, env: Rails.env
+end
+
+config = SidekiqConfig.new
+
+config.settings.web.username # => "staging_admin" (from sidekiq.staging.json)
+config.settings.web.password # => "staging_password" (from sidekiq.staging.json)
+```
+
+---
+
### Load from ENV
- `:convert_values` (`false` by default):
- `'t'`, `'T'`, `'true'`, `'TRUE'` - covnerts to `true`;
- `'f'`, `'F'`, `'false'`, `'FALSE'` - covnerts to `false`;
@@ -1166,10 +1327,11 @@
---
### Load from \_\_END\_\_
- aka `load_from_self`
+- works with `YAML` format;
```ruby
class Config < Qonfig::DataSet
load_from_self # on the root
@@ -1204,10 +1366,61 @@
enabled: false
```
---
+### Expose \_\_END\_\_
+
+- aka `expose_self`;
+- works in `expose_json` and `expose_yaml` manner, but with `__END__` instruction of the current file;
+- `env:` - your environment name (must be a type of `String`, `Symbol` or `Numeric`);
+- works with `YAML` format;
+
+```ruby
+class Config < Qonfig::DataSet
+ expose_self env: :production
+
+ # NOTE: for Rails-like applications you can use this:
+ expose_self env: Rails.env
+end
+
+config = Config.new
+
+config.settings.log # => true (from :production environment)
+config.settings.api_enabled # => true (from :production environment)
+config.settings.creds.user # => "D@iVeR" (from :production environment)
+config.settings.creds.password # => "test123" (from :production environment)
+
+__END__
+default: &default
+ log: false
+ api_enabled: true
+ creds:
+ user: admin
+ password: 1234
+
+development:
+ <<: *default
+ log: true
+
+test:
+ <<: *default
+ log: false
+
+staging:
+ <<: *default
+
+production:
+ <<: *default
+ log: true
+ creds:
+ user: D@iVeR
+ password: test123
+```
+
+---
+
### Save to JSON file
- `#save_to_json` - represents config object as a json structure and saves it to a file:
- uses native `::JSON.generate` under the hood;
- writes new file (or rewrites existing file);
@@ -1357,9 +1570,13 @@
Qonfig.plugins # => array of strings
# --- load specific plugin ---
Qonfig.plugin(:plugin_name) # or Qonfig.plugin('plugin_name')
```
+
+Provided plugins:
+
+- [toml](#plugins-toml) (provides `load_from_toml`, `save_to_toml`, `expose_toml`)
---
### Plugins: toml