tty-config 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +103 -18
- data/lib/tty/config.rb +66 -129
- data/lib/tty/config/dependency_loader.rb +55 -0
- data/lib/tty/config/generator.rb +57 -0
- data/lib/tty/config/marshaller.rb +56 -0
- data/lib/tty/config/marshaller_registry.rb +43 -0
- data/lib/tty/config/marshallers.rb +35 -0
- data/lib/tty/config/marshallers/hcl_marshaller.rb +25 -0
- data/lib/tty/config/marshallers/ini_marshaller.rb +28 -0
- data/lib/tty/config/marshallers/java_props_marshaller.rb +25 -0
- data/lib/tty/config/marshallers/json_marshaller.rb +25 -0
- data/lib/tty/config/marshallers/toml_marshaller.rb +25 -0
- data/lib/tty/config/marshallers/yaml_marshaller.rb +29 -0
- data/lib/tty/config/version.rb +1 -1
- metadata +54 -32
- 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 -22
- data/spec/unit/new_spec.rb +0 -6
- data/spec/unit/normalize_hash_spec.rb +0 -21
- data/spec/unit/read_spec.rb +0 -118
- 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 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f0321ad959e00b63f653d7f27a89964cdc24b103aab2052615e0ed3fdf284ce
|
4
|
+
data.tar.gz: 12df44d97821e84cb19620fadec565841d0de28abc1a4ba1cd8a05d9d1d6ec24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebe68702be360238664adf912b42342df8e3e3be266d7e52d2be515d8f48373db53850688517f7c569f2b9674a88371a3205bad707d48a209c01d147af27c07f
|
7
|
+
data.tar.gz: af1c4f4586a6be640f65ebe01e0dcb88340860b4ae1645ba611135e618ca1b772c75eab2ab9744e0409dddac316154f2358d403e0950af20c25c1755ee7f16cc
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## [v0.4.0] - 2020-01-25
|
4
|
+
|
5
|
+
### Added
|
6
|
+
* Add DependencyLoader for a generic interface for loading marshalling dependencies
|
7
|
+
* Add Marshaller as a generic interface for building marshalling plugins
|
8
|
+
* Add MarshallerRegistry for storing all marshallers
|
9
|
+
* Add Marshallers to allow configuration of marshallers via #register_marshaller
|
10
|
+
& #unregister_marshaller
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
* Change #initialize to accept hash as settings
|
14
|
+
* Change #marshal & #unmarshal to use marshalling plugins
|
15
|
+
* Change gemspec to add metadata and remove test artefacts
|
16
|
+
|
3
17
|
## [v0.3.2] - 2019-06-18
|
4
18
|
|
5
19
|
### Changed
|
@@ -41,6 +55,7 @@
|
|
41
55
|
|
42
56
|
* Initial implementation and release
|
43
57
|
|
58
|
+
[v0.4.0]: https://github.com/piotrmurach/tty-config/compare/v0.3.2...v0.4.0
|
44
59
|
[v0.3.2]: https://github.com/piotrmurach/tty-config/compare/v0.3.1...v0.3.2
|
45
60
|
[v0.3.1]: https://github.com/piotrmurach/tty-config/compare/v0.3.0...v0.3.1
|
46
61
|
[v0.3.0]: https://github.com/piotrmurach/tty-config/compare/v0.2.0...v0.3.0
|
data/README.md
CHANGED
@@ -25,11 +25,15 @@
|
|
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 and write config files in YAML, JSON, TOML, INI, HCL and Java Properties formats
|
31
|
+
* Add custom marshallers or override the built-in ones
|
32
|
+
* Set and read settings for deeply nested keys
|
33
|
+
* Set defaults for undefined settings
|
34
|
+
* Read settings with indifferent access
|
35
|
+
* Merge configuration settings from other hash objects
|
36
|
+
* Read values from environment variables
|
33
37
|
|
34
38
|
## Installation
|
35
39
|
|
@@ -72,6 +76,8 @@ Or install it yourself as:
|
|
72
76
|
* [2.18 write](#218-write)
|
73
77
|
* [2.19 exist?](#219-exist)
|
74
78
|
* [2.20 autoload_env](#220-autoload_env)
|
79
|
+
* [2.21 register_marshaller](#221-register_marshaller)
|
80
|
+
* [2.22 unregister_marshaller](#222-register_marshaller)
|
75
81
|
* [3. Examples](#3-examples)
|
76
82
|
* [3.1 Working with env vars](#31-working-with-env-vars)
|
77
83
|
* [3.2 Working with optparse](#32-working-with-optparse)
|
@@ -85,7 +91,7 @@ config = TTY::Config.new
|
|
85
91
|
config.filename = 'investments'
|
86
92
|
```
|
87
93
|
|
88
|
-
|
94
|
+
Then configure values for different nested keys with `set` and `append`:
|
89
95
|
|
90
96
|
```ruby
|
91
97
|
config.set(:settings, :base, value: 'USD')
|
@@ -95,7 +101,7 @@ config.set(:coins, value: ['BTC'])
|
|
95
101
|
config.append('ETH', 'TRX', 'DASH', to: :coins)
|
96
102
|
```
|
97
103
|
|
98
|
-
get any value by using `fetch`:
|
104
|
+
You can get any value by using `fetch`:
|
99
105
|
|
100
106
|
```ruby
|
101
107
|
config.fetch(:settings, :base)
|
@@ -105,7 +111,7 @@ config.fetch(:coins)
|
|
105
111
|
# => ['BTC', 'ETH', 'TRX', 'DASH']
|
106
112
|
```
|
107
113
|
|
108
|
-
|
114
|
+
And call `write` to persist the configuration to `investments.yml` file:
|
109
115
|
|
110
116
|
```ruby
|
111
117
|
config.write
|
@@ -121,14 +127,14 @@ config.write
|
|
121
127
|
# - DASH
|
122
128
|
```
|
123
129
|
|
124
|
-
|
130
|
+
To read an `investments.yml` file, you need to provide the locations to search in:
|
125
131
|
|
126
132
|
```ruby
|
127
133
|
config.append_path Dir.pwd
|
128
134
|
config.append_path Dir.home
|
129
135
|
```
|
130
136
|
|
131
|
-
Finally, read
|
137
|
+
Finally, call `read` to convert configuration file back into an object again:
|
132
138
|
|
133
139
|
```ruby
|
134
140
|
config.read
|
@@ -175,7 +181,7 @@ You can also specify deeply nested configuration settings by passing sequence of
|
|
175
181
|
config.set :settings, :base, value: 'USD'
|
176
182
|
```
|
177
183
|
|
178
|
-
is equivalent to:
|
184
|
+
Which is equivalent to:
|
179
185
|
|
180
186
|
```ruby
|
181
187
|
config.set 'settings.base', value: 'USD'
|
@@ -240,7 +246,7 @@ config.set_from_env('settings.base') { 'CURRENCY'}
|
|
240
246
|
config.set_from_env('settings.base') { :currency}
|
241
247
|
```
|
242
248
|
|
243
|
-
And
|
249
|
+
And assuming `ENV['CURRENCY']=USD`:
|
244
250
|
|
245
251
|
```ruby
|
246
252
|
config.fetch(:settings, :base)
|
@@ -266,7 +272,7 @@ Similar to `set` operation, `fetch` allows you to retrieve deeply nested values:
|
|
266
272
|
config.fetch(:settings, :base) # => USD
|
267
273
|
```
|
268
274
|
|
269
|
-
is equivalent to:
|
275
|
+
Which is equivalent to:
|
270
276
|
|
271
277
|
```ruby
|
272
278
|
config.fetch('settings.base')
|
@@ -432,7 +438,7 @@ end
|
|
432
438
|
|
433
439
|
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
440
|
|
435
|
-
When setting value all the
|
441
|
+
When setting value all the validations will be run:
|
436
442
|
|
437
443
|
```ruby
|
438
444
|
config.set(:settings, :base, value: 'PL')
|
@@ -529,8 +535,10 @@ Currently the supported file formats are:
|
|
529
535
|
* `json` for `.json` extension
|
530
536
|
* `toml` for `.toml` extension
|
531
537
|
* `ini` for `.ini`, `.cnf`, `.conf`, `.cfg`, `.cf extensions`
|
538
|
+
* `hcl` for `.hcl` extensions
|
539
|
+
* `jprops` for `.properties`, `.props`, `.prop` extensions
|
532
540
|
|
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
|
541
|
+
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
542
|
|
535
543
|
For example, to find file called investments in the current directory do:
|
536
544
|
|
@@ -599,9 +607,9 @@ config.exist? # => true
|
|
599
607
|
|
600
608
|
### 2.20 autoload_env
|
601
609
|
|
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
|
610
|
+
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 environment variable will be checked.
|
603
611
|
|
604
|
-
For example, given an
|
612
|
+
For example, given an environment variable `MYTOOL_HOST` set to `localhost`:
|
605
613
|
|
606
614
|
```ruby
|
607
615
|
ENV['MYTOOL_HOST']=localhost
|
@@ -621,6 +629,83 @@ config.fetch(:host)
|
|
621
629
|
# => 'localhost'
|
622
630
|
```
|
623
631
|
|
632
|
+
### 2.21 register_marshaller
|
633
|
+
|
634
|
+
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.
|
635
|
+
|
636
|
+
Currently supported formats out-of-the-box are: `YAML`, `JSON`, `TOML`, `INI` & `HCL`.
|
637
|
+
|
638
|
+
To create your own marshaller use the `TTY::Config::Marshaller` interface. You need to provide the implementation for the following marshalling methods:
|
639
|
+
|
640
|
+
* `marshal`
|
641
|
+
* `unmarshal`
|
642
|
+
|
643
|
+
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:
|
644
|
+
|
645
|
+
```ruby
|
646
|
+
extension ".ext1", ".ext2", ".ext3"
|
647
|
+
```
|
648
|
+
|
649
|
+
Optionally, you can provide a dependency or dependencies that will be lazy loaded if the extension is used. For this use the `dependency` method.
|
650
|
+
|
651
|
+
You can either specify dependencies as a list of names:
|
652
|
+
|
653
|
+
```ruby
|
654
|
+
dependency "toml"
|
655
|
+
dependency "toml", "tomlrb"
|
656
|
+
```
|
657
|
+
|
658
|
+
Or provide dependencies in a block:
|
659
|
+
|
660
|
+
```ruby
|
661
|
+
dependency do
|
662
|
+
require "toml"
|
663
|
+
require "tomlrb"
|
664
|
+
end
|
665
|
+
```
|
666
|
+
|
667
|
+
Putting it all together, you can create your own marshaller like so:
|
668
|
+
|
669
|
+
```ruby
|
670
|
+
class MyCustomMarshaller
|
671
|
+
include TTY::Config::Marshaller
|
672
|
+
|
673
|
+
dependency "my_dep"
|
674
|
+
|
675
|
+
extension ".ext1", ".ext2"
|
676
|
+
|
677
|
+
def marshal(object)
|
678
|
+
MyDep.dump(object)
|
679
|
+
end
|
680
|
+
|
681
|
+
def unmarshal(content)
|
682
|
+
MyDep.parse(content)
|
683
|
+
end
|
684
|
+
end
|
685
|
+
```
|
686
|
+
|
687
|
+
And then let the configuration know about your marshaller by calling the `register_marshaller`:
|
688
|
+
|
689
|
+
```ruby
|
690
|
+
config.register_marshaller(:my_custom, MyCustomMarshaller)
|
691
|
+
```
|
692
|
+
|
693
|
+
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:
|
694
|
+
|
695
|
+
```ruby
|
696
|
+
config.register_marshaller(:toml, MyTOMLMarshaller)
|
697
|
+
```
|
698
|
+
|
699
|
+
### 2.22 unregister_marshaller
|
700
|
+
|
701
|
+
By default, the **TTY::Config** is ready to recognize various extensions. See (2.17 read)[#217-read] section for more details. But, you're free to remove the default marshallers from the internal registry with `unregister_marshaller` method.
|
702
|
+
|
703
|
+
For example, to remove all the built-in marshallers do:
|
704
|
+
|
705
|
+
```ruby
|
706
|
+
config.unregister_marshaller :yaml, :json, :toml, :ini, :hcl
|
707
|
+
```
|
708
|
+
|
624
709
|
## 3. Examples
|
625
710
|
|
626
711
|
### 3.1 Working with env vars
|
@@ -640,7 +725,7 @@ config.set_from_env(:host)
|
|
640
725
|
config.set_from_env(:port)
|
641
726
|
```
|
642
727
|
|
643
|
-
|
728
|
+
Or automatically load all prefixed environment variables with [autoload_env](#220-autoload-env):
|
644
729
|
|
645
730
|
```ruby
|
646
731
|
config.env_prefix = 'mytool'
|
data/lib/tty/config.rb
CHANGED
@@ -1,11 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "pathname"
|
4
4
|
|
5
|
-
require_relative
|
5
|
+
require_relative "config/version"
|
6
|
+
require_relative "config/marshallers"
|
7
|
+
require_relative "config/marshallers/ini_marshaller"
|
8
|
+
require_relative "config/marshallers/json_marshaller"
|
9
|
+
require_relative "config/marshallers/yaml_marshaller"
|
10
|
+
require_relative "config/marshallers/toml_marshaller"
|
11
|
+
require_relative "config/marshallers/hcl_marshaller"
|
12
|
+
require_relative "config/marshallers/java_props_marshaller"
|
6
13
|
|
7
14
|
module TTY
|
8
15
|
class Config
|
16
|
+
include Marshallers
|
17
|
+
|
18
|
+
# Error raised when failed to load a dependency
|
19
|
+
DependencyLoadError = Class.new(StandardError)
|
9
20
|
# Error raised when key fails validation
|
10
21
|
ReadError = Class.new(StandardError)
|
11
22
|
# Error raised when issues writing configuration to a file
|
@@ -30,65 +41,6 @@ module TTY
|
|
30
41
|
end
|
31
42
|
end
|
32
43
|
|
33
|
-
# Generate file content based on the data hash
|
34
|
-
#
|
35
|
-
# @param [Hash] data
|
36
|
-
#
|
37
|
-
# @return [String]
|
38
|
-
# the file content
|
39
|
-
#
|
40
|
-
# @api public
|
41
|
-
def self.generate(data, separator: '=')
|
42
|
-
content = []
|
43
|
-
values = {}
|
44
|
-
sections = {}
|
45
|
-
|
46
|
-
data.keys.sort.each do |key|
|
47
|
-
val = data[key]
|
48
|
-
if val.is_a?(NilClass)
|
49
|
-
next
|
50
|
-
elsif val.is_a?(Hash) ||
|
51
|
-
(val.is_a?(Array) && val.first.is_a?(Hash))
|
52
|
-
sections[key] = val
|
53
|
-
elsif val.is_a?(Array)
|
54
|
-
values[key] = val.join(',')
|
55
|
-
else
|
56
|
-
values[key] = val
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# values
|
61
|
-
values.each do |key, val|
|
62
|
-
content << "#{key} #{separator} #{val}"
|
63
|
-
end
|
64
|
-
content << '' unless values.empty?
|
65
|
-
|
66
|
-
# sections
|
67
|
-
sections.each do |section, object|
|
68
|
-
next if object.empty? # only add section if values present
|
69
|
-
|
70
|
-
content << "[#{section}]"
|
71
|
-
if object.is_a?(Array)
|
72
|
-
object = object.reduce({}, :merge!)
|
73
|
-
end
|
74
|
-
object.each do |key, val|
|
75
|
-
val = val.join(',') if val.is_a?(Array)
|
76
|
-
content << "#{key} #{separator} #{val}" if val
|
77
|
-
end
|
78
|
-
content << ''
|
79
|
-
end
|
80
|
-
content.join("\n")
|
81
|
-
end
|
82
|
-
|
83
|
-
# Storage for suppported format & extensions pairs
|
84
|
-
# @api public
|
85
|
-
EXTENSIONS = {
|
86
|
-
yaml: %w(.yaml .yml),
|
87
|
-
json: %w(.json),
|
88
|
-
toml: %w(.toml),
|
89
|
-
ini: %w(.ini .cnf .conf .cfg .cf)
|
90
|
-
}.freeze
|
91
|
-
|
92
44
|
# A collection of config paths
|
93
45
|
# @api public
|
94
46
|
attr_reader :location_paths
|
@@ -116,19 +68,25 @@ module TTY
|
|
116
68
|
# Create a configuration instance
|
117
69
|
#
|
118
70
|
# @api public
|
119
|
-
def initialize(
|
71
|
+
def initialize(settings = {})
|
120
72
|
@settings = settings
|
121
73
|
@location_paths = []
|
122
74
|
@validators = {}
|
123
75
|
@filename = 'config'
|
124
76
|
@extname = '.yml'
|
125
|
-
@extensions = EXTENSIONS.values.flatten << ''
|
126
77
|
@key_delim = '.'
|
127
78
|
@envs = {}
|
128
79
|
@env_prefix = ''
|
129
80
|
@autoload_env = false
|
130
81
|
@aliases = {}
|
131
82
|
|
83
|
+
register_marshaller :yaml, Marshallers::YAMLMarshaller
|
84
|
+
register_marshaller :json, Marshallers::JSONMarshaller
|
85
|
+
register_marshaller :toml, Marshallers::TOMLMarshaller
|
86
|
+
register_marshaller :ini, Marshallers::INIMarshaller
|
87
|
+
register_marshaller :hcl, Marshallers::HCLMarshaller
|
88
|
+
register_marshaller :jprops, Marshallers::JavaPropsMarshaller
|
89
|
+
|
132
90
|
yield(self) if block_given?
|
133
91
|
end
|
134
92
|
|
@@ -138,7 +96,7 @@ module TTY
|
|
138
96
|
#
|
139
97
|
# api public
|
140
98
|
def extname=(name)
|
141
|
-
unless
|
99
|
+
unless extensions.include?(name)
|
142
100
|
raise UnsupportedExtError, "Config file format `#{name}` is not supported."
|
143
101
|
end
|
144
102
|
@extname = name
|
@@ -392,7 +350,12 @@ module TTY
|
|
392
350
|
raise ReadError, "Configuration file `#{file}` does not exist!"
|
393
351
|
end
|
394
352
|
|
395
|
-
|
353
|
+
set_file_metadata(file)
|
354
|
+
|
355
|
+
ext = (format == :auto ? extname : ".#{format}")
|
356
|
+
content = ::File.read(file)
|
357
|
+
|
358
|
+
merge(unmarshal(content, ext: ext))
|
396
359
|
end
|
397
360
|
|
398
361
|
# Write current configuration to a file.
|
@@ -416,10 +379,24 @@ module TTY
|
|
416
379
|
file = ::File.join(dir, "#{filename}#{@extname}")
|
417
380
|
end
|
418
381
|
|
419
|
-
|
382
|
+
set_file_metadata(file)
|
383
|
+
|
384
|
+
ext = (format == :auto ? extname : ".#{format}")
|
385
|
+
content = marshal(@settings, ext: ext)
|
386
|
+
|
420
387
|
::File.write(file, content)
|
421
388
|
end
|
422
389
|
|
390
|
+
# Set file name and extension
|
391
|
+
#
|
392
|
+
# @param [File] file
|
393
|
+
#
|
394
|
+
# @api public
|
395
|
+
def set_file_metadata(file)
|
396
|
+
self.extname = ::File.extname(file)
|
397
|
+
self.filename = ::File.basename(file, extname)
|
398
|
+
end
|
399
|
+
|
423
400
|
# Current configuration
|
424
401
|
#
|
425
402
|
# @api public
|
@@ -583,7 +560,7 @@ module TTY
|
|
583
560
|
# @api private
|
584
561
|
def search_in_path(path)
|
585
562
|
path = Pathname.new(path)
|
586
|
-
|
563
|
+
extensions.each do |ext|
|
587
564
|
if ::File.exist?(path.join("#{filename}#{ext}").to_s)
|
588
565
|
return path.join("#{filename}#{ext}").to_s
|
589
566
|
end
|
@@ -591,81 +568,41 @@ module TTY
|
|
591
568
|
nil
|
592
569
|
end
|
593
570
|
|
571
|
+
# Crate a marshaller instance based on the extension name
|
572
|
+
#
|
573
|
+
# @return [nil, Marshaller]
|
574
|
+
#
|
594
575
|
# @api private
|
595
|
-
def
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
case ext
|
602
|
-
when *EXTENSIONS[:yaml]
|
603
|
-
load_read_dep('yaml', ext)
|
604
|
-
if YAML.respond_to?(:safe_load)
|
605
|
-
YAML.safe_load(::File.read(file))
|
606
|
-
else
|
607
|
-
YAML.load(::File.read(file))
|
608
|
-
end
|
609
|
-
when *EXTENSIONS[:json]
|
610
|
-
load_read_dep('json', ext)
|
611
|
-
JSON.parse(::File.read(file))
|
612
|
-
when *EXTENSIONS[:toml]
|
613
|
-
load_read_dep('toml', ext)
|
614
|
-
TOML.load(::File.read(file))
|
615
|
-
when *EXTENSIONS[:ini]
|
616
|
-
load_read_dep('inifile', ext)
|
617
|
-
ini = IniFile.load(file).to_h
|
618
|
-
global = ini.delete('global')
|
619
|
-
ini.merge!(global)
|
620
|
-
else
|
621
|
-
raise ReadError, "Config file format `#{ext}` is not supported."
|
622
|
-
end
|
576
|
+
def create_marshaller(ext)
|
577
|
+
marshaller = marshallers.find { |marsh| marsh.ext.include?(ext) }
|
578
|
+
|
579
|
+
return nil if marshaller.nil?
|
580
|
+
|
581
|
+
marshaller.new
|
623
582
|
end
|
624
583
|
|
625
|
-
# Try loading read dependency
|
626
584
|
# @api private
|
627
|
-
def
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
585
|
+
def unmarshal(content, ext: nil)
|
586
|
+
ext ||= extname
|
587
|
+
if marshaller = create_marshaller(ext)
|
588
|
+
marshaller.unmarshal(content)
|
589
|
+
else
|
590
|
+
raise ReadError, "Config file format `#{ext}` is not supported."
|
591
|
+
end
|
632
592
|
end
|
633
593
|
|
634
|
-
# Marshal
|
594
|
+
# Marshal hash object into a configuration file content
|
635
595
|
#
|
636
596
|
# @return [String]
|
637
597
|
#
|
638
598
|
# @api private
|
639
|
-
def marshal(
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
self.filename = ::File.basename(file, file_ext)
|
644
|
-
|
645
|
-
case ext
|
646
|
-
when *EXTENSIONS[:yaml]
|
647
|
-
load_write_dep('yaml', ext)
|
648
|
-
YAML.dump(self.class.normalize_hash(data, :to_s))
|
649
|
-
when *EXTENSIONS[:json]
|
650
|
-
load_write_dep('json', ext)
|
651
|
-
JSON.pretty_generate(data)
|
652
|
-
when *EXTENSIONS[:toml]
|
653
|
-
load_write_dep('toml', ext)
|
654
|
-
TOML::Generator.new(data).body
|
655
|
-
when *EXTENSIONS[:ini]
|
656
|
-
Config.generate(data)
|
599
|
+
def marshal(object, ext: nil)
|
600
|
+
ext ||= extname
|
601
|
+
if marshaller = create_marshaller(ext)
|
602
|
+
marshaller.marshal(object)
|
657
603
|
else
|
658
604
|
raise WriteError, "Config file format `#{ext}` is not supported."
|
659
605
|
end
|
660
606
|
end
|
661
|
-
|
662
|
-
# Try loading write depedency
|
663
|
-
# @api private
|
664
|
-
def load_write_dep(gem_name, format)
|
665
|
-
require gem_name
|
666
|
-
rescue LoadError
|
667
|
-
raise WriteError, "Gem `#{gem_name}` is missing. Please install it " \
|
668
|
-
"to read #{format} configuration format."
|
669
|
-
end
|
670
607
|
end # Config
|
671
608
|
end # TTY
|