tty-config 0.3.1 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +50 -1
- data/LICENSE.txt +1 -1
- data/README.md +305 -153
- data/lib/tty/config/dependency_loader.rb +55 -0
- data/lib/tty/config/generator.rb +57 -0
- data/lib/tty/config/marshaller.rb +66 -0
- data/lib/tty/config/marshaller_registry.rb +45 -0
- data/lib/tty/config/marshallers/hcl_marshaller.rb +30 -0
- data/lib/tty/config/marshallers/ini_marshaller.rb +31 -0
- data/lib/tty/config/marshallers/java_props_marshaller.rb +28 -0
- data/lib/tty/config/marshallers/json_marshaller.rb +28 -0
- data/lib/tty/config/marshallers/toml_marshaller.rb +28 -0
- data/lib/tty/config/marshallers/yaml_marshaller.rb +32 -0
- data/lib/tty/config/marshallers.rb +35 -0
- data/lib/tty/config/version.rb +3 -3
- data/lib/tty/config.rb +374 -190
- data/lib/tty-config.rb +1 -1
- metadata +66 -57
- data/Rakefile +0 -8
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/spec/spec_helper.rb +0 -54
- data/spec/unit/alias_setting_spec.rb +0 -72
- data/spec/unit/append_spec.rb +0 -26
- data/spec/unit/autoload_env_spec.rb +0 -62
- data/spec/unit/delete_spec.rb +0 -22
- data/spec/unit/exist_spec.rb +0 -24
- data/spec/unit/fetch_spec.rb +0 -45
- data/spec/unit/generate_spec.rb +0 -70
- data/spec/unit/merge_spec.rb +0 -13
- data/spec/unit/new_spec.rb +0 -6
- data/spec/unit/normalize_hash_spec.rb +0 -21
- data/spec/unit/read_spec.rb +0 -109
- data/spec/unit/remove_spec.rb +0 -16
- data/spec/unit/set_from_env_spec.rb +0 -78
- data/spec/unit/set_if_empty_spec.rb +0 -26
- data/spec/unit/set_spec.rb +0 -62
- data/spec/unit/validate_spec.rb +0 -76
- data/spec/unit/write_spec.rb +0 -197
- data/tasks/console.rake +0 -11
- data/tasks/coverage.rake +0 -11
- data/tasks/spec.rake +0 -29
- data/tty-config.gemspec +0 -30
data/README.md
CHANGED
@@ -1,42 +1,46 @@
|
|
1
1
|
<div align="center">
|
2
|
-
<a href="https://
|
2
|
+
<a href="https://ttytoolkit.org"><img width="130" src="https://github.com/piotrmurach/tty/raw/master/images/tty.png" alt="TTY Toolkit logo" /></a>
|
3
3
|
</div>
|
4
4
|
|
5
5
|
# TTY::Config [![Gitter](https://badges.gitter.im/Join%20Chat.svg)][gitter]
|
6
6
|
|
7
7
|
[![Gem Version](https://badge.fury.io/rb/tty-config.svg)][gem]
|
8
|
-
[![
|
8
|
+
[![Actions CI](https://github.com/piotrmurach/tty-config/workflows/CI/badge.svg?branch=master)][gh_actions_ci]
|
9
9
|
[![Build status](https://ci.appveyor.com/api/projects/status/2383i0dn3hlw9cnn?svg=true)][appveyor]
|
10
10
|
[![Maintainability](https://api.codeclimate.com/v1/badges/dfac05073e1549e9dbb6/maintainability)][codeclimate]
|
11
11
|
[![Coverage Status](https://coveralls.io/repos/github/piotrmurach/tty-config/badge.svg)][coverage]
|
12
|
-
[![Inline docs](
|
12
|
+
[![Inline docs](https://inch-ci.org/github/piotrmurach/tty-config.svg?branch=master)][inchpages]
|
13
13
|
|
14
14
|
[gitter]: https://gitter.im/piotrmurach/tty
|
15
|
-
[gem]:
|
16
|
-
[
|
15
|
+
[gem]: https://badge.fury.io/rb/tty-config
|
16
|
+
[gh_actions_ci]: https://github.com/piotrmurach/tty-config/actions?query=workflow%3ACI
|
17
17
|
[appveyor]: https://ci.appveyor.com/project/piotrmurach/tty-config
|
18
18
|
[codeclimate]: https://codeclimate.com/github/piotrmurach/tty-config/maintainability
|
19
19
|
[coverage]: https://coveralls.io/github/piotrmurach/tty-config
|
20
|
-
[inchpages]:
|
20
|
+
[inchpages]: https://inch-ci.org/github/piotrmurach/tty-config
|
21
21
|
|
22
|
-
>
|
22
|
+
> A highly customisable application configuration interface for building terminal tools.
|
23
23
|
|
24
|
-
**TTY::Config** provides
|
24
|
+
**TTY::Config** provides application configuration component for [TTY](https://github.com/piotrmurach/tty) toolkit.
|
25
25
|
|
26
26
|
## Features
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
*
|
31
|
-
*
|
32
|
-
*
|
28
|
+
This is a one-stop shop for all your configuration needs:
|
29
|
+
|
30
|
+
* [Read](#216-read) and [write](#217-write) config files in YAML, JSON, TOML, INI, HCL and Java Properties formats
|
31
|
+
* Add [custom marshallers](#222-register_marshaller) or override the built-in ones
|
32
|
+
* [Set](#21-set) and [read](#24-fetch) settings for deeply nested keys
|
33
|
+
* [Set](#21-set) defaults for undefined settings
|
34
|
+
* [Read](#24-fetch) settings with indifferent access
|
35
|
+
* [Merge](#25-merge) configuration settings from other hash objects
|
36
|
+
* Read values from [environment variables](#23-set_from_env)
|
33
37
|
|
34
38
|
## Installation
|
35
39
|
|
36
40
|
Add this line to your application's Gemfile:
|
37
41
|
|
38
42
|
```ruby
|
39
|
-
gem
|
43
|
+
gem "tty-config"
|
40
44
|
```
|
41
45
|
|
42
46
|
And then execute:
|
@@ -63,15 +67,18 @@ Or install it yourself as:
|
|
63
67
|
* [2.9 delete](#29-delete)
|
64
68
|
* [2.10 alias_setting](#210-alias_setting)
|
65
69
|
* [2.11 validate](#211-validate)
|
66
|
-
* [2.12
|
67
|
-
* [2.13
|
68
|
-
* [2.14
|
69
|
-
* [2.15
|
70
|
-
* [2.16
|
71
|
-
* [2.17
|
72
|
-
* [2.18
|
73
|
-
* [2.19
|
74
|
-
* [2.20
|
70
|
+
* [2.12 filename=](#212-filename)
|
71
|
+
* [2.13 extname=](#213-extname)
|
72
|
+
* [2.14 append_path](#214-append_path)
|
73
|
+
* [2.15 prepend_path](#215-prepend_path)
|
74
|
+
* [2.16 read](#216-read)
|
75
|
+
* [2.17 write](#217-write)
|
76
|
+
* [2.18 exist?](#218-exist)
|
77
|
+
* [2.19 env_prefix=](#219-env_prefix)
|
78
|
+
* [2.20 env_separator=](#220-env_separator)
|
79
|
+
* [2.21 autoload_env](#221-autoload_env)
|
80
|
+
* [2.22 register_marshaller](#222-register_marshaller)
|
81
|
+
* [2.23 unregister_marshaller](#223-unregister_marshaller)
|
75
82
|
* [3. Examples](#3-examples)
|
76
83
|
* [3.1 Working with env vars](#31-working-with-env-vars)
|
77
84
|
* [3.2 Working with optparse](#32-working-with-optparse)
|
@@ -82,30 +89,30 @@ Initialize the configuration and provide the name:
|
|
82
89
|
|
83
90
|
```ruby
|
84
91
|
config = TTY::Config.new
|
85
|
-
config.filename =
|
92
|
+
config.filename = "investments"
|
86
93
|
```
|
87
94
|
|
88
|
-
|
95
|
+
Then configure values for different nested keys with `set` and `append`:
|
89
96
|
|
90
97
|
```ruby
|
91
|
-
config.set(:settings, :base, value:
|
98
|
+
config.set(:settings, :base, value: "USD")
|
92
99
|
config.set(:settings, :color, value: true)
|
93
|
-
config.set(:coins, value: [
|
100
|
+
config.set(:coins, value: ["BTC"])
|
94
101
|
|
95
|
-
config.append(
|
102
|
+
config.append("ETH", "TRX", "DASH", to: :coins)
|
96
103
|
```
|
97
104
|
|
98
|
-
get any value by using `fetch`:
|
105
|
+
You can get any value by using `fetch`:
|
99
106
|
|
100
107
|
```ruby
|
101
108
|
config.fetch(:settings, :base)
|
102
|
-
# =>
|
109
|
+
# => "USD"
|
103
110
|
|
104
111
|
config.fetch(:coins)
|
105
|
-
# => [
|
112
|
+
# => ["BTC", "ETH", "TRX", "DASH"]
|
106
113
|
```
|
107
114
|
|
108
|
-
|
115
|
+
And call `write` to persist the configuration to `investments.yml` file:
|
109
116
|
|
110
117
|
```ruby
|
111
118
|
config.write
|
@@ -121,14 +128,14 @@ config.write
|
|
121
128
|
# - DASH
|
122
129
|
```
|
123
130
|
|
124
|
-
|
131
|
+
To read an `investments.yml` file, you need to provide the locations to search in:
|
125
132
|
|
126
133
|
```ruby
|
127
134
|
config.append_path Dir.pwd
|
128
135
|
config.append_path Dir.home
|
129
136
|
```
|
130
137
|
|
131
|
-
Finally, read
|
138
|
+
Finally, call `read` to convert configuration file back into an object again:
|
132
139
|
|
133
140
|
```ruby
|
134
141
|
config.read
|
@@ -144,8 +151,8 @@ class App
|
|
144
151
|
|
145
152
|
def initialize
|
146
153
|
@config = TTY::Config.new
|
147
|
-
@config.filename =
|
148
|
-
@config.extname =
|
154
|
+
@config.filename = "investments"
|
155
|
+
@config.extname = ".toml"
|
149
156
|
@config.append_path Dir.pwd
|
150
157
|
@config.append_path Dir.home
|
151
158
|
end
|
@@ -163,22 +170,22 @@ end
|
|
163
170
|
To set configuration setting use `set` method. It accepts any number of keys and value by either using `:value` keyword argument or passing a block:
|
164
171
|
|
165
172
|
```ruby
|
166
|
-
config.set(:base, value:
|
167
|
-
config.set(:base) {
|
173
|
+
config.set(:base, value: "USD")
|
174
|
+
config.set(:base) { "USD" }
|
168
175
|
```
|
169
176
|
|
170
|
-
The block version of specifying a value will mean that the value is evaluated every time
|
177
|
+
The block version of specifying a value will mean that the value is evaluated every time it's being read.
|
171
178
|
|
172
179
|
You can also specify deeply nested configuration settings by passing sequence of keys:
|
173
180
|
|
174
181
|
```ruby
|
175
|
-
config.set
|
182
|
+
config.set(:settings, :base, value: "USD")
|
176
183
|
```
|
177
184
|
|
178
|
-
is equivalent to:
|
185
|
+
Which is equivalent to:
|
179
186
|
|
180
187
|
```ruby
|
181
|
-
config.set
|
188
|
+
config.set("settings.base", value: "USD")
|
182
189
|
```
|
183
190
|
|
184
191
|
Internally all configuration settings are stored as string keys for ease of working with configuration files and command line application's inputs.
|
@@ -188,13 +195,13 @@ Internally all configuration settings are stored as string keys for ease of work
|
|
188
195
|
To set a configuration setting only if it hasn't been set before use `set_if_empty`:
|
189
196
|
|
190
197
|
```ruby
|
191
|
-
config.set_if_empty
|
198
|
+
config.set_if_empty(:base, value: "USD")
|
192
199
|
```
|
193
200
|
|
194
201
|
Similar to `set` it allows you to specify arbitrary sequence of keys followed by a key value or block:
|
195
202
|
|
196
203
|
```ruby
|
197
|
-
config.set_if_empty
|
204
|
+
config.set_if_empty(:settings, :base, value: "USD")
|
198
205
|
```
|
199
206
|
|
200
207
|
### 2.3 set_from_env
|
@@ -204,8 +211,8 @@ To read configuration options from environment variables use `set_from_env`. At
|
|
204
211
|
Given the following environment variables:
|
205
212
|
|
206
213
|
```ruby
|
207
|
-
ENV[
|
208
|
-
ENV[
|
214
|
+
ENV["HOST"] = "192.168.1.17"
|
215
|
+
ENV["PORT"] = "7727"
|
209
216
|
```
|
210
217
|
|
211
218
|
You can make the config aware of the above env variables:
|
@@ -219,35 +226,35 @@ Then you can retrieve values like any other configuration option:
|
|
219
226
|
|
220
227
|
```ruby
|
221
228
|
config.fetch(:host)
|
222
|
-
# =>
|
229
|
+
# => "192.168.1.17"
|
223
230
|
config.fetch(:port)
|
224
|
-
# =>
|
231
|
+
# => "7727"
|
225
232
|
```
|
226
233
|
|
227
234
|
If you want the configuration key name to be different from `ENV` variable name use a block:
|
228
235
|
|
229
236
|
```ruby
|
230
|
-
config.set_from_env(:host) {
|
237
|
+
config.set_from_env(:host) { "HOSTNAME" }
|
231
238
|
config.set_from_env(:host) { :hostname }
|
232
239
|
```
|
233
240
|
|
234
241
|
You can also configure settings for deeply nested keys:
|
235
242
|
|
236
243
|
```ruby
|
237
|
-
config.set_from_env(:settings, :base) {
|
244
|
+
config.set_from_env(:settings, :base) { "CURRENCY" }
|
238
245
|
config.set_from_env(:settings, :base) { :currency }
|
239
|
-
config.set_from_env(
|
240
|
-
config.set_from_env(
|
246
|
+
config.set_from_env("settings.base") { "CURRENCY" }
|
247
|
+
config.set_from_env("settings.base") { :currency }
|
241
248
|
```
|
242
249
|
|
243
|
-
And
|
250
|
+
And assuming `ENV["CURRENCY"]=USD`:
|
244
251
|
|
245
252
|
```ruby
|
246
253
|
config.fetch(:settings, :base)
|
247
254
|
# => USD
|
248
255
|
```
|
249
256
|
|
250
|
-
You can also prefix your environment variables
|
257
|
+
You can also prefix your environment variables with [env_prefix=](#219-env_prefix) or use a different separator with [env_separator](#220-env_separator).
|
251
258
|
|
252
259
|
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
260
|
|
@@ -256,8 +263,8 @@ It's important to recognise that `set_from_env` doesn't record the value for the
|
|
256
263
|
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:
|
257
264
|
|
258
265
|
```ruby
|
259
|
-
config.fetch(:base, default:
|
260
|
-
config.fetch(:base) {
|
266
|
+
config.fetch(:base, default: "USD")
|
267
|
+
config.fetch(:base) { "USD" }
|
261
268
|
```
|
262
269
|
|
263
270
|
Similar to `set` operation, `fetch` allows you to retrieve deeply nested values:
|
@@ -266,19 +273,19 @@ Similar to `set` operation, `fetch` allows you to retrieve deeply nested values:
|
|
266
273
|
config.fetch(:settings, :base) # => USD
|
267
274
|
```
|
268
275
|
|
269
|
-
is equivalent to:
|
276
|
+
Which is equivalent to:
|
270
277
|
|
271
278
|
```ruby
|
272
|
-
config.fetch(
|
279
|
+
config.fetch("settings.base")
|
273
280
|
```
|
274
281
|
|
275
282
|
`fetch` has indifferent access so you can mix string and symbol keys, all the following examples retrieve the value:
|
276
283
|
|
277
284
|
```ruby
|
278
285
|
config.fetch(:settings, :base)
|
279
|
-
config.fetch(
|
280
|
-
config.fetch(:settings
|
281
|
-
config.fetch(
|
286
|
+
config.fetch("settings", "base")
|
287
|
+
config.fetch(:settings, "base")
|
288
|
+
config.fetch("settings", :base)
|
282
289
|
```
|
283
290
|
|
284
291
|
### 2.5 merge
|
@@ -289,7 +296,7 @@ To merge in other configuration settings as hash use `merge`:
|
|
289
296
|
config.set(:a, :b, value: 1)
|
290
297
|
config.set(:a, :c, value: 2)
|
291
298
|
|
292
|
-
config.merge({
|
299
|
+
config.merge({"a" => {"c" => 3, "d" => 4}})
|
293
300
|
|
294
301
|
config.fetch(:a, :c) # => 3
|
295
302
|
config.fetch(:a, :d) # => 4
|
@@ -373,6 +380,14 @@ config.delete(:settings, :base)
|
|
373
380
|
# "USD"
|
374
381
|
```
|
375
382
|
|
383
|
+
You can provide an optional default value in a block that will be returned when a key is not set:
|
384
|
+
|
385
|
+
```ruby
|
386
|
+
config.delete(:settings, :unknown) { |key| "#{key} isn't set" }
|
387
|
+
# =>
|
388
|
+
# "unknown isn't set"
|
389
|
+
```
|
390
|
+
|
376
391
|
### 2.10 alias_setting
|
377
392
|
|
378
393
|
In order to alias a configuration setting to another name use `alias_setting`.
|
@@ -380,7 +395,7 @@ In order to alias a configuration setting to another name use `alias_setting`.
|
|
380
395
|
For example, given an already existing setting:
|
381
396
|
|
382
397
|
```ruby
|
383
|
-
config.set(:base, value:
|
398
|
+
config.set(:base, value: "baz")
|
384
399
|
```
|
385
400
|
|
386
401
|
You can alias it to another name:
|
@@ -393,29 +408,29 @@ And then access like any other configuration setting:
|
|
393
408
|
|
394
409
|
```ruby
|
395
410
|
config.fetch(:currency)
|
396
|
-
# =>
|
411
|
+
# => "USD"
|
397
412
|
```
|
398
413
|
|
399
414
|
Deep nested configuration options are also supported:
|
400
415
|
|
401
416
|
```ruby
|
402
|
-
config.set(:settings, :base, value:
|
417
|
+
config.set(:settings, :base, value: "USD")
|
403
418
|
```
|
404
419
|
|
405
420
|
And then can be aliased like so:
|
406
421
|
|
407
422
|
```ruby
|
408
423
|
config.alias_setting(:settings, :base, to: [:settings, :currency])
|
409
|
-
config.alias_setting(
|
424
|
+
config.alias_setting("settings.base", to [:settings, :currency])
|
410
425
|
```
|
411
426
|
|
412
427
|
You can then access the deep nested settings:
|
413
428
|
|
414
429
|
```ruby
|
415
430
|
config.fetch(:settings, :currency)
|
416
|
-
# =>
|
417
|
-
config.fetch(
|
418
|
-
# =>
|
431
|
+
# => "USD"
|
432
|
+
config.fetch("settings.currency")
|
433
|
+
# => "USD"
|
419
434
|
```
|
420
435
|
|
421
436
|
### 2.11 validate
|
@@ -432,71 +447,40 @@ end
|
|
432
447
|
|
433
448
|
You can assign multiple validations for a given key and each of them will be run in the order they were registered when checking a value.
|
434
449
|
|
435
|
-
When setting value all the
|
450
|
+
When setting value all the validations will be run:
|
436
451
|
|
437
452
|
```ruby
|
438
|
-
config.set(:settings, :base, value:
|
439
|
-
# raises TTY::Config::ValidationError,
|
453
|
+
config.set(:settings, :base, value: "PL")
|
454
|
+
# raises TTY::Config::ValidationError, "Currency code needs to be 3 chars long."
|
440
455
|
```
|
441
456
|
|
442
|
-
If the value
|
457
|
+
If the value is provided as a proc or a block then the validation will be delayed until the value is actually read:
|
443
458
|
|
444
459
|
```ruby
|
445
|
-
config.set(:settings, :base) {
|
460
|
+
config.set(:settings, :base) { "PL" }
|
446
461
|
config.fetch(:settings, :base)
|
447
|
-
# raises TTY::Config::ValidationError,
|
448
|
-
```
|
449
|
-
|
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'
|
462
|
+
# raises TTY::Config::ValidationError, "Currency code needs to be 3 chars long."
|
463
463
|
```
|
464
464
|
|
465
|
-
|
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=
|
465
|
+
### 2.12 filename=
|
482
466
|
|
483
467
|
By default, **TTY::Config** searches for `config` named configuration file. To change this use `filename=` method without the extension name:
|
484
468
|
|
485
469
|
```ruby
|
486
|
-
config.filename =
|
470
|
+
config.filename = "investments"
|
487
471
|
```
|
488
472
|
|
489
|
-
Then any supported extensions will be
|
473
|
+
Then any supported extensions will be searched for such as `.yml`, `.json` and `.toml`.
|
490
474
|
|
491
|
-
### 2.
|
475
|
+
### 2.13 extname=
|
492
476
|
|
493
|
-
By default
|
477
|
+
By default ".yml" extension is used to write configuration out to a file but you can change that with `extname=`:
|
494
478
|
|
495
479
|
```ruby
|
496
|
-
config.extname =
|
480
|
+
config.extname = ".toml"
|
497
481
|
```
|
498
482
|
|
499
|
-
### 2.
|
483
|
+
### 2.14 append_path
|
500
484
|
|
501
485
|
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.
|
502
486
|
|
@@ -508,9 +492,9 @@ config.append_path(Dir.home) # look in user's home directory
|
|
508
492
|
config.append_path(Dir.pwd) # look in current working directory
|
509
493
|
```
|
510
494
|
|
511
|
-
None of these paths are required, but you should provide at least one path if you wish to read configuration file.
|
495
|
+
None of these paths are required, but you should provide at least one path if you wish to read a configuration file.
|
512
496
|
|
513
|
-
### 2.
|
497
|
+
### 2.15 prepend_path
|
514
498
|
|
515
499
|
The `prepend_path` allows you to add configuration search paths that should be searched first.
|
516
500
|
|
@@ -519,7 +503,7 @@ config.append_path(Dir.pwd) # look in current working directory second
|
|
519
503
|
config.prepend_path(Dir.home) # look in user's home directory first
|
520
504
|
```
|
521
505
|
|
522
|
-
### 2.
|
506
|
+
### 2.16 read
|
523
507
|
|
524
508
|
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
509
|
|
@@ -529,14 +513,16 @@ Currently the supported file formats are:
|
|
529
513
|
* `json` for `.json` extension
|
530
514
|
* `toml` for `.toml` extension
|
531
515
|
* `ini` for `.ini`, `.cnf`, `.conf`, `.cfg`, `.cf extensions`
|
516
|
+
* `hcl` for `.hcl` extensions
|
517
|
+
* `jprops` for `.properties`, `.props`, `.prop` extensions
|
532
518
|
|
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
|
519
|
+
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 specified then all known extensions will be tried.
|
534
520
|
|
535
521
|
For example, to find file called investments in the current directory do:
|
536
522
|
|
537
523
|
```ruby
|
538
524
|
config.append_path(Dir.pwd) # look in current working directory
|
539
|
-
config.filename =
|
525
|
+
config.filename = "investments" # file to search for
|
540
526
|
```
|
541
527
|
|
542
528
|
Find and read the configuration file:
|
@@ -548,7 +534,7 @@ config.read
|
|
548
534
|
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`:
|
549
535
|
|
550
536
|
```ruby
|
551
|
-
config.read(
|
537
|
+
config.read("./investments.toml")
|
552
538
|
```
|
553
539
|
|
554
540
|
In cases where you wish to specify a custom file extension, you will need to also specify the file format to use.
|
@@ -556,40 +542,70 @@ In cases where you wish to specify a custom file extension, you will need to als
|
|
556
542
|
For example, if you have a configuration file formatted using `YAML` notation with extension called `.config`, to read it do:
|
557
543
|
|
558
544
|
```ruby
|
559
|
-
config.read(
|
545
|
+
config.read("investments.config", format: :yaml)
|
546
|
+
```
|
547
|
+
|
548
|
+
### 2.17 write
|
549
|
+
|
550
|
+
By default **TTY::Config**, persists configuration file in the current working directory with a `config.yml` name. However, you can change the default file name by specifying the `filename` and `extension` type:
|
551
|
+
|
552
|
+
```ruby
|
553
|
+
config.filename = "investments"
|
554
|
+
config.extname = ".toml"
|
560
555
|
```
|
561
556
|
|
562
|
-
|
557
|
+
Now, by invoking `write` you will persist the current configuration to `investments.toml` file.
|
563
558
|
|
564
|
-
|
559
|
+
```ruby
|
560
|
+
config.write # writes "investments.toml" in the current directory
|
561
|
+
```
|
562
|
+
|
563
|
+
To write the current configuration to a file in a custom location, you can specify a direct location path and filename as an argument:
|
565
564
|
|
566
565
|
```ruby
|
567
|
-
config.
|
568
|
-
|
566
|
+
config.write("/custom/path/to/investments.toml")
|
567
|
+
# may raise an error if any of the path directories are missing
|
569
568
|
```
|
570
569
|
|
571
|
-
|
570
|
+
Alternatively, if the filename doesn't need to change you can specify only a custom path using the `:path` keyword:
|
572
571
|
|
573
572
|
```ruby
|
574
|
-
config.write(
|
573
|
+
config.write(path: "/custom/path/to")
|
574
|
+
# may raise an error if any of the path directories are missing
|
575
575
|
```
|
576
576
|
|
577
|
-
|
577
|
+
If the `/custom/path/to` doesn't exist an error will be raised. You can set the `:create` option to make any missing directories in the path:
|
578
578
|
|
579
579
|
```ruby
|
580
|
-
config.
|
580
|
+
config.write("/custom/path/to/investments.toml", create: true)
|
581
|
+
config.write(path: "/custom/path/to", create: true)
|
582
|
+
```
|
581
583
|
|
582
|
-
|
584
|
+
When the `investments.toml` file already exists the `TTY::Config::WriteError` error will be raised.
|
585
|
+
|
586
|
+
To create a configuration file regardless of whether it exists or not, use `:force` flag:
|
587
|
+
|
588
|
+
```ruby
|
589
|
+
config.write(force: true)
|
590
|
+
config.write("/custom/path/to/investments.toml", force: true)
|
591
|
+
config.write(path: "/custom/path/to", force: true)
|
592
|
+
```
|
593
|
+
|
594
|
+
By default, only the current directory is searched. You can specify additional location paths to be searched for already existing configuration to overwrite:
|
595
|
+
|
596
|
+
```ruby
|
597
|
+
config.append_path("/custom/path/to") # search in "/custom/path/to" for config file
|
583
598
|
```
|
584
599
|
|
585
|
-
|
600
|
+
By setting the `:create` option to `true`, you can ensure that even when no path is found that has a configuration file, the first location will be used and all missing directories created.
|
601
|
+
|
602
|
+
To ensure that a configuration file is written no matter what, use both `:create` and `:force`:
|
586
603
|
|
587
604
|
```ruby
|
588
|
-
config.write(force: true)
|
589
|
-
config.write('./investments.toml', force: true) # overwrite specific config file
|
605
|
+
config.write(create: true, force: true)
|
590
606
|
```
|
591
607
|
|
592
|
-
### 2.
|
608
|
+
### 2.18 exist?
|
593
609
|
|
594
610
|
To check if a configuration file exists within the configured search paths use `exist?` method:
|
595
611
|
|
@@ -597,20 +613,79 @@ To check if a configuration file exists within the configured search paths use `
|
|
597
613
|
config.exist? # => true
|
598
614
|
```
|
599
615
|
|
600
|
-
### 2.
|
616
|
+
### 2.19 env_prefix=
|
601
617
|
|
602
|
-
|
618
|
+
Given the following variables:
|
603
619
|
|
604
|
-
|
620
|
+
```ruby
|
621
|
+
ENV["MYTOOL_HOST"] = "127.0.0.1"
|
622
|
+
ENV["MYTOOL_PORT"] = "7727"
|
623
|
+
```
|
624
|
+
|
625
|
+
You can inform configuration about common prefix using `env_prefix`:
|
605
626
|
|
606
627
|
```ruby
|
607
|
-
|
628
|
+
config.env_prefix = "mytool"
|
629
|
+
```
|
630
|
+
|
631
|
+
Then set configuration key name to environment variable name:
|
632
|
+
|
633
|
+
```ruby
|
634
|
+
config.set_from_env(:host)
|
635
|
+
config.set_from_env(:port)
|
636
|
+
```
|
637
|
+
|
638
|
+
And retrieve the value:
|
639
|
+
|
640
|
+
```ruby
|
641
|
+
config.fetch(:host)
|
642
|
+
# => "127.0.0.1"
|
643
|
+
config.fetch(:port)
|
644
|
+
# => "7727"
|
645
|
+
```
|
646
|
+
|
647
|
+
### 2.20 env_separator=
|
648
|
+
|
649
|
+
By default, the `_` character is used to separate parts in the environment variable name and it can be changed using the `env_separator=` like so:
|
650
|
+
|
651
|
+
```ruby
|
652
|
+
config.env_separator = "___"
|
653
|
+
```
|
654
|
+
|
655
|
+
Given the following environment variable:
|
656
|
+
|
657
|
+
```ruby
|
658
|
+
ENV["SERVER__PORT"] = "123"
|
659
|
+
```
|
660
|
+
|
661
|
+
Then we can make configuration aware of the above variable name in one of these ways:
|
662
|
+
|
663
|
+
```ruby
|
664
|
+
config.set_from_env(:server, :port)
|
665
|
+
config.set_from_env("server.port")
|
666
|
+
````
|
667
|
+
|
668
|
+
And retrieve the value:
|
669
|
+
|
670
|
+
```ruby
|
671
|
+
config.fetch(:server, :port)
|
672
|
+
# => "123"
|
673
|
+
```
|
674
|
+
|
675
|
+
### 2.21 autoload_env
|
676
|
+
|
677
|
+
The `autoload_env` method allows you to automatically read environment variables. In most cases you would combine it with [env_prefix=](#219-env_prefix) to only read a subset of variables. When using `autoload_env`, anytime the `fetch` is called a corresponding environment variable will be checked.
|
678
|
+
|
679
|
+
For example, given an environment variable `MYTOOL_HOST` set to `localhost`:
|
680
|
+
|
681
|
+
```ruby
|
682
|
+
ENV["MYTOOL_HOST"]=localhost
|
608
683
|
```
|
609
684
|
|
610
685
|
And loading environment variables with a prefix of `MYTOOL`:
|
611
686
|
|
612
687
|
```ruby
|
613
|
-
config.env_prefix =
|
688
|
+
config.env_prefix = "mytool"
|
614
689
|
config.autoload_env
|
615
690
|
```
|
616
691
|
|
@@ -618,7 +693,84 @@ You can retrieve value with:
|
|
618
693
|
|
619
694
|
```ruby
|
620
695
|
config.fetch(:host)
|
621
|
-
# =>
|
696
|
+
# => "localhost"
|
697
|
+
```
|
698
|
+
|
699
|
+
### 2.22 register_marshaller
|
700
|
+
|
701
|
+
There are number of built-in marshallers that handle the process of serializing internal configuration from and back into a desired format, for example, a `JSON` string.
|
702
|
+
|
703
|
+
Currently supported formats out-of-the-box are: `YAML`, `JSON`, `TOML`, `INI` & `HCL`.
|
704
|
+
|
705
|
+
To create your own marshaller use the `TTY::Config::Marshaller` interface. You need to provide the implementation for the following marshalling methods:
|
706
|
+
|
707
|
+
* `marshal`
|
708
|
+
* `unmarshal`
|
709
|
+
|
710
|
+
In addition, you will need to specify the extension types this marshaller will handle using the `extension` method. The method accepts a list of names preceded by a dot:
|
711
|
+
|
712
|
+
```ruby
|
713
|
+
extension ".ext1", ".ext2", ".ext3"
|
714
|
+
```
|
715
|
+
|
716
|
+
Optionally, you can provide a dependency or dependencies that will be lazy loaded if the extension is used. For this use the `dependency` method.
|
717
|
+
|
718
|
+
You can either specify dependencies as a list of names:
|
719
|
+
|
720
|
+
```ruby
|
721
|
+
dependency "toml"
|
722
|
+
dependency "toml", "tomlrb"
|
723
|
+
```
|
724
|
+
|
725
|
+
Or provide dependencies in a block:
|
726
|
+
|
727
|
+
```ruby
|
728
|
+
dependency do
|
729
|
+
require "toml"
|
730
|
+
require "tomlrb"
|
731
|
+
end
|
732
|
+
```
|
733
|
+
|
734
|
+
Putting it all together, you can create your own marshaller like so:
|
735
|
+
|
736
|
+
```ruby
|
737
|
+
class MyCustomMarshaller
|
738
|
+
include TTY::Config::Marshaller
|
739
|
+
|
740
|
+
dependency "my_dep"
|
741
|
+
|
742
|
+
extension ".ext1", ".ext2"
|
743
|
+
|
744
|
+
def marshal(object)
|
745
|
+
MyDep.dump(object)
|
746
|
+
end
|
747
|
+
|
748
|
+
def unmarshal(content)
|
749
|
+
MyDep.parse(content)
|
750
|
+
end
|
751
|
+
end
|
752
|
+
```
|
753
|
+
|
754
|
+
And then let the configuration know about your marshaller by calling the `register_marshaller`:
|
755
|
+
|
756
|
+
```ruby
|
757
|
+
config.register_marshaller(:my_custom, MyCustomMarshaller)
|
758
|
+
```
|
759
|
+
|
760
|
+
Bear in mind that you can also override the built-in implementation of a marshaller. For example, if you find a better performing Ruby gem for TOML parsing, register your custom marshaller under the `:toml` name like so:
|
761
|
+
|
762
|
+
```ruby
|
763
|
+
config.register_marshaller(:toml, MyTOMLMarshaller)
|
764
|
+
```
|
765
|
+
|
766
|
+
### 2.23 unregister_marshaller
|
767
|
+
|
768
|
+
By default, the **TTY::Config** is ready to recognize various extensions. See [2.16 read](#216-read) section for more details. But, you're free to remove the default marshallers from the internal registry with `unregister_marshaller` method.
|
769
|
+
|
770
|
+
For example, to remove all the built-in marshallers do:
|
771
|
+
|
772
|
+
```ruby
|
773
|
+
config.unregister_marshaller :yaml, :json, :toml, :ini, :hcl
|
622
774
|
```
|
623
775
|
|
624
776
|
## 3. Examples
|
@@ -628,22 +780,22 @@ config.fetch(:host)
|
|
628
780
|
*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
781
|
|
630
782
|
```ruby
|
631
|
-
ENV[
|
632
|
-
ENV[
|
783
|
+
ENV["MYTOOL_HOST"] = "192.168.1.17"
|
784
|
+
ENV["MYTOOL_PORT"] = "7727"
|
633
785
|
```
|
634
786
|
|
635
|
-
Then in order to make your configuration aware of the above, you would use [env_prefix=](#
|
787
|
+
Then in order to make your configuration aware of the above, you would use [env_prefix=](#219-env_prefix) and [set_from_env](#23-set_from_env):
|
636
788
|
|
637
789
|
```ruby
|
638
|
-
config.env_prefix =
|
790
|
+
config.env_prefix = "mytool"
|
639
791
|
config.set_from_env(:host)
|
640
792
|
config.set_from_env(:port)
|
641
793
|
```
|
642
794
|
|
643
|
-
|
795
|
+
Or automatically load all prefixed environment variables with [autoload_env](#221-autoload_env):
|
644
796
|
|
645
797
|
```ruby
|
646
|
-
config.env_prefix =
|
798
|
+
config.env_prefix = "mytool"
|
647
799
|
config.autoload_env
|
648
800
|
```
|
649
801
|
|
@@ -651,9 +803,9 @@ And then retrieve values with [fetch](#24-fetch):
|
|
651
803
|
|
652
804
|
```ruby
|
653
805
|
config.fetch(:host)
|
654
|
-
#=>
|
806
|
+
#=> "192.168.1.17"
|
655
807
|
config.fetch(:port)
|
656
|
-
# =>
|
808
|
+
# => "7727"
|
657
809
|
```
|
658
810
|
|
659
811
|
### 3.2 Working with optparse
|
@@ -665,7 +817,7 @@ Let's assume you want to create a command line tool that among many options acce
|
|
665
817
|
First, you need to parse the flags and store results away in options hash:
|
666
818
|
|
667
819
|
```ruby
|
668
|
-
require
|
820
|
+
require "optparse"
|
669
821
|
|
670
822
|
options = {}
|
671
823
|
|
@@ -686,7 +838,7 @@ end
|
|
686
838
|
option_parser.parse!
|
687
839
|
```
|
688
840
|
|
689
|
-
Then, you
|
841
|
+
Then, you create a configuration instance:
|
690
842
|
|
691
843
|
```ruby
|
692
844
|
config = TTY::Config.new
|
@@ -695,7 +847,7 @@ config = TTY::Config.new
|
|
695
847
|
And setup config filename:
|
696
848
|
|
697
849
|
```ruby
|
698
|
-
config_filename = options[:config_file_path] ||
|
850
|
+
config_filename = options[:config_file_path] || "config.yml"
|
699
851
|
```
|
700
852
|
|
701
853
|
As well as add configuration file locations to search in:
|
@@ -709,7 +861,7 @@ Once config is initialized, you can read the configuration from a config file:
|
|
709
861
|
|
710
862
|
```ruby
|
711
863
|
begin
|
712
|
-
config.read(config_filename) # by default the
|
864
|
+
config.read(config_filename) # by default the "config.yml" is read
|
713
865
|
rescue TTY::Config::ReadError => read_error
|
714
866
|
STDERR.puts "\nNo configuration file found:"
|
715
867
|
STDERR.puts read_error
|
@@ -739,7 +891,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
739
891
|
|
740
892
|
## Contributing
|
741
893
|
|
742
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
894
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/piotrmurach/tty-config. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
743
895
|
|
744
896
|
## License
|
745
897
|
|
@@ -747,7 +899,7 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
747
899
|
|
748
900
|
## Code of Conduct
|
749
901
|
|
750
|
-
Everyone interacting in the
|
902
|
+
Everyone interacting in the TTY::Config project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/piotrmurach/tty-config/blob/master/CODE_OF_CONDUCT.md).
|
751
903
|
|
752
904
|
## Copyright
|
753
905
|
|