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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d774926f0d94544e9d256b7c3e06bbc51b16a51a1323fbcb1f020a1c377ffaf7
4
- data.tar.gz: a3d2769d42ba24938db56bd853f65b041a7053af462644a6d4e3ac3109c3b121
3
+ metadata.gz: 364dfdc09c159ed886729491cc0d066f961b5be382b766d99d57705fca5f88d7
4
+ data.tar.gz: 9525458cf3d84fa9588ab48805cdb8a5ec0150278a7658986fb6325efcd2d191
5
5
  SHA512:
6
- metadata.gz: 82ac7dd98fdccf5ab5ba846a9c733fbb8e3523676a23b390aca49c587e01b1cf9c76602d5909cda2736c7e4d572ffe219b85e3f7267f4499051c579a5bf59997
7
- data.tar.gz: 747f86b8b8f8f2a348ae906e0e3e75a37f45afd896874ee1eb56aa7b66ee6a4c4581d48fbbe3d7d203879c345ff0894ca780f12a5bcbd660b421f7e202c29028
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: 17
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.1.0] - 2018-05-xx
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 &middot; [![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 &middot; [![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 # => 'api.service.com'
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] # => 'api.service.com'
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 block
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: :memory_sync
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: { engine: :ok },
205
- hash: { engine: :native },
229
+ "serializers": {
230
+ "json" => { "engine" => :ok },
231
+ "hash" => { "engine" => :native },
206
232
  },
207
- adapter: { default: :memory_sync },
208
- logger: #<Logger:0x4b0d79fc>
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)