tty-config 0.2.0 → 0.3.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
- SHA1:
3
- metadata.gz: b7d2891f50d6ec7735ddf4c68e811d2b9726d5f1
4
- data.tar.gz: a4c6a91a265b84c849aa7be416eb0062d9253ff7
2
+ SHA256:
3
+ metadata.gz: 5f98bab385a665c7b78c6d94d82c4ba93c7f37354fcd801a87b7d4ca9f9cd14f
4
+ data.tar.gz: 62265adbaae3b68b9b73e590a1a06df502577d669c67be39a1425515c1f30482
5
5
  SHA512:
6
- metadata.gz: 2f735b5c715194df5873b78bee19062392effc855f712659ab3fc07cd6c87737eedcc79fbce15362ecbe473df226090a3d76c00c1438f0f522c265f742141c50
7
- data.tar.gz: 282c1817e5c73f18bf1be3c0b2c32d41d142a22a894ab5c528901bdfda0a573cbda9cfe74961b92dfe63ee91e89d89f2e06649cd4c208c7e85db47e226dd2ce5
6
+ metadata.gz: b6abcbe7ddc76d4856354221e6780ea0e502f28cd02bf79633d4584c05206d4629cf22cfd797a3457ffebc6454a3269a0481b34c5736005406cf6f334d101a2d
7
+ data.tar.gz: 9f423088aa20776fbe529ed554025887320a71c203c247f97e068a03c8a650ce48fa5d91feb4e9e831f368177305db9b8025c62475eda4959232652c77d9e9a4
@@ -1,5 +1,21 @@
1
1
  # Change log
2
2
 
3
+ ## [v0.3.0] - 2018-10-20
4
+
5
+ ### Added
6
+ * Add #set_from_env for binding keys to environment variables
7
+ * Add #env_prefix for setting environment variables prefix
8
+ * Add #autoload_env for loading all environment variables
9
+ * Add #generate for generating file content from the settings
10
+ * Add #alias_setting for aliasing settings
11
+ * Add ability to read & write INI file types
12
+
13
+ ### Changed
14
+ * Change #fetch to read environment variables before defaults
15
+ * Change #fetch to handle aliased settings
16
+ * Change to remove stdout output when dependency cannot be loaded
17
+ * Change to allow for config files without any extension
18
+
3
19
  ## [v0.2.0] - 2018-05-07
4
20
 
5
21
  ### Added
@@ -12,5 +28,6 @@
12
28
 
13
29
  * Initial implementation and release
14
30
 
31
+ [v0.3.0]: https://github.com/piotrmurach/tty-config/compare/v0.2.0...v0.3.0
15
32
  [v0.2.0]: https://github.com/piotrmurach/tty-config/compare/v0.1.0...v0.2.0
16
33
  [v0.1.0]: https://github.com/piotrmurach/tty-config/compare/v0.1.0
data/README.md CHANGED
@@ -1,3 +1,7 @@
1
+ <div align="center">
2
+ <a href="https://piotrmurach.github.io/tty" target="_blank"><img width="130" src="https://cdn.rawgit.com/piotrmurach/tty/master/images/tty.png" alt="tty logo" /></a>
3
+ </div>
4
+
1
5
  # TTY::Config [![Gitter](https://badges.gitter.im/Join%20Chat.svg)][gitter]
2
6
 
3
7
  [![Gem Version](https://badge.fury.io/rb/tty-config.svg)][gem]
@@ -21,9 +25,11 @@
21
25
 
22
26
  ## Features
23
27
 
24
- * Read & write configurations in YAML, JSON, TOML formats
25
- * Simple interface for setting and fetching values for deeply nested keys
26
- * Merging of configuration options from other hashes
28
+ * Read & write configurations in YAML, JSON, TOML, INI formats
29
+ * Simple interface for adding and reading settings for deeply nested keys
30
+ * Indifferent access for reading settings
31
+ * Merging of configuration settings from other hashes
32
+ * Reading values from environment variables
27
33
 
28
34
  ## Installation
29
35
 
@@ -48,20 +54,27 @@ Or install it yourself as:
48
54
  * [2. Interface](#2-interface)
49
55
  * [2.1 set](#21-set)
50
56
  * [2.2 set_if_empty](#22-set_if_empty)
51
- * [2.3 fetch](#23-fetch)
52
- * [2.4 merge](#24-merge)
53
- * [2.5 coerce](#25-coerce)
54
- * [2.6 append](#26-append)
55
- * [2.7 remove](#27-remove)
56
- * [2.8 delete](#28-delete)
57
- * [2.9 validate](#29-validate)
58
- * [2.10 filename=](#210-filename)
59
- * [2.11 extname=](#211-extname)
60
- * [2.12 append_path](#212-append_path)
61
- * [2.13 prepend_path](#213-prepend_path)
62
- * [2.14 read](#214-read)
63
- * [2.15 write](#215-write)
64
- * [2.16 persisted?](#216-persisted)
57
+ * [2.3 set_from_env](#23-set_from_env)
58
+ * [2.4 fetch](#24-fetch)
59
+ * [2.5 merge](#25-merge)
60
+ * [2.6 coerce](#26-coerce)
61
+ * [2.7 append](#27-append)
62
+ * [2.8 remove](#28-remove)
63
+ * [2.9 delete](#29-delete)
64
+ * [2.10 alias_setting](#210-alias_setting)
65
+ * [2.11 validate](#211-validate)
66
+ * [2.12 env_prefix=](#212-env_prefix)
67
+ * [2.13 filename=](#213-filename)
68
+ * [2.14 extname=](#214-extname)
69
+ * [2.15 append_path](#215-append_path)
70
+ * [2.16 prepend_path](#216-prepend_path)
71
+ * [2.17 read](#217-read)
72
+ * [2.18 write](#218-write)
73
+ * [2.19 exist?](#219-exist)
74
+ * [2.20 autoload_env](#220-autoload_env)
75
+ * [3. Examples](#3-examples)
76
+ * [3.1 Working with env vars](#31-working-with-env-vars)
77
+ * [3.2 Working with optparse](#32-working-with-optparse)
65
78
 
66
79
  ## 1. Usage
67
80
 
@@ -184,7 +197,61 @@ Similar to `set` it allows you to specify arbitrary sequence of keys followed by
184
197
  config.set_if_empty :settings, :base, value: 'USD'
185
198
  ```
186
199
 
187
- ### 2.3 fetch
200
+ ### 2.3 set_from_env
201
+
202
+ To read configuration options from environment variables use `set_from_env`. At minimum it requires a single argument which will match the name of `ENV` variable. The name of this parameter is case insensitive.
203
+
204
+ Given the following environment variables:
205
+
206
+ ```ruby
207
+ ENV['HOST'] = '192.168.1.17'
208
+ ENV['PORT'] = '7727'
209
+ ```
210
+
211
+ You can make the config aware of the above env variables:
212
+
213
+ ```ruby
214
+ config.set_from_env(:host)
215
+ config.set_from_env(:port)
216
+ ```
217
+
218
+ Then you can retrieve values like any other configuration option:
219
+
220
+ ```ruby
221
+ config.fetch(:host)
222
+ # => '192.168.1.17'
223
+ config.fetch(:port)
224
+ # => '7727'
225
+ ```
226
+
227
+ If you want the configuration key name to be different from `ENV` variable name use a block:
228
+
229
+ ```ruby
230
+ config.set_from_env(:host) { 'HOSTNAME' }
231
+ config.set_from_env(:host) { :hostname }
232
+ ```
233
+
234
+ You can also configure settings for deeply nested keys:
235
+
236
+ ```ruby
237
+ config.set_from_env(:settings, :base) { 'CURRENCY' }
238
+ config.set_from_env(:settings, :base) { :currency }
239
+ config.set_from_env('settings.base') { 'CURRENCY'}
240
+ config.set_from_env('settings.base') { :currency}
241
+ ```
242
+
243
+ And asssuming `ENV['CURRENCY']=USD`:
244
+
245
+ ```ruby
246
+ config.fetch(:settings, :base)
247
+ # => USD
248
+ ```
249
+
250
+ You can also prefix your environment variables. See [env_prefix=](#212-env_prefix)
251
+
252
+ It's important to recognise that `set_from_env` doesn't record the value for the environment variables. They are read each time from the `ENV` when `fetch` is called.
253
+
254
+ ### 2.4 fetch
188
255
 
189
256
  To get a configuration setting use `fetch`, which can accept default value either with a `:default` keyword or a block that will be lazy evaluated:
190
257
 
@@ -214,7 +281,7 @@ config.fetch(:settings', 'base')
214
281
  config.fetch('settings', :base)
215
282
  ```
216
283
 
217
- ### 2.4 merge
284
+ ### 2.5 merge
218
285
 
219
286
  To merge in other configuration settings as hash use `merge`:
220
287
 
@@ -230,7 +297,7 @@ config.fetch(:a, :d) # => 4
230
297
 
231
298
  Internally all configuration settings are stored as string keys for ease of working with file values and command line applications inputs.
232
299
 
233
- ### 2.5 coerce
300
+ ### 2.6 coerce
234
301
 
235
302
  You can initialize configuration based on a hash, with all the keys converted to symbols:
236
303
 
@@ -242,7 +309,7 @@ config.to_h
242
309
  # {settings: {base: "USD", exchange: "CCCAGG"}}
243
310
  ```
244
311
 
245
- ### 2.6 append
312
+ ### 2.7 append
246
313
 
247
314
  To append arbitrary number of values to a value under a given key use `append`:
248
315
 
@@ -264,7 +331,7 @@ config.append("EUR", "GBP", to: [:settings, :bases])
264
331
  # {settings: {bases: ["USD", "EUR", "GBP"]}}
265
332
  ```
266
333
 
267
- ### 2.7 remove
334
+ ### 2.8 remove
268
335
 
269
336
  Use `remove` to remove a set of values from a key.
270
337
 
@@ -286,12 +353,12 @@ config.remove("TRX", "DASH", from: [:holdings, :coins])
286
353
  # ["BTC", "ETH"]
287
354
  ```
288
355
 
289
- ### 2.8 delete
356
+ ### 2.9 delete
290
357
 
291
358
  To completely delete a value and corresponding key use `delete`:
292
359
 
293
360
  ```ruby
294
- config.set(:base, "USD")
361
+ config.set(:base, value: "USD")
295
362
  config.delete(:base)
296
363
  # =>
297
364
  # "USD"
@@ -300,13 +367,58 @@ config.delete(:base)
300
367
  You can also delete deeply nested keys and their values:
301
368
 
302
369
  ```ruby
303
- config.set(:settings, :base, "USD")
370
+ config.set(:settings, :base, value: "USD")
304
371
  config.delete(:settings, :base)
305
372
  # =>
306
373
  # "USD"
307
374
  ```
308
375
 
309
- ### 2.9 validate
376
+ ### 2.10 alias_setting
377
+
378
+ In order to alias a configuration setting to another name use `alias_setting`.
379
+
380
+ For example, given an already existing setting:
381
+
382
+ ```ruby
383
+ config.set(:base, value: 'baz')
384
+ ```
385
+
386
+ You can alias it to another name:
387
+
388
+ ```ruby
389
+ config.alias_setting(:base, to: :currency)
390
+ ```
391
+
392
+ And then access like any other configuration setting:
393
+
394
+ ```ruby
395
+ config.fetch(:currency)
396
+ # => 'USD'
397
+ ```
398
+
399
+ Deep nested configuration options are also supported:
400
+
401
+ ```ruby
402
+ config.set(:settings, :base, value: 'USD')
403
+ ```
404
+
405
+ And then can be aliased like so:
406
+
407
+ ```ruby
408
+ config.alias_setting(:settings, :base, to: [:settings, :currency])
409
+ config.alias_setting('settings.base', to [:settings, :currency])
410
+ ```
411
+
412
+ You can then access the deep nested settings:
413
+
414
+ ```ruby
415
+ config.fetch(:settings, :currency)
416
+ # => 'USD'
417
+ config.fetch('settings.currency')
418
+ # => 'USD'
419
+ ```
420
+
421
+ ### 2.11 validate
310
422
 
311
423
  To ensure consistency of the data, you can validate values being set at arbitrarily deep keys using `validate` method, that takes an arbitrarily nested key as its argument and a validation block.
312
424
 
@@ -335,7 +447,38 @@ config.fetch(:settings, :base)
335
447
  # raises TTY::Config::ValidationError, 'Currency code needs to be 3 chars long.'
336
448
  ```
337
449
 
338
- ### 2.10 filename=
450
+ ### 2.12 env_prefix=
451
+
452
+ Given the following variables:
453
+
454
+ ```ruby
455
+ ENV['MYTOOL_HOST'] = '192.168.1.17'
456
+ ENV['MYTOOL_PORT'] = ' 7727'
457
+ ```
458
+
459
+ You can inform configuration about common prefix using `env_prefix`:
460
+
461
+ ```ruby
462
+ config.env_prefix = 'mytool'
463
+ ```
464
+
465
+ Then set configuration key name to environment variable name:
466
+
467
+ ```ruby
468
+ config.set_from_env(:host)
469
+ config.set_from_env(:port)
470
+ ```
471
+
472
+ And finally retrieve the value:
473
+
474
+ ```ruby
475
+ config.fetch(:host)
476
+ #=> '192.168.1.17'
477
+ config.fetch(:port)
478
+ # => '7727'
479
+ ```
480
+
481
+ ### 2.13 filename=
339
482
 
340
483
  By default, **TTY::Config** searches for `config` named configuration file. To change this use `filename=` method without the extension name:
341
484
 
@@ -345,7 +488,7 @@ config.filename = 'investments'
345
488
 
346
489
  Then any supported extensions will be search for such as `.yml`, `.json` and `.toml`.
347
490
 
348
- ### 2.11 extname=
491
+ ### 2.14 extname=
349
492
 
350
493
  By default '.yml' extension is used to write configuration out to a file but you can change that with `extname=`:
351
494
 
@@ -353,7 +496,7 @@ By default '.yml' extension is used to write configuration out to a file but you
353
496
  config.extname = '.toml'
354
497
  ```
355
498
 
356
- ### 2.12 append_path
499
+ ### 2.15 append_path
357
500
 
358
501
  You need to tell the **TTY::Config** where to search for configuration files. To search multiple paths for a configuration file use `append_path` or `prepend_path` methods.
359
502
 
@@ -367,7 +510,7 @@ config.append_path(Dir.pwd) # look in current working directory
367
510
 
368
511
  None of these paths are required, but you should provide at least one path if you wish to read configuration file.
369
512
 
370
- ### 2.13 prepend_path
513
+ ### 2.16 prepend_path
371
514
 
372
515
  The `prepend_path` allows you to add configuration search paths that should be searched first.
373
516
 
@@ -376,11 +519,20 @@ config.append_path(Dir.pwd) # look in current working directory second
376
519
  config.prepend_path(Dir.home) # look in user's home directory first
377
520
  ```
378
521
 
379
- ### 2.14 read
522
+ ### 2.17 read
523
+
524
+ There are two ways for reading configuration files and both use the `read` method. One attempts to guess extension and format of your data, the other allows you to request specific extension and format.
525
+
526
+ Currently the supported file formats are:
527
+
528
+ * `yaml` for `.yaml`, `.yml` extensions
529
+ * `json` for `.json` extension
530
+ * `toml` for `.toml` extension
531
+ * `ini` for `.ini`, `.cnf`, `.conf`, `.cfg`, `.cf extensions`
380
532
 
381
- There are two ways for reading configuration files and both use the `read` method.
533
+ Calling `read` without any arguments searches through provided locations to find configuration file and reads it. Therefore, you need to specify at least one search path that contains the configuration file together with actual filename. When filename is specifed then all known extensions will be tried.
382
534
 
383
- First one, searches through provided locations to find configuration file and read it. Therefore, you need to specify at least one search path that contains the configuration file.
535
+ For example, to find file called investments in the current directory do:
384
536
 
385
537
  ```ruby
386
538
  config.append_path(Dir.pwd) # look in current working directory
@@ -393,13 +545,21 @@ Find and read the configuration file:
393
545
  config.read
394
546
  ```
395
547
 
396
- However, you can also specify directly the file to read without setting up any search paths or filenames:
548
+ You can also specify directly the file to read without setting up any search paths or filenames. If you specify a configuration with a known file extension, an appropriate format will be guessed, in this instance `TOML`:
397
549
 
398
550
  ```ruby
399
551
  config.read('./investments.toml')
400
552
  ```
401
553
 
402
- ### 2.15 write
554
+ In cases where you wish to specify a custom file extension, you will need to also specify the file format to use.
555
+
556
+ For example, if you have a configuration file formatted using `YAML` notation with extension called `.config`, to read it do:
557
+
558
+ ```ruby
559
+ config.read('investments.config', format: :yaml)
560
+ ```
561
+
562
+ ### 2.18 write
403
563
 
404
564
  By default **TTY::Config**, persists configuration file in the current working directory with a `config.yml` name. However, you can change that by specifying the filename and extension type:
405
565
 
@@ -429,12 +589,146 @@ config.write(force: true) # overwrite any found config fi
429
589
  config.write('./investments.toml', force: true) # overwrite specific config file
430
590
  ```
431
591
 
432
- ### 2.16 persisted?
592
+ ### 2.19 exist?
593
+
594
+ To check if a configuration file exists within the configured search paths use `exist?` method:
595
+
596
+ ```ruby
597
+ config.exist? # => true
598
+ ```
599
+
600
+ ### 2.20 autoload_env
601
+
602
+ The `autload_env` allows you to automatically read environment variables. In most cases you would combine it with [env_prefix=](#212-env_prefix) to only read a subset of variables. When using `autload_env`, anytime the `fetch` is called a corresponding enviornment variable will be checked.
603
+
604
+ For example, given an evironment variable `MYTOOL_HOST` set to `localhost`:
605
+
606
+ ```ruby
607
+ ENV['MYTOOL_HOST']=localhost
608
+ ```
609
+
610
+ And loading environment variables with a prefix of `MYTOOL`:
611
+
612
+ ```ruby
613
+ config.env_prefix = 'mytool'
614
+ config.autoload_env
615
+ ```
616
+
617
+ You can retrieve value with:
618
+
619
+ ```ruby
620
+ config.fetch(:host)
621
+ # => 'localhost'
622
+ ```
623
+
624
+ ## 3. Examples
625
+
626
+ ### 3.1 Working with env vars
627
+
628
+ *TTY::Config* fully supports working with environment variables. For example, there are couple of environment variables that your configuration is interested in, which normally would be set in terminal but for the sake of this example we assign them:
629
+
630
+ ```ruby
631
+ ENV['MYTOOL_HOST'] = '192.168.1.17'
632
+ ENV['MYTOOL_PORT'] = '7727'
633
+ ```
634
+
635
+ Then in order to make your configuration aware of the above, you would use [env_prefix=](#212-env_prefix) and [set_from_env](#23-set_from_env):
636
+
637
+ ```ruby
638
+ config.env_prefix = 'mytool'
639
+ config.set_from_env(:host)
640
+ config.set_from_env(:port)
641
+ ```
642
+
643
+ or automatically load all prefixed environment variables with [autoload_env](#220-autoload-env):
644
+
645
+ ```ruby
646
+ config.env_prefix = 'mytool'
647
+ config.autoload_env
648
+ ```
649
+
650
+ And then retrieve values with [fetch](#24-fetch):
651
+
652
+ ```ruby
653
+ config.fetch(:host)
654
+ #=> '192.168.1.17'
655
+ config.fetch(:port)
656
+ # => '7727'
657
+ ```
658
+
659
+ ### 3.2 Working with optparse
660
+
661
+ This is an example of combining `tty-config` with `optparse` stdlib.
662
+
663
+ Let's assume you want to create a command line tool that among many options accepts `--host|-h` and `--port|-p` flags. In addition, these flags will take precedence over the options specified in the configuration file.
664
+
665
+ First, you need to parse the flags and store results away in options hash:
666
+
667
+ ```ruby
668
+ require 'optparse'
669
+
670
+ options = {}
671
+
672
+ option_parser = OptionParser.new do |opts|
673
+ opts.on("-h", "--host HOSTNAME_OR_IP", "Hostname or IP Adress") do |h|
674
+ options[:host] = h
675
+ end
676
+ opts.on("-p", "--port PORT", "Port of application", Integer) do |p|
677
+ options[:port] = p
678
+ end
679
+ opts.on("-c", "--config FILE",
680
+ "Read config values from file (defaults: ./config.yml, ~/.config.yml") do |c|
681
+ options[:config_file_path] = c
682
+ end
683
+ ...
684
+ end
685
+
686
+ option_parser.parse!
687
+ ```
688
+
689
+ Then, you craete a configuration instance:
690
+
691
+ ```ruby
692
+ config = TTY::Config.new
693
+ ```
694
+
695
+ And setup config filename:
696
+
697
+ ```ruby
698
+ config_filename = options[:config_file_path] || 'config.yml'
699
+ ```
700
+
701
+ As well as add configuration file locations to search in:
702
+
703
+ ```ruby
704
+ config.append_path Dir.pwd
705
+ config.append_path Dir.home
706
+ ```
707
+
708
+ Once config is initialized, you can read the configuration from a config file:
709
+
710
+ ```ruby
711
+ begin
712
+ config.read(config_filename) # by default the 'config.yml' is read
713
+ rescue TTY::Config::ReadError => read_error
714
+ STDERR.puts "\nNo configuration file found:"
715
+ STDERR.puts read_error
716
+ end
717
+ ```
718
+
719
+ Then merge options passed as arguments with those stored in a configuration file:
433
720
 
434
- To check if a configuration file exists within the configured search paths use `persisted?` method:
721
+ ```ruby
722
+ config.merge(options)
723
+ ```
724
+
725
+ Provide optional validation to ensure both host and port are configured:
435
726
 
436
727
  ```ruby
437
- config.persisted? # => true
728
+ if !config.fetch(:host) || !config.fetch(:port)
729
+ STDERR.puts "Host and port have to be specified (call with --help for help)."
730
+ exit 1
731
+ end
438
732
  ```
439
733
 
440
734
  ## Development