qonfig 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +24 -3
- data/CHANGELOG.md +47 -1
- data/README.md +472 -19
- data/lib/qonfig/command_set.rb +26 -4
- data/lib/qonfig/commands/add_nested_option.rb +14 -11
- data/lib/qonfig/commands/add_option.rb +8 -3
- data/lib/qonfig/commands/compose.rb +7 -0
- data/lib/qonfig/commands/load_from_env/value_converter.rb +84 -0
- data/lib/qonfig/commands/load_from_env.rb +97 -0
- data/lib/qonfig/commands/load_from_self.rb +77 -0
- data/lib/qonfig/commands/load_from_yaml.rb +62 -0
- data/lib/qonfig/configurable.rb +108 -0
- data/lib/qonfig/data_set/class_builder.rb +32 -0
- data/lib/qonfig/data_set.rb +96 -5
- data/lib/qonfig/dsl.rb +48 -7
- data/lib/qonfig/error.rb +47 -1
- data/lib/qonfig/loaders/yaml.rb +34 -0
- data/lib/qonfig/settings/builder.rb +22 -0
- data/lib/qonfig/settings/key_guard.rb +75 -0
- data/lib/qonfig/settings/lock.rb +64 -0
- data/lib/qonfig/settings.rb +215 -54
- data/lib/qonfig/version.rb +2 -2
- data/lib/qonfig.rb +13 -1
- data/qonfig.gemspec +3 -3
- metadata +18 -9
- data/lib/qonfig/settings_builder.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 364dfdc09c159ed886729491cc0d066f961b5be382b766d99d57705fca5f88d7
|
4
|
+
data.tar.gz: 9525458cf3d84fa9588ab48805cdb8a5ec0150278a7658986fb6325efcd2d191
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6cf8f8df874ebcb636f7862247ada545579f413c030b4d4dde51decb72ed18f38f5af3faa9c595e6cf741f25ab6fc8a09afef4c72133ced1448f12bbe76dbb96
|
7
|
+
data.tar.gz: 785f7e10238601b7f5be5c506d516004eee7d914b451e2a4c0a7e0aebf6257ca0003f19a52bad0c86f35c89713b4a837d5e175cbf71217cbd1f0de1a6950cc45
|
data/.rubocop.yml
CHANGED
@@ -5,8 +5,8 @@ AllCops:
|
|
5
5
|
DisplayStyleGuide: true
|
6
6
|
TargetRubyVersion: 2.5.1
|
7
7
|
Include:
|
8
|
-
- lib
|
9
|
-
- spec
|
8
|
+
- lib/**/*.rb
|
9
|
+
- spec/**/*.rb
|
10
10
|
Exclude:
|
11
11
|
- bin/**/*
|
12
12
|
- Gemfile
|
@@ -61,6 +61,9 @@ Lint/HandleExceptions:
|
|
61
61
|
Metrics/MethodLength:
|
62
62
|
Max: 20
|
63
63
|
|
64
|
+
Style/DoubleNegation:
|
65
|
+
Enabled: false
|
66
|
+
|
64
67
|
Style/EmptyCaseCondition:
|
65
68
|
Enabled: false
|
66
69
|
|
@@ -70,5 +73,23 @@ RSpec/ExampleLength:
|
|
70
73
|
RSpec/MultipleExpectations:
|
71
74
|
Enabled: false
|
72
75
|
|
76
|
+
Style/MultilineBlockChain:
|
77
|
+
Enabled: false
|
78
|
+
|
73
79
|
Metrics/AbcSize:
|
74
|
-
Max:
|
80
|
+
Max: 19
|
81
|
+
|
82
|
+
Metrics/CyclomaticComplexity:
|
83
|
+
Max: 10
|
84
|
+
|
85
|
+
Metrics/PerceivedComplexity:
|
86
|
+
Max: 10
|
87
|
+
|
88
|
+
Style/ClassAndModuleChildren:
|
89
|
+
Enabled: false
|
90
|
+
|
91
|
+
Lint/UnderscorePrefixedVariableName:
|
92
|
+
Enabled: false
|
93
|
+
|
94
|
+
Security/YAMLLoad:
|
95
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,51 @@
|
|
1
1
|
# Changelog
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
-
## [0.
|
4
|
+
## [0.2.0] - 2018-06-07
|
5
|
+
### Added
|
6
|
+
- Instant configuration via block `config = Config.new { |conf| <<your configuration code>> }`;
|
7
|
+
- `.load_from_env` command - an ability to define config settings by loading them from ENV variable;
|
8
|
+
- `.load_from_yaml` command - an ability to define config settings by loading them from a yaml file;
|
9
|
+
- `.load_from_self` command - an ability to load config definitions form the YAML
|
10
|
+
instructions written in the file where the config class is defined (`__END__` section);
|
11
|
+
- `#reload!` - an ability to reload config isntance after any config class changes and updates;
|
12
|
+
- `#clear!` - an ability to set all options to `nil`;
|
13
|
+
- `#dig` - an ability to fetch setting values in `Hash#dig` manner
|
14
|
+
(fails with `Qonfig::UnknownSettingError` when the required key does not exist);
|
15
|
+
- Settings as Predicates - an ability to check the boolean nature of the config setting by appending
|
16
|
+
the question mark symbol (`?`) at the end of setting name:
|
17
|
+
- `nil` and `false` setting values indicates `false`;
|
18
|
+
- other setting values indicates `true`;
|
19
|
+
- setting roots always returns `true`;
|
20
|
+
- examples:
|
21
|
+
- `config.settings.database.user # => nil`;
|
22
|
+
- `config.settings.database.user? # => false`;
|
23
|
+
- `config.settings.database.host # => 'google.com'`;
|
24
|
+
- `config.settings.database.host? # => true`;
|
25
|
+
- `config.settings.database? # => true (setting with nested option (setting root))`
|
26
|
+
- Support for ERB instructions in YAML;
|
27
|
+
- Support for `HashWithIndifferentAccess`-like behaviour;
|
28
|
+
- `Qonfig::Settings` instance method redefinition protection: the setting key can not
|
29
|
+
have a name that matches an any instance method name of `Qonfig::Settings`;
|
30
|
+
- Added `Qonfig::Configurable` mixin - configuration behaviour for any classes and modules
|
31
|
+
and their instances:
|
32
|
+
- all `Qonfig`-related features;
|
33
|
+
- different class-level and instance-level config objects;
|
34
|
+
- working class-level inheritance :);
|
35
|
+
- Full thread-safe implementation;
|
36
|
+
|
37
|
+
### Changed
|
38
|
+
- Superclass of `Qonfig::FrozenSettingsError` (it was `Qonfig::Error` before):
|
39
|
+
- `ruby >= 2.5` - inherited from `::FrozenError`;
|
40
|
+
- `ruby < 2.5` - inherited from `::RuntimeError`;
|
41
|
+
- `.setting` will raise exceptions immediately:
|
42
|
+
- `.setting(key, ...) { ... }` - if setting key has incompatible type;
|
43
|
+
- `.compose(config_class)`- if composed config class is not a subtype of `Qonfig::DataSet`;
|
44
|
+
|
45
|
+
### Fixed
|
46
|
+
- Recoursive hash representation with deep nested `Qonfig::Settings` values (infinite loop);
|
47
|
+
- Fixed re-assignment of the options with nested options (losing the nested options
|
48
|
+
due to the instance configuration). Now it causes `Qonfig::AmbigousSettingValueError`.
|
49
|
+
|
50
|
+
## [0.1.0] - 2018-05-18
|
5
51
|
- Release :)
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
# Qonfig · [![Gem Version](https://badge.fury.io/rb/qonfig.svg)](https://badge.fury.io/rb/qonfig) [![Build Status](https://travis-ci.org/0exp/qonfig.svg?branch=master)](https://travis-ci.org/0exp/qonfig) [![Coverage Status](https://coveralls.io/repos/github/0exp/qonfig/badge.svg)](https://coveralls.io/github/0exp/qonfig)
|
1
|
+
# Qonfig · [![Gem Version](https://badge.fury.io/rb/qonfig.svg)](https://badge.fury.io/rb/qonfig) [![Build Status](https://travis-ci.org/0exp/qonfig.svg?branch=master)](https://travis-ci.org/0exp/qonfig) [![Coverage Status](https://coveralls.io/repos/github/0exp/qonfig/badge.svg?branch=master)](https://coveralls.io/github/0exp/qonfig?branch=master)
|
2
2
|
|
3
3
|
Config. Defined as a class. Used as an instance. Support for inheritance and composition.
|
4
|
-
Lazy instantiation. Command-style DSL. Extremely simple to define. Extremely simple to use. That's all.
|
4
|
+
Lazy instantiation. Thread-safe. Command-style DSL. Extremely simple to define. Extremely simple to use. That's all.
|
5
5
|
|
6
6
|
## Installation
|
7
7
|
|
@@ -12,7 +12,7 @@ gem 'qonfig'
|
|
12
12
|
```shell
|
13
13
|
$ bundle install
|
14
14
|
# --- or ---
|
15
|
-
gem install 'qonfig'
|
15
|
+
$ gem install 'qonfig'
|
16
16
|
```
|
17
17
|
|
18
18
|
```ruby
|
@@ -27,6 +27,13 @@ require 'qonfig'
|
|
27
27
|
- [Composition](#composition)
|
28
28
|
- [Hash representation](#hash-representation)
|
29
29
|
- [State freeze](#state-freeze)
|
30
|
+
- [Config reloading](#config-reloading) (reload config definitions and option values)
|
31
|
+
- [Clear options](#clear-options) (set to nil)
|
32
|
+
- [Settings as Predicates](#settings-as-predicates)
|
33
|
+
- [Load from YAML file](#load-from-yaml-file)
|
34
|
+
- [Load from ENV](#load-from-env)
|
35
|
+
- [Load from \_\_END\_\_](#load-from-__end__) (aka `load_from_self`)
|
36
|
+
- [Smart Mixin](#smart-mixin) (`Qonfig::Configurable`)
|
30
37
|
|
31
38
|
---
|
32
39
|
|
@@ -40,7 +47,6 @@ class Config < Qonfig::DataSet
|
|
40
47
|
# nested setting
|
41
48
|
setting :vendor_api do
|
42
49
|
setting :host, 'app.service.com'
|
43
|
-
setting :port, 12345
|
44
50
|
end
|
45
51
|
|
46
52
|
setting :enable_graphql, false
|
@@ -48,25 +54,38 @@ class Config < Qonfig::DataSet
|
|
48
54
|
# nested setting reopening
|
49
55
|
setting :vendor_api do
|
50
56
|
setting :user, 'test_user'
|
51
|
-
setting :password, 'test_password'
|
52
57
|
end
|
53
58
|
end
|
54
59
|
|
55
60
|
config = Config.new
|
56
61
|
|
62
|
+
# get option value via method
|
57
63
|
config.settings.project_id # => nil
|
58
|
-
config.settings.vendor_api.host # => '
|
59
|
-
config.settings.vendor_api.port # => 12345
|
64
|
+
config.settings.vendor_api.host # => 'app.service.com'
|
60
65
|
config.settings.vendor_api.user # => 'test_user'
|
61
|
-
config.settings.vendor_api.password # => 'test_password'
|
62
66
|
config.settings.enable_graphql # => false
|
63
67
|
|
68
|
+
# get option value via index (with indifferent (string / symbol / mixed) access)
|
64
69
|
config.settings[:project_id] # => nil
|
65
|
-
config.settings[:vendor_api][:host] # => '
|
66
|
-
config.settings[:vendor_api][:port] # => 12345
|
70
|
+
config.settings[:vendor_api][:host] # => 'app.service.com'
|
67
71
|
config.settings[:vendor_api][:user] # => 'test_user'
|
68
|
-
config.settings[:vendor_api][:password] # => 'test_password'
|
69
72
|
config.settings[:enable_graphql] # => false
|
73
|
+
|
74
|
+
# get option value via index (with indifferent (string / symbol / mixed) access)
|
75
|
+
config.settings['project_id'] # => nil
|
76
|
+
config.settings['vendor_api']['host'] # => 'app.service.com'
|
77
|
+
config.settings['vendor_api']['user'] # => 'test_user'
|
78
|
+
config.settings['enable_graphql'] # => false
|
79
|
+
|
80
|
+
# get option value directly via index (with indifferent access)
|
81
|
+
config['project_id'] # => nil
|
82
|
+
config['enable_graphql'] # => false
|
83
|
+
config[:project_id] # => nil
|
84
|
+
config[:enable_graphql] # => false
|
85
|
+
|
86
|
+
# get option value in Hash#dig manner (and fail when the required key does not exist)
|
87
|
+
config.dig(:vendor_api, :host) # => 'app.service.com' # (key exists)
|
88
|
+
config.dig(:vendor_api, :port) # => Qonfig::UnknownSettingError # (key does not exist)
|
70
89
|
```
|
71
90
|
|
72
91
|
---
|
@@ -89,7 +108,7 @@ end
|
|
89
108
|
|
90
109
|
config = Config.new
|
91
110
|
|
92
|
-
# configure via
|
111
|
+
# configure via proc
|
93
112
|
config.configure do |conf|
|
94
113
|
conf.enable_middlewares = true
|
95
114
|
conf.geo_api.provider = :yandex_maps
|
@@ -105,6 +124,13 @@ config.settings.testing.engine = :ultra_test
|
|
105
124
|
config.settings[:enable_middlewares] = true
|
106
125
|
config.settings[:geo_api][:provider] = :rambler_maps
|
107
126
|
config.settings[:testing][:engine] = :mega_test
|
127
|
+
|
128
|
+
# instant configuration via proc
|
129
|
+
config = Config.new do |conf|
|
130
|
+
conf.enable_middlewares = false
|
131
|
+
conf.geo_api.provider = :amazon_maps
|
132
|
+
conf.testing.engine = :crypto_test
|
133
|
+
end
|
108
134
|
```
|
109
135
|
|
110
136
|
---
|
@@ -191,7 +217,7 @@ class Config < Qonfig::DataSet
|
|
191
217
|
end
|
192
218
|
|
193
219
|
setting :adapter do
|
194
|
-
setting :default
|
220
|
+
setting :default, :memory_sync
|
195
221
|
end
|
196
222
|
|
197
223
|
setting :logger, Logger.new(STDOUT)
|
@@ -200,23 +226,107 @@ end
|
|
200
226
|
Config.new.to_h
|
201
227
|
|
202
228
|
{
|
203
|
-
serializers: {
|
204
|
-
json
|
205
|
-
hash
|
229
|
+
"serializers": {
|
230
|
+
"json" => { "engine" => :ok },
|
231
|
+
"hash" => { "engine" => :native },
|
206
232
|
},
|
207
|
-
adapter
|
208
|
-
logger
|
233
|
+
"adapter" => { "default" => :memory_sync },
|
234
|
+
"logger" => #<Logger:0x4b0d79fc>
|
209
235
|
}
|
210
236
|
```
|
211
237
|
|
212
238
|
---
|
213
239
|
|
240
|
+
### Config reloading
|
241
|
+
|
242
|
+
```ruby
|
243
|
+
class Config < Qonfig::DataSet
|
244
|
+
setting :db do
|
245
|
+
setting :adapter, 'postgresql'
|
246
|
+
end
|
247
|
+
|
248
|
+
setting :logger, Logger.new(STDOUT)
|
249
|
+
end
|
250
|
+
|
251
|
+
config = Config.new
|
252
|
+
|
253
|
+
config.settings.db.adapter # => 'postgresql'
|
254
|
+
config.settings.logger # => #<Logger:0x00007ff9>
|
255
|
+
|
256
|
+
config.configure { |conf| conf.logger = nil } # redefine some settings (will be reloaded)
|
257
|
+
|
258
|
+
# re-define and append settings
|
259
|
+
class Config
|
260
|
+
setting :db do
|
261
|
+
setting :adapter, 'mongoid' # re-define defaults
|
262
|
+
end
|
263
|
+
|
264
|
+
setting :enable_api, false # append new setting
|
265
|
+
end
|
266
|
+
|
267
|
+
# reload settings
|
268
|
+
config.reload!
|
269
|
+
|
270
|
+
config.settings.db.adapter # => 'mongoid'
|
271
|
+
config.settings.logger # => #<Logger:0x00007ff9> (reloaded from defaults)
|
272
|
+
config.settings.enable_api # => false (new setting)
|
273
|
+
|
274
|
+
# reload with instant configuration
|
275
|
+
config.reload! do |conf|
|
276
|
+
conf.enable_api = true # changed instantly
|
277
|
+
end
|
278
|
+
|
279
|
+
config.settings.db.adapter # => 'mongoid'
|
280
|
+
config.settings.logger = # => #<Logger:0x00007ff9>
|
281
|
+
config.settings.enable_api # => true # value from instant change
|
282
|
+
```
|
283
|
+
|
284
|
+
---
|
285
|
+
|
286
|
+
### Clear options
|
287
|
+
|
288
|
+
```ruby
|
289
|
+
class Config
|
290
|
+
setting :database do
|
291
|
+
setting :user
|
292
|
+
setting :password
|
293
|
+
end
|
294
|
+
|
295
|
+
setting :web_api do
|
296
|
+
setting :endpoint
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
config = Config.new do |conf|
|
301
|
+
conf.database.user = '0exp'
|
302
|
+
conf.database.password = 'test123'
|
303
|
+
|
304
|
+
conf.web_api.endpoint = '/api/'
|
305
|
+
end
|
306
|
+
|
307
|
+
config.settings.database.user # => '0exp'
|
308
|
+
config.settings.database.password # => 'test123'
|
309
|
+
config.settings.web_api.endpoint # => '/api'
|
310
|
+
|
311
|
+
# clear all options
|
312
|
+
config.clear!
|
313
|
+
|
314
|
+
config.settings.database.user # => nil
|
315
|
+
config.settings.database.password # => nil
|
316
|
+
config.settings.web_api.endpoint # => nil
|
317
|
+
```
|
318
|
+
|
319
|
+
---
|
320
|
+
|
214
321
|
### State freeze
|
215
322
|
|
216
323
|
```ruby
|
217
324
|
class Config < Qonfig::DataSet
|
218
325
|
setting :logger, Logger.new(STDOUT)
|
219
326
|
setting :worker, :sidekiq
|
327
|
+
setting :db do
|
328
|
+
setting :adapter, 'postgresql'
|
329
|
+
end
|
220
330
|
end
|
221
331
|
|
222
332
|
config = Config.new
|
@@ -224,14 +334,357 @@ config.freeze!
|
|
224
334
|
|
225
335
|
config.settings.logger = Logger.new(StringIO.new) # => Qonfig::FrozenSettingsError
|
226
336
|
config.settings.worker = :que # => Qonfig::FrozenSettingsError
|
337
|
+
config.settings.db.adapter = 'mongoid' # => Qonfig::FrozenSettingsError
|
338
|
+
|
339
|
+
config.reload! # => Qonfig::FrozenSettingsError
|
340
|
+
```
|
341
|
+
|
342
|
+
---
|
343
|
+
|
344
|
+
### Settings as Predicates
|
345
|
+
|
346
|
+
- predicate form: `?` at the end of setting name;
|
347
|
+
- `nil` and `false` setting values indicates `false`;
|
348
|
+
- other setting values indicates `true`;
|
349
|
+
- setting roots always returns `true`;
|
350
|
+
|
351
|
+
```ruby
|
352
|
+
class Config < Qonfig::DataSet
|
353
|
+
setting :database do
|
354
|
+
setting :user
|
355
|
+
setting :host, 'google.com'
|
356
|
+
|
357
|
+
setting :engine do
|
358
|
+
setting :driver, 'postgres'
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
config = Config.new
|
364
|
+
|
365
|
+
# predicates
|
366
|
+
config.settings.database.user? # => false (nil => false)
|
367
|
+
config.settings.database.host? # => true ('google.com' => true)
|
368
|
+
config.settings.database.engine.driver? # => true ('postgres' => true)
|
369
|
+
|
370
|
+
# setting roots always returns true
|
371
|
+
config.settings.database? # => true
|
372
|
+
config.settings.database.engine? # => ture
|
373
|
+
|
374
|
+
config.configure do |conf|
|
375
|
+
conf.database.user = '0exp'
|
376
|
+
conf.database.host = false
|
377
|
+
conf.database.engine.driver = true
|
378
|
+
end
|
379
|
+
|
380
|
+
# predicates
|
381
|
+
config.settings.database.user? # => true ('0exp' => true)
|
382
|
+
config.settings.database.host? # => false (false => false)
|
383
|
+
config.settings.database.engine.driver? # => true (true => true)
|
227
384
|
```
|
228
385
|
|
229
386
|
---
|
230
387
|
|
388
|
+
### Load from YAML file
|
389
|
+
|
390
|
+
- `:strict` mode (fail behaviour when the required yaml file doesnt exist):
|
391
|
+
- `true` (by default) - causes `Qonfig::FileNotFoundError`;
|
392
|
+
- `false` - do nothing, ignore current command;
|
393
|
+
|
394
|
+
```yaml
|
395
|
+
<!-- travis.yml -->
|
396
|
+
sudo: false
|
397
|
+
language: ruby
|
398
|
+
rvm:
|
399
|
+
- ruby-head
|
400
|
+
- jruby-head
|
401
|
+
```
|
402
|
+
|
403
|
+
```yaml
|
404
|
+
<!-- project.yml -->
|
405
|
+
enable_api: false
|
406
|
+
Sidekiq/Scheduler:
|
407
|
+
enable: true
|
408
|
+
```
|
409
|
+
|
410
|
+
```yaml
|
411
|
+
<!-- ruby_data.yml -->
|
412
|
+
version: <%= RUBY_VERSION %>
|
413
|
+
platform: <%= RUBY_PLATFORM %>
|
414
|
+
```
|
415
|
+
|
416
|
+
```ruby
|
417
|
+
class Config < Qonfig::DataSet
|
418
|
+
setting :ruby do
|
419
|
+
load_from_yaml 'ruby_data.yml'
|
420
|
+
end
|
421
|
+
|
422
|
+
setting :travis do
|
423
|
+
load_from_yaml 'travis.yml'
|
424
|
+
end
|
425
|
+
|
426
|
+
load_from_yaml 'project.yml'
|
427
|
+
end
|
428
|
+
|
429
|
+
config = Config.new
|
430
|
+
|
431
|
+
config.settings.travis.sudo # => false
|
432
|
+
config.settings.travis.language # => 'ruby'
|
433
|
+
config.settings.travis.rvm # => ['ruby-head', 'jruby-head']
|
434
|
+
config.settings.enable_api # => false
|
435
|
+
config.settings['Sidekiq/Scheduler']['enable'] #=> true
|
436
|
+
config.settings.ruby.version # => '2.5.1'
|
437
|
+
config.settings.ruby.platform # => 'x86_64-darwin17'
|
438
|
+
```
|
439
|
+
|
440
|
+
```ruby
|
441
|
+
# --- strict mode ---
|
442
|
+
class Config < Qonfig::DataSet
|
443
|
+
setting :nonexistent_yaml do
|
444
|
+
load_from_yaml 'unexistent_file.yml', strict: true # true by default
|
445
|
+
end
|
446
|
+
|
447
|
+
setting :another_key
|
448
|
+
end
|
449
|
+
|
450
|
+
Config.new # => Qonfig::FileNotFoundError
|
451
|
+
|
452
|
+
# --- non-strict mode ---
|
453
|
+
class Config < Qonfig::DataSet
|
454
|
+
settings :nonexistent_yaml do
|
455
|
+
load_from_yaml 'unexistent_file.yml', strict: false
|
456
|
+
end
|
457
|
+
|
458
|
+
setting :another_key
|
459
|
+
end
|
460
|
+
|
461
|
+
Config.new.to_h # => { "nonexistent_yaml" => {}, "another_key" => nil }
|
462
|
+
```
|
463
|
+
|
464
|
+
---
|
465
|
+
|
466
|
+
### Load from ENV
|
467
|
+
|
468
|
+
- `:convert_values` (`false` by default):
|
469
|
+
- `'t'`, `'T'`, `'true'`, `'TRUE'` - covnerts to `true`;
|
470
|
+
- `'f'`, `'F'`, `'false'`, `'FALSE'` - covnerts to `false`;
|
471
|
+
- `1`, `23` and etc - converts to `Integer`;
|
472
|
+
- `1.25`, `0.26` and etc - converts to `Float`;
|
473
|
+
- `1, 2, test`, `FALSE,Qonfig` (strings without quotes that contains at least one comma) -
|
474
|
+
converts to `Array` with recursively converted values;
|
475
|
+
- `'"please, test"'`, `"'test, please'"` (quoted strings) - converts to `String` without quotes;
|
476
|
+
- `:prefix` - load ENV variables which names starts with a prefix:
|
477
|
+
- `nil` (by default) - empty prefix;
|
478
|
+
- `Regexp` - names that match the regexp pattern;
|
479
|
+
- `String` - names which starts with a passed string;
|
480
|
+
- `:trim_prefix` (`false` by default);
|
481
|
+
|
482
|
+
```ruby
|
483
|
+
# some env variables
|
484
|
+
ENV['QONFIG_BOOLEAN'] = 'true'
|
485
|
+
ENV['QONFIG_INTEGER'] = '0'
|
486
|
+
ENV['QONFIG_STRING'] = 'none'
|
487
|
+
ENV['QONFIG_ARRAY'] = '1, 2.5, t, f, TEST'
|
488
|
+
ENV['QONFIG_MESSAGE'] = '"Hello, Qonfig!"'
|
489
|
+
ENV['RUN_CI'] = '1'
|
490
|
+
|
491
|
+
class Config < Qonfig::DataSet
|
492
|
+
# nested
|
493
|
+
setting :qonfig do
|
494
|
+
load_from_env convert_values: true, prefix: 'QONFIG' # or /\Aqonfig.*\z/i
|
495
|
+
end
|
496
|
+
|
497
|
+
setting :trimmed do
|
498
|
+
load_from_env convert_values: true, prefix: 'QONFIG_', trim_prefix: true # trim prefix
|
499
|
+
end
|
500
|
+
|
501
|
+
# on the root
|
502
|
+
load_from_env
|
503
|
+
end
|
504
|
+
|
505
|
+
config = Config.new
|
506
|
+
|
507
|
+
# customized
|
508
|
+
config.settings['qonfig']['QONFIG_BOOLEAN'] # => true ('true' => true)
|
509
|
+
config.settings['qonfig']['QONFIG_INTEGER'] # => 0 ('0' => 0)
|
510
|
+
config.settings['qonfig']['QONFIG_STRING'] # => 'none'
|
511
|
+
config.settings['qonfig']['QONFIG_ARRAY'] # => [1, 2.5, true, false, 'TEST']
|
512
|
+
config.settings['qonfig']['QONFIG_MESSAGE'] # => 'Hello, Qonfig!'
|
513
|
+
config.settings['qonfig']['RUN_CI'] # => Qonfig::UnknownSettingError
|
514
|
+
|
515
|
+
# trimmed (and customized)
|
516
|
+
config.settings['trimmed']['BOOLEAN'] # => true ('true' => true)
|
517
|
+
config.settings['trimmed']['INTEGER'] # => 0 ('0' => 0)
|
518
|
+
config.settings['trimmed']['STRING'] # => 'none'
|
519
|
+
config.settings['trimmed']['ARRAY'] # => [1, 2.5, true, false, 'TEST']
|
520
|
+
config.settings['trimmed']['MESSAGE'] # => 'Hello, Qonfig!'
|
521
|
+
config.settings['trimmed']['RUN_CI'] # => Qonfig::UnknownSettingError
|
522
|
+
|
523
|
+
# default
|
524
|
+
config.settings['QONFIG_BOOLEAN'] # => 'true'
|
525
|
+
config.settings['QONFIG_INTEGER'] # => '0'
|
526
|
+
config.settings['QONFIG_STRING'] # => 'none'
|
527
|
+
config.settings['QONFIG_ARRAY'] # => '1, 2.5, t, f, TEST'
|
528
|
+
config.settings['QONFIG_MESSAGE'] # => '"Hello, Qonfig!"'
|
529
|
+
config.settings['RUN_CI'] # => '1'
|
530
|
+
```
|
531
|
+
|
532
|
+
---
|
533
|
+
|
534
|
+
### Load from \_\_END\_\_
|
535
|
+
|
536
|
+
- aka `load_from_self`
|
537
|
+
|
538
|
+
```ruby
|
539
|
+
class Config < Qonfig::DataSet
|
540
|
+
load_from_self # on the root
|
541
|
+
|
542
|
+
setting :clowd do
|
543
|
+
load_from_self # nested
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
config = Config.new
|
548
|
+
|
549
|
+
# on the root
|
550
|
+
config.settings.ruby_version # => '2.5.1'
|
551
|
+
config.settings.secret_key # => 'top-mega-secret'
|
552
|
+
config.settings.api_host # => 'super.puper-google.com'
|
553
|
+
config.settings.connection_timeout.seconds # => 10
|
554
|
+
config.settings.connection_timeout.enabled # => false
|
555
|
+
|
556
|
+
# nested
|
557
|
+
config.settings.nested.ruby_version # => '2.5.1'
|
558
|
+
config.settings.nested.secret_key # => 'top-mega-secret'
|
559
|
+
config.settings.nested.api_host # => 'super.puper-google.com'
|
560
|
+
config.settings.nested.connection_timeout.seconds # => 10
|
561
|
+
config.settings.nested.connection_timeout.enabled # => false
|
562
|
+
|
563
|
+
__END__
|
564
|
+
|
565
|
+
ruby_version: <%= RUBY_VERSION %>
|
566
|
+
secret_key: top-mega-secret
|
567
|
+
api_host: super.puper-google.com
|
568
|
+
connection_timeout:
|
569
|
+
seconds: 10
|
570
|
+
enabled: false
|
571
|
+
```
|
572
|
+
|
573
|
+
---
|
574
|
+
|
575
|
+
### Smart Mixin
|
576
|
+
|
577
|
+
- class-level:
|
578
|
+
- `.configuration` - settings definitions;
|
579
|
+
- `.configure` - configuration;
|
580
|
+
- `.config` - config object;
|
581
|
+
- settings definitions are inheritable;
|
582
|
+
- instance-level:
|
583
|
+
- `#configure` - configuration;
|
584
|
+
- `#config` - config object;
|
585
|
+
|
586
|
+
```ruby
|
587
|
+
# --- usage ---
|
588
|
+
|
589
|
+
class Application
|
590
|
+
# make configurable
|
591
|
+
include Qonfig::Configurable
|
592
|
+
|
593
|
+
configuration do
|
594
|
+
setting :user
|
595
|
+
setting :password
|
596
|
+
end
|
597
|
+
end
|
598
|
+
|
599
|
+
app = Application.new
|
600
|
+
|
601
|
+
# class-level config
|
602
|
+
Application.config.settings.user # => nil
|
603
|
+
Application.config.settings.password # => nil
|
604
|
+
|
605
|
+
# instance-level config
|
606
|
+
app.config.settings.user # => nil
|
607
|
+
app.config.settings.password # => nil
|
608
|
+
|
609
|
+
# class-level configuration
|
610
|
+
Application.configure do |conf|
|
611
|
+
conf.user = '0exp'
|
612
|
+
conf.password = 'test123'
|
613
|
+
end
|
614
|
+
|
615
|
+
# instance-level configuration
|
616
|
+
app.configure do |conf|
|
617
|
+
conf.user = 'admin'
|
618
|
+
conf.password = '123test'
|
619
|
+
end
|
620
|
+
|
621
|
+
# class has own config object
|
622
|
+
Application.config.settings.user # => '0exp'
|
623
|
+
Application.config.settings.password # => 'test123'
|
624
|
+
|
625
|
+
# instance has own config object
|
626
|
+
app.config.settings.user # => 'admin'
|
627
|
+
app.config.settings.password # => '123test'
|
628
|
+
|
629
|
+
# and etc... (all Qonfig-related features)
|
630
|
+
```
|
631
|
+
|
632
|
+
```ruby
|
633
|
+
# --- inheritance ---
|
634
|
+
|
635
|
+
class BasicApplication
|
636
|
+
# make configurable
|
637
|
+
include Qonfig::Configurable
|
638
|
+
|
639
|
+
configuration do
|
640
|
+
setting :user
|
641
|
+
setting :pswd
|
642
|
+
end
|
643
|
+
|
644
|
+
configure do |conf|
|
645
|
+
conf.user = 'admin'
|
646
|
+
conf.pswd = 'admin'
|
647
|
+
end
|
648
|
+
end
|
649
|
+
|
650
|
+
class GeneralApplication < BasicApplication
|
651
|
+
# extend inherited definitions
|
652
|
+
configuration do
|
653
|
+
setting :db do
|
654
|
+
setting :adapter
|
655
|
+
end
|
656
|
+
end
|
657
|
+
|
658
|
+
configure do |conf|
|
659
|
+
conf.user = '0exp' # .user inherited from BasicApplication
|
660
|
+
conf.pswd = '123test' # .pswd inherited from BasicApplication
|
661
|
+
conf.db.adapter = 'pg'
|
662
|
+
end
|
663
|
+
end
|
664
|
+
|
665
|
+
BasicApplication.config.to_h
|
666
|
+
{ 'user' => 'admin', 'pswd' => 'admin' }
|
667
|
+
|
668
|
+
GeneralApplication.config.to_h
|
669
|
+
{ 'user' => '0exp', 'pswd' => '123test', 'db' => { 'adapter' => 'pg' } }
|
670
|
+
|
671
|
+
# and etc... (all Qonfig-related features)
|
672
|
+
```
|
673
|
+
|
674
|
+
---
|
675
|
+
|
676
|
+
## Contributing
|
677
|
+
|
678
|
+
- Fork it ( https://github.com/0exp/qonfig/fork )
|
679
|
+
- Create your feature branch (`git checkout -b feature/my-new-feature development`)
|
680
|
+
- Commit your changes (`git commit -am 'Add some feature'`)
|
681
|
+
- Push to the branch (`git push origin feature/my-new-feature`)
|
682
|
+
- Create new Pull Request
|
683
|
+
|
231
684
|
## License
|
232
685
|
|
233
686
|
Released under MIT License.
|
234
687
|
|
235
688
|
## Authors
|
236
689
|
|
237
|
-
Rustam Ibragimov.
|
690
|
+
[Rustam Ibragimov](https://github.com/0exp)
|