configurate 0.1.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/Changelog.md +30 -0
- data/README.md +96 -20
- data/lib/configurate.rb +26 -15
- data/lib/configurate/lookup_chain.rb +19 -17
- data/lib/configurate/provider.rb +34 -27
- data/lib/configurate/provider/dynamic.rb +34 -17
- data/lib/configurate/provider/env.rb +18 -14
- data/lib/configurate/provider/string_hash.rb +46 -0
- data/lib/configurate/provider/toml.rb +39 -0
- data/lib/configurate/provider/yaml.rb +26 -32
- data/lib/configurate/proxy.rb +42 -13
- data/lib/configurate/setting_path.rb +20 -8
- data/spec/configurate/lookup_chain_spec.rb +11 -9
- data/spec/configurate/provider/dynamic_spec.rb +13 -5
- data/spec/configurate/provider/env_spec.rb +13 -11
- data/spec/configurate/provider/string_hash_spec.rb +82 -0
- data/spec/configurate/provider/toml_spec.rb +112 -0
- data/spec/configurate/provider/yaml_spec.rb +42 -18
- data/spec/configurate/provider_spec.rb +15 -2
- data/spec/configurate/proxy_spec.rb +33 -7
- data/spec/configurate/setting_path_spec.rb +39 -20
- data/spec/configurate_spec.rb +5 -3
- data/spec/spec_helper.rb +8 -5
- metadata +31 -13
- checksums.yaml.gz.asc +0 -11
- data.tar.gz.asc +0 -11
- metadata.gz.asc +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5917dff879c04bd7e35104f02ed093e0ade7628503b70eaa9ba9f988250ce89d
|
4
|
+
data.tar.gz: 0ac06ee31c43264bac9001e7dad1c4fa18e9116dd02adfd325f21281d65ac2a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eaf82b6d8a397b3473bf4abc11722a7fb43f98981ee25142786a37c7ba46c1d847324a43f6950ad8997b7fd6db1186d3cd0e7d9a554b28e4f3a5d07b742075bb
|
7
|
+
data.tar.gz: 28022b6871d3282a5c8283b701bc9a45b1e2519470cb4762e9cb0d4a1875c86c5d16648c8eead096bc0da0da4cc09d477b2c27ef398b9b8c55c0638a4c245b6c
|
data/Changelog.md
CHANGED
@@ -1,3 +1,33 @@
|
|
1
|
+
# 0.5.0
|
2
|
+
|
3
|
+
* Support and prefer `toml-rb` over `tomlrb` in the shipped TOML provider.
|
4
|
+
* Drop explicit support for Ruby < 2.4
|
5
|
+
|
6
|
+
# 0.4.0
|
7
|
+
|
8
|
+
* `Configurate::Proxy` returns its own singleton class if the target does not support creating one.
|
9
|
+
* Extract `Configurate::Provider::StringHash` as a new base class for hash based providers.
|
10
|
+
* Add `Configurate::Provider::TOML`.
|
11
|
+
|
12
|
+
# 0.3.1
|
13
|
+
|
14
|
+
* Configurate::Provider::Dynamic returns true when passed the special
|
15
|
+
`reset_dynamic!` call.
|
16
|
+
|
17
|
+
# 0.3.0
|
18
|
+
|
19
|
+
* Add new exception: Configurate::MissingSetting to be raised and bubble up to the user
|
20
|
+
if a setting wasn't found and the user requested to be informed.
|
21
|
+
* Configurate::Provider::YAML got the new option raise_on_missing to raise
|
22
|
+
Configurate::MissingSetting if the requested key is not in the YAML document.
|
23
|
+
|
24
|
+
# 0.2.0
|
25
|
+
|
26
|
+
* Dynamic provider listens to reset_dynamic! message and forgets all settings on it.
|
27
|
+
* Calls ending in ! call the providers directly.
|
28
|
+
* Added SettingPath#action?, remove is_ prefix from SettingPath methods.
|
29
|
+
* Add implicit converters to Proxy that call the explicit converters.
|
30
|
+
|
1
31
|
# 0.1.0
|
2
32
|
|
3
33
|
* Dynamic provider resolves nested assignments
|
data/README.md
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
# Configurate - A flexible configuration system
|
2
|
-
[](https://coveralls.io/r/MrZYX/configurate)
|
2
|
+
[](https://badge.fury.io/rb/configurate)
|
3
|
+
[](https://travis-ci.org/jhass/configurate)
|
4
|
+
[](https://codeclimate.com/github/jhass/configurate)
|
5
|
+
[](https://coveralls.io/r/jhass/configurate?branch=master)
|
7
6
|
|
8
7
|
Configurate allows you to specify a chain of configuration providers which are
|
9
8
|
queried in order until one returns a value. This allows scenarios like overriding
|
@@ -11,7 +10,7 @@ your default settings with a user configuration file and let those be overridden
|
|
11
10
|
by environment variables. The query interface allows to group and nest your configuration options
|
12
11
|
to a practically unlimited level.
|
13
12
|
|
14
|
-
Configurate
|
13
|
+
Configurate supports Ruby 2.0 or later.
|
15
14
|
|
16
15
|
## Installation
|
17
16
|
|
@@ -80,7 +79,7 @@ Ruby does not allow to metaprogram `false`, thus something like
|
|
80
79
|
puts "yep" if Config.enable_stuff
|
81
80
|
```
|
82
81
|
|
83
|
-
always outputs `yep`. The workaround is to append `.get
|
82
|
+
always outputs `yep`. The workaround is to append `.get`, or `?` to get the
|
84
83
|
real value:
|
85
84
|
|
86
85
|
```ruby
|
@@ -107,14 +106,6 @@ will always output `unknown`. Again use `.get`
|
|
107
106
|
|
108
107
|
## Shipped providers
|
109
108
|
|
110
|
-
### Configurate::Provider::Base
|
111
|
-
|
112
|
-
A convenience base class changing the interface for implementers. It provides a basic `#lookup` method
|
113
|
-
which just passes all parameters through to `#lookup_path`.
|
114
|
-
The result of `#lookup_path` is returned, unless it's `nil`
|
115
|
-
then `Configurate::SettingNotFoundError` is raised. Subclasses are expected to implement `#lookup_path`.
|
116
|
-
Do not use this class directly as a provider!
|
117
|
-
|
118
109
|
### Configurate::Provider::Env
|
119
110
|
|
120
111
|
This class transforms a query string into a name for a environment variable and looks up this variable then.
|
@@ -124,6 +115,40 @@ into arrays.
|
|
124
115
|
|
125
116
|
This provider does not take any additional initialization parameters.
|
126
117
|
|
118
|
+
### Configurate::Provider::TOML
|
119
|
+
|
120
|
+
This provider reads settings from a given [TOML](https://github.com/toml-lang/toml) file. It converts the sections of
|
121
|
+
query string to a nested value. For a given TOML file
|
122
|
+
|
123
|
+
```toml
|
124
|
+
[stuff]
|
125
|
+
enable = true
|
126
|
+
param = "foo"
|
127
|
+
|
128
|
+
[stuff.nested]
|
129
|
+
param = "bar"
|
130
|
+
```
|
131
|
+
|
132
|
+
the following queries would be valid:
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
Config.stuff.enable? # => true
|
136
|
+
Config.stuff.param # => "foo"
|
137
|
+
Config.stuff.nested.param # => "bar"
|
138
|
+
```
|
139
|
+
|
140
|
+
This provider depends on the [toml-rb](https://github.com/emancu/toml-rb) or the [tomlrb](https://github.com/fbernier/tomlrb) gem.
|
141
|
+
This is why it is not loaded by default and needs an explicit `require 'configurate/provider/toml'` to be available. If both are available, toml-rb is preferred.
|
142
|
+
|
143
|
+
The initializer takes a path to the configuration file a the mandatory first argument and
|
144
|
+
the following optional parameters:
|
145
|
+
|
146
|
+
* *namespace:* Specify a alternative root. This is useful if you for example add the same file multiple
|
147
|
+
times through multiple providers, with different namespaces, letting you override settings depending on
|
148
|
+
the rails environment, without duplicating common settings. Defaults to none.
|
149
|
+
* *required:* Whether to raise an error if the the file isn't found or, if one is given, the namespace
|
150
|
+
doesn't exist in the file.
|
151
|
+
|
127
152
|
### Configurate::Provider::YAML
|
128
153
|
|
129
154
|
This provider reads settings from a given [YAML](http://www.yaml.org) file. It converts the sections of
|
@@ -145,8 +170,8 @@ Config.stuff.param # => "foo"
|
|
145
170
|
Config.stuff.nested.param # => "bar"
|
146
171
|
```
|
147
172
|
|
148
|
-
The initializer takes a path to the configuration file
|
149
|
-
the following optional parameters
|
173
|
+
The initializer takes a path to the configuration file a the mandatory first argument and
|
174
|
+
the following optional parameters:
|
150
175
|
|
151
176
|
* *namespace:* Specify a alternative root. This is useful if you for example add the same file multiple
|
152
177
|
times through multiple providers, with different namespaces, letting you override settings depending on
|
@@ -154,18 +179,67 @@ the following optional parameters, as a hash:
|
|
154
179
|
* *required:* Whether to raise an error if the the file isn't found or, if one is given, the namespace
|
155
180
|
doesn't exist in the file.
|
156
181
|
|
182
|
+
|
183
|
+
### Configurate::Provider::StringHash
|
184
|
+
|
185
|
+
A provider taking a (nested) `Hash` where all keys are strings. The query string is then looked up in this hash.
|
186
|
+
|
187
|
+
So for a given `Hash`
|
188
|
+
|
189
|
+
```ruby
|
190
|
+
{
|
191
|
+
"stuff" => {
|
192
|
+
"enable" => true,
|
193
|
+
"param" => "foo",
|
194
|
+
"nested" => {
|
195
|
+
"param" => "bar"
|
196
|
+
}
|
197
|
+
}
|
198
|
+
}
|
199
|
+
```
|
200
|
+
|
201
|
+
the following queries would be valid:
|
202
|
+
|
203
|
+
```ruby
|
204
|
+
Config.stuff.enable? # => true
|
205
|
+
Config.stuff.param # => "foo"
|
206
|
+
Config.stuff.nested.param # => "bar"
|
207
|
+
```
|
208
|
+
|
209
|
+
The initializer takes the hash as the mandatory first argument and
|
210
|
+
the following optional parameters:
|
211
|
+
|
212
|
+
* *namespace:* Specify a alternative root. This is useful if you for example add the same file multiple
|
213
|
+
times through multiple providers, with different namespaces, letting you override settings depending on
|
214
|
+
the rails environment, without duplicating common settings. Defaults to none.
|
215
|
+
* *required:* Whether to raise an error if the namespace
|
216
|
+
doesn't exist in the hash.
|
217
|
+
* *source:* A hint text about the origin of the configuration data to be used in error messages.
|
218
|
+
|
219
|
+
As you may have noticed by now, `Configurate::Provider::YAML` and `Configurate::Provider::TOML` are merely convenience
|
220
|
+
subclasses of this provider, loading the file for you.
|
221
|
+
|
157
222
|
### Configurate::Provider::Dynamic
|
158
223
|
|
159
|
-
A provider which stores the first
|
160
|
-
return it later. This is mainly useful for testing but can be useful to temporarily
|
161
|
-
too. To clarify a small example:
|
224
|
+
A provider which stores the first additional parameter if the query string ends with an equal sign and can
|
225
|
+
return it later. This is mainly useful for testing but can be useful to temporarily override stuff too. To clarify a small example:
|
162
226
|
|
163
227
|
```ruby
|
164
228
|
Config.foo.bar # => nil
|
165
229
|
Config.foo.bar = "baz"
|
166
230
|
Config.foo.bar # => "baz"
|
231
|
+
Config.reset_dynamic!
|
232
|
+
Config.foo.bar # => nil
|
167
233
|
```
|
168
234
|
|
235
|
+
### Configurate::Provider::Base
|
236
|
+
|
237
|
+
A convenience base class changing the interface for implementers. It provides a basic `#lookup` method
|
238
|
+
which just passes all parameters through to `#lookup_path`.
|
239
|
+
The result of `#lookup_path` is returned, unless it's `nil`
|
240
|
+
then `Configurate::SettingNotFoundError` is raised. Subclasses are expected to implement `#lookup_path`.
|
241
|
+
Do not use this class directly as a provider!
|
242
|
+
|
169
243
|
## Writing a provider
|
170
244
|
|
171
245
|
...should be pretty easy. For example here is the `Configurate::Provider::Env` provider:
|
@@ -183,6 +257,8 @@ class Configurate::Provider::Env < Configurate::Provider::Base
|
|
183
257
|
end
|
184
258
|
```
|
185
259
|
|
260
|
+
`Configurate::Provider::StringHash` should also serve as a useful baseclass for most providers.
|
261
|
+
|
186
262
|
|
187
263
|
## Documentation
|
188
264
|
|
data/lib/configurate.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require 'configurate/lookup_chain'
|
5
|
-
require 'configurate/provider'
|
6
|
-
require 'configurate/proxy'
|
3
|
+
require "forwardable"
|
7
4
|
|
5
|
+
require "configurate/setting_path"
|
6
|
+
require "configurate/lookup_chain"
|
7
|
+
require "configurate/provider"
|
8
|
+
require "configurate/proxy"
|
8
9
|
|
9
10
|
# A flexible and extendable configuration system.
|
10
11
|
# The calling logic is isolated from the lookup logic
|
@@ -20,15 +21,15 @@ require 'configurate/proxy'
|
|
20
21
|
module Configurate
|
21
22
|
# This is your main entry point. Instead of lengthy explanations
|
22
23
|
# let an example demonstrate its usage:
|
23
|
-
#
|
24
|
+
#
|
24
25
|
# require 'configuration_methods'
|
25
|
-
#
|
26
|
+
#
|
26
27
|
# AppSettings = Configurate::Settings.create do
|
27
28
|
# add_provider Configurate::Provider::Env
|
28
29
|
# add_provider Configurate::Provider::YAML, '/etc/app_settings.yml',
|
29
30
|
# namespace: Rails.env, required: false
|
30
31
|
# add_provider Configurate::Provider::YAML, 'config/default_settings.yml'
|
31
|
-
#
|
32
|
+
#
|
32
33
|
# extend YourConfigurationMethods
|
33
34
|
# end
|
34
35
|
#
|
@@ -36,18 +37,17 @@ module Configurate
|
|
36
37
|
#
|
37
38
|
# Please also read the note at {Proxy}!
|
38
39
|
class Settings
|
39
|
-
|
40
40
|
attr_reader :lookup_chain
|
41
|
-
|
41
|
+
|
42
42
|
undef_method :method # Remove possible conflicts with common setting names
|
43
43
|
|
44
44
|
extend Forwardable
|
45
45
|
|
46
46
|
def initialize
|
47
47
|
@lookup_chain = LookupChain.new
|
48
|
-
|
48
|
+
warn "Warning you called Configurate::Settings.new with a block, you really meant to call #create" if block_given?
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
# @!method lookup(setting)
|
52
52
|
# (see {LookupChain#lookup})
|
53
53
|
|
@@ -59,19 +59,30 @@ module Configurate
|
|
59
59
|
|
60
60
|
def_delegators :@lookup_chain, :lookup, :add_provider, :[]
|
61
61
|
|
62
|
+
# rubocop:disable Style/MethodMissingSuper we handle all calls
|
63
|
+
# rubocop:disable Style/MissingRespondToMissing we override respond_to? instead
|
64
|
+
|
62
65
|
# See description and {#lookup}, {#[]} and {#add_provider}
|
63
66
|
def method_missing(method, *args, &block)
|
64
67
|
Proxy.new(@lookup_chain).public_send(method, *args, &block)
|
65
68
|
end
|
66
|
-
|
69
|
+
# rubocop:enable all
|
70
|
+
|
67
71
|
# Create a new configuration object
|
68
72
|
# @yield the given block will be evaluated in the context of the new object
|
69
73
|
def self.create(&block)
|
70
|
-
config =
|
74
|
+
config = new
|
71
75
|
config.instance_eval(&block) if block_given?
|
72
76
|
config
|
73
77
|
end
|
74
78
|
end
|
75
|
-
|
79
|
+
|
80
|
+
# This is supposed to be raised by providers if the requested setting
|
81
|
+
# does not exist, (remember, nil is a valid value and thus rarely a sufficient check)
|
82
|
+
# and this should be communicated to the end user.
|
83
|
+
class MissingSetting < RuntimeError; end
|
84
|
+
|
85
|
+
# This is supposed to be raised by providers if the requested setting
|
86
|
+
# cannot be found and the next provider in the chain should be tried.
|
76
87
|
class SettingNotFoundError < RuntimeError; end
|
77
88
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Configurate
|
2
4
|
# This object builds a chain of configuration providers to try to find
|
3
5
|
# the value of a setting.
|
@@ -5,7 +7,7 @@ module Configurate
|
|
5
7
|
def initialize
|
6
8
|
@provider = []
|
7
9
|
end
|
8
|
-
|
10
|
+
|
9
11
|
# Adds a provider to the chain. Providers are tried in the order
|
10
12
|
# they are added, so the order is important.
|
11
13
|
#
|
@@ -17,11 +19,10 @@ module Configurate
|
|
17
19
|
unless provider.respond_to?(:instance_methods) && provider.instance_methods.include?(:lookup)
|
18
20
|
raise ArgumentError, "the given provider does not respond to lookup"
|
19
21
|
end
|
20
|
-
|
22
|
+
|
21
23
|
@provider << provider.new(*args)
|
22
24
|
end
|
23
|
-
|
24
|
-
|
25
|
+
|
25
26
|
# Tries all providers in the order they were added to provide a response
|
26
27
|
# for setting.
|
27
28
|
#
|
@@ -37,27 +38,28 @@ module Configurate
|
|
37
38
|
return special_value_or_string(provider.lookup(setting.clone, *args))
|
38
39
|
rescue SettingNotFoundError; end
|
39
40
|
end
|
40
|
-
|
41
|
+
|
41
42
|
nil
|
42
43
|
end
|
43
44
|
alias_method :[], :lookup
|
44
|
-
|
45
|
-
private
|
46
|
-
|
45
|
+
|
46
|
+
private
|
47
|
+
|
47
48
|
def special_value_or_string(value)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
49
|
+
case value
|
50
|
+
when TrueClass, FalseClass, NilClass, Array, Hash
|
51
|
+
value
|
52
|
+
else
|
53
|
+
if value.respond_to?(:to_s)
|
54
|
+
case value.to_s.strip
|
52
55
|
when "true" then true
|
53
56
|
when "false" then false
|
54
57
|
when "", "nil" then nil
|
55
|
-
else value
|
58
|
+
else value.to_s
|
59
|
+
end
|
60
|
+
else
|
61
|
+
value
|
56
62
|
end
|
57
|
-
elsif value.respond_to?(:to_s)
|
58
|
-
return value.to_s
|
59
|
-
else
|
60
|
-
return value
|
61
63
|
end
|
62
64
|
end
|
63
65
|
end
|
data/lib/configurate/provider.rb
CHANGED
@@ -1,32 +1,39 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Configurate
|
4
|
+
module Provider
|
5
|
+
# This provides a basic {#lookup} method for other providers to build
|
6
|
+
# upon. Childs are expected to define +lookup_path(path, *args)+.
|
7
|
+
# The method should return nil if the setting
|
8
|
+
# wasn't found and {#lookup} will raise an {SettingNotFoundError} in that
|
9
|
+
# case.
|
10
|
+
class Base
|
11
|
+
def lookup(*args)
|
12
|
+
result = lookup_path(*args)
|
13
|
+
return result unless result.nil?
|
14
|
+
|
15
|
+
raise Configurate::SettingNotFoundError, "The setting #{args.first} was not found"
|
16
|
+
end
|
12
17
|
end
|
13
|
-
end
|
14
18
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
# Utility function to lookup a settings path in a hash
|
20
|
+
# @param setting_path [SettingPath]
|
21
|
+
# @param hash [Hash]
|
22
|
+
# @yield fallback value if not found
|
23
|
+
# @return [Object]
|
24
|
+
def self.lookup_in_hash setting_path, hash, &fallback
|
25
|
+
fallback ||= proc { nil }
|
26
|
+
while hash.is_a?(Hash) && hash.has_key?(setting_path.first) && !setting_path.empty?
|
27
|
+
hash = hash[setting_path.shift]
|
28
|
+
end
|
29
|
+
return fallback.call unless setting_path.empty?
|
30
|
+
|
31
|
+
hash
|
24
32
|
end
|
25
|
-
return fallback.call unless setting_path.empty?
|
26
|
-
hash
|
27
33
|
end
|
28
|
-
end
|
34
|
+
end
|
29
35
|
|
30
|
-
require
|
31
|
-
require
|
32
|
-
require
|
36
|
+
require "configurate/provider/string_hash"
|
37
|
+
require "configurate/provider/yaml"
|
38
|
+
require "configurate/provider/env"
|
39
|
+
require "configurate/provider/dynamic"
|