configurate 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 +4 -4
- data/Changelog.md +7 -0
- data/README.md +4 -4
- data/lib/configurate.rb +21 -16
- data/lib/configurate/lookup_chain.rb +10 -10
- data/lib/configurate/provider.rb +29 -27
- data/lib/configurate/provider/dynamic.rb +30 -22
- data/lib/configurate/provider/env.rb +16 -14
- data/lib/configurate/provider/yaml.rb +34 -29
- data/lib/configurate/proxy.rb +7 -6
- data/lib/configurate/setting_path.rb +8 -4
- data/spec/configurate/lookup_chain_spec.rb +3 -3
- data/spec/configurate/provider/dynamic_spec.rb +6 -6
- data/spec/configurate/provider/env_spec.rb +10 -10
- data/spec/configurate/provider/yaml_spec.rb +33 -15
- data/spec/configurate/provider_spec.rb +14 -2
- data/spec/configurate/proxy_spec.rb +10 -11
- data/spec/configurate/setting_path_spec.rb +8 -9
- data/spec/configurate_spec.rb +2 -2
- data/spec/spec_helper.rb +3 -4
- metadata +7 -7
- 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
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cee20b7c12f6d7b03d65511ea8c501955dc437cc
|
4
|
+
data.tar.gz: 6b23db2069cf5b8128c9b2d1c6b1f3e1ddac26b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53094d245312357e844542e7342fc9c1e07c864320109c35a883bcd250bfcd81a81fffef41792cf092bb81f4ec96f61d5ba6faa577e79f0678dca2543a68c9ec
|
7
|
+
data.tar.gz: ddf023b472ebcd5388e6e454939970d7744add4784cf4d1d434fd1b6dfe9f5f8d9c0d4f7e20bd295dc97fd587a9eb5cd0a2afc13aaf18d897bdff4fec227fd11
|
data/Changelog.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# 0.3.0
|
2
|
+
|
3
|
+
* Add new exception: Configurate::MissingSetting to be raised and bubble up to the user
|
4
|
+
if a setting wasn't found and the user requested to be informed.
|
5
|
+
* Configurate::Provider::YAML got the new option raise_on_missing to raise
|
6
|
+
Configurate::MissingSetting if the requested key is not in the YAML document.
|
7
|
+
|
1
8
|
# 0.2.0
|
2
9
|
|
3
10
|
* Dynamic provider listens to reset_dynamic! message and forgets all settings on it.
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# Configurate - A flexible configuration system
|
2
2
|
[![Gem Version](https://badge.fury.io/rb/configurate.png)](https://rubygems.org/gems/configurate)
|
3
3
|
[![Build Status](https://secure.travis-ci.org/jhass/configurate.png?branch=master)](https://travis-ci.org/jhass/configurate)
|
4
|
-
[![Gemnasium](https://gemnasium.com/
|
5
|
-
[![Code Climate](https://codeclimate.com/github/jhass/configurate.png)](https://codeclimate.com/github/
|
6
|
-
[![Coverage Status](https://coveralls.io/repos/jhass/configurate/badge.
|
4
|
+
[![Gemnasium](https://gemnasium.com/jhass/configurate.png)](https://gemnasium.com/jhass/configurate)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/jhass/configurate.png)](https://codeclimate.com/github/jhass/configurate)
|
6
|
+
[![Coverage Status](https://coveralls.io/repos/jhass/configurate/badge.svg?branch=master)](https://coveralls.io/r/jhass/configurate?branch=master)
|
7
7
|
|
8
8
|
Configurate allows you to specify a chain of configuration providers which are
|
9
9
|
queried in order until one returns a value. This allows scenarios like overriding
|
@@ -11,7 +11,7 @@ your default settings with a user configuration file and let those be overridden
|
|
11
11
|
by environment variables. The query interface allows to group and nest your configuration options
|
12
12
|
to a practically unlimited level.
|
13
13
|
|
14
|
-
Configurate
|
14
|
+
Configurate supports Ruby 2.0 or later.
|
15
15
|
|
16
16
|
## Installation
|
17
17
|
|
data/lib/configurate.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require 'configurate/setting_path'
|
4
|
-
require 'configurate/lookup_chain'
|
5
|
-
require 'configurate/provider'
|
6
|
-
require 'configurate/proxy'
|
1
|
+
require "forwardable"
|
7
2
|
|
3
|
+
require "configurate/setting_path"
|
4
|
+
require "configurate/lookup_chain"
|
5
|
+
require "configurate/provider"
|
6
|
+
require "configurate/proxy"
|
8
7
|
|
9
8
|
# A flexible and extendable configuration system.
|
10
9
|
# The calling logic is isolated from the lookup logic
|
@@ -20,15 +19,15 @@ require 'configurate/proxy'
|
|
20
19
|
module Configurate
|
21
20
|
# This is your main entry point. Instead of lengthy explanations
|
22
21
|
# let an example demonstrate its usage:
|
23
|
-
#
|
22
|
+
#
|
24
23
|
# require 'configuration_methods'
|
25
|
-
#
|
24
|
+
#
|
26
25
|
# AppSettings = Configurate::Settings.create do
|
27
26
|
# add_provider Configurate::Provider::Env
|
28
27
|
# add_provider Configurate::Provider::YAML, '/etc/app_settings.yml',
|
29
28
|
# namespace: Rails.env, required: false
|
30
29
|
# add_provider Configurate::Provider::YAML, 'config/default_settings.yml'
|
31
|
-
#
|
30
|
+
#
|
32
31
|
# extend YourConfigurationMethods
|
33
32
|
# end
|
34
33
|
#
|
@@ -36,18 +35,17 @@ module Configurate
|
|
36
35
|
#
|
37
36
|
# Please also read the note at {Proxy}!
|
38
37
|
class Settings
|
39
|
-
|
40
38
|
attr_reader :lookup_chain
|
41
|
-
|
39
|
+
|
42
40
|
undef_method :method # Remove possible conflicts with common setting names
|
43
41
|
|
44
42
|
extend Forwardable
|
45
43
|
|
46
44
|
def initialize
|
47
45
|
@lookup_chain = LookupChain.new
|
48
|
-
|
46
|
+
warn "Warning you called Configurate::Settings.new with a block, you really meant to call #create" if block_given?
|
49
47
|
end
|
50
|
-
|
48
|
+
|
51
49
|
# @!method lookup(setting)
|
52
50
|
# (see {LookupChain#lookup})
|
53
51
|
|
@@ -63,15 +61,22 @@ module Configurate
|
|
63
61
|
def method_missing(method, *args, &block)
|
64
62
|
Proxy.new(@lookup_chain).public_send(method, *args, &block)
|
65
63
|
end
|
66
|
-
|
64
|
+
|
67
65
|
# Create a new configuration object
|
68
66
|
# @yield the given block will be evaluated in the context of the new object
|
69
67
|
def self.create(&block)
|
70
|
-
config =
|
68
|
+
config = new
|
71
69
|
config.instance_eval(&block) if block_given?
|
72
70
|
config
|
73
71
|
end
|
74
72
|
end
|
75
|
-
|
73
|
+
|
74
|
+
# This is supposed to be raised by providers if the requested setting
|
75
|
+
# does not exist, (remember, nil is a valid value and thus rarely a sufficient check)
|
76
|
+
# and this should be communicated to the end user.
|
77
|
+
class MissingSetting < RuntimeError; end
|
78
|
+
|
79
|
+
# This is supposed to be raised by providers if the requested setting
|
80
|
+
# cannot be found and the next provider in the chain should be tried.
|
76
81
|
class SettingNotFoundError < RuntimeError; end
|
77
82
|
end
|
@@ -21,7 +21,6 @@ module Configurate
|
|
21
21
|
@provider << provider.new(*args)
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
24
|
# Tries all providers in the order they were added to provide a response
|
26
25
|
# for setting.
|
27
26
|
#
|
@@ -45,19 +44,20 @@ module Configurate
|
|
45
44
|
private
|
46
45
|
|
47
46
|
def special_value_or_string(value)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
case value
|
48
|
+
when TrueClass, FalseClass, NilClass, Array, Hash
|
49
|
+
value
|
50
|
+
else
|
51
|
+
if value.respond_to?(:to_s)
|
52
|
+
case value.to_s.strip
|
52
53
|
when "true" then true
|
53
54
|
when "false" then false
|
54
55
|
when "", "nil" then nil
|
55
|
-
else value
|
56
|
+
else value.to_s
|
57
|
+
end
|
58
|
+
else
|
59
|
+
value
|
56
60
|
end
|
57
|
-
elsif value.respond_to?(:to_s)
|
58
|
-
return value.to_s
|
59
|
-
else
|
60
|
-
return value
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
data/lib/configurate/provider.rb
CHANGED
@@ -1,32 +1,34 @@
|
|
1
|
-
module Configurate
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
module Configurate
|
2
|
+
module Provider
|
3
|
+
# This provides a basic {#lookup} method for other providers to build
|
4
|
+
# upon. Childs are expected to define +lookup_path(path, *args)+.
|
5
|
+
# The method should return nil if the setting
|
6
|
+
# wasn't found and {#lookup} will raise an {SettingNotFoundError} in that
|
7
|
+
# case.
|
8
|
+
class Base
|
9
|
+
def lookup(*args)
|
10
|
+
result = lookup_path(*args)
|
11
|
+
return result unless result.nil?
|
12
|
+
raise Configurate::SettingNotFoundError, "The setting #{args.first} was not found"
|
13
|
+
end
|
12
14
|
end
|
13
|
-
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
# Utility function to lookup a settings path in a hash
|
17
|
+
# @param setting_path [SettingPath]
|
18
|
+
# @param hash [Hash]
|
19
|
+
# @yield fallback value if not found
|
20
|
+
# @return [Object]
|
21
|
+
def self.lookup_in_hash setting_path, hash, &fallback
|
22
|
+
fallback ||= proc { nil }
|
23
|
+
while hash.is_a?(Hash) && hash.has_key?(setting_path.first) && !setting_path.empty?
|
24
|
+
hash = hash[setting_path.shift]
|
25
|
+
end
|
26
|
+
return fallback.call unless setting_path.empty?
|
27
|
+
hash
|
24
28
|
end
|
25
|
-
return fallback.call unless setting_path.empty?
|
26
|
-
hash
|
27
29
|
end
|
28
|
-
end
|
30
|
+
end
|
29
31
|
|
30
|
-
require
|
31
|
-
require
|
32
|
-
require
|
32
|
+
require "configurate/provider/yaml"
|
33
|
+
require "configurate/provider/env"
|
34
|
+
require "configurate/provider/dynamic"
|
@@ -1,30 +1,38 @@
|
|
1
|
-
module Configurate
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
module Configurate
|
2
|
+
module Provider
|
3
|
+
# This provider knows nothing upon initialization, however if you access
|
4
|
+
# a setting ending with +=+ and give one argument to that call it remembers
|
5
|
+
# that setting, stripping the +=+ and will return it on the next call
|
6
|
+
# without +=+. Sending +reset_dynamic!+ to it will make it forget all
|
7
|
+
# settings. Also assigning nil will have the effect of it forgetting
|
8
|
+
# a setting.
|
9
|
+
class Dynamic < Base
|
10
|
+
def lookup_path(setting_path, *args)
|
11
|
+
if setting_path.to_s == "reset_dynamic!"
|
12
|
+
@settings = nil
|
13
|
+
return
|
14
|
+
end
|
15
|
+
|
16
|
+
if setting_path.setter? && args.length > 0
|
17
|
+
*root, key = setting_path.to_a
|
18
|
+
hash = root.inject(settings) {|hash, key| hash[key] }
|
19
|
+
hash[key] = extract_value(args)
|
20
|
+
end
|
21
|
+
|
22
|
+
Provider.lookup_in_hash setting_path, settings
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
12
26
|
|
13
|
-
|
14
|
-
|
15
|
-
@settings = {}
|
16
|
-
return
|
27
|
+
def settings
|
28
|
+
@settings ||= Hash.new {|hash, key| hash[key] = Hash.new(&hash.default_proc) }
|
17
29
|
end
|
18
30
|
|
19
|
-
|
31
|
+
def extract_value args
|
20
32
|
value = args.first
|
21
33
|
value = value.get if value.respond_to?(:_proxy?) && value._proxy?
|
22
|
-
|
23
|
-
hash = root.inject(@settings) {|hash, key| hash[key] ||= {} }
|
24
|
-
hash[key] = value
|
34
|
+
value
|
25
35
|
end
|
26
|
-
|
27
|
-
Provider.lookup_in_hash setting_path, @settings
|
28
36
|
end
|
29
37
|
end
|
30
|
-
end
|
38
|
+
end
|
@@ -1,17 +1,19 @@
|
|
1
|
-
module Configurate
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
module Configurate
|
2
|
+
module Provider
|
3
|
+
# This provider looks for settings in the environment.
|
4
|
+
# For the setting +foo.bar_baz+ this provider will look for an
|
5
|
+
# environment variable +FOO_BAR_BAZ+, joining all components of the
|
6
|
+
# setting with underscores and upcasing the result.
|
7
|
+
# If an value contains any commas (,) it's split at them and returned as array.
|
8
|
+
class Env < Base
|
9
|
+
def lookup_path(setting_path, *_args)
|
10
|
+
value = ENV[setting_path.join("_").upcase]
|
11
|
+
unless value.nil?
|
12
|
+
value = value.dup
|
13
|
+
value = value.split(",") if value.include?(",")
|
14
|
+
end
|
15
|
+
value
|
13
16
|
end
|
14
|
-
value
|
15
17
|
end
|
16
18
|
end
|
17
|
-
end
|
19
|
+
end
|
@@ -1,37 +1,42 @@
|
|
1
|
-
require
|
1
|
+
require "yaml"
|
2
2
|
|
3
|
-
module Configurate
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
@
|
16
|
-
|
3
|
+
module Configurate
|
4
|
+
module Provider
|
5
|
+
# This provider tries to open a YAML file and does nested lookups
|
6
|
+
# in it.
|
7
|
+
class YAML < Base
|
8
|
+
# @param file [String] the path to the file
|
9
|
+
# @param namespace [String] optionally set this as the root
|
10
|
+
# @param required [Boolean] whether or not to raise an error if
|
11
|
+
# the file or the namespace, if given, is not found. Defaults to +true+.
|
12
|
+
# @param raise_on_missing [Boolean] whether to raise {Configurate::MissingSetting}
|
13
|
+
# if a setting can't be provided. Defaults to +false+.
|
14
|
+
# @raise [ArgumentError] if the namespace isn't found in the file
|
15
|
+
# @raise [Errno:ENOENT] if the file isn't found
|
16
|
+
def initialize file, namespace: nil, required: true, raise_on_missing: false
|
17
|
+
@raise_on_missing = raise_on_missing
|
18
|
+
@settings = {}
|
17
19
|
|
18
|
-
|
20
|
+
@settings = ::YAML.load_file(file)
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
unless namespace.nil?
|
23
|
+
@settings = Provider.lookup_in_hash(SettingPath.new(namespace), @settings) do
|
24
|
+
raise ArgumentError, "Namespace #{namespace} not found in #{file}" if required
|
25
|
+
$stderr.puts "WARNING: Namespace #{namespace} not found in #{file}"
|
26
|
+
nil
|
27
|
+
end
|
26
28
|
end
|
29
|
+
rescue Errno::ENOENT => e
|
30
|
+
warn "WARNING: Configuration file #{file} not found, ensure it's present"
|
31
|
+
raise e if required
|
27
32
|
end
|
28
|
-
rescue Errno::ENOENT => e
|
29
|
-
$stderr.puts "WARNING: Configuration file #{file} not found, ensure it's present"
|
30
|
-
raise e if required
|
31
|
-
end
|
32
33
|
|
33
|
-
|
34
|
-
|
34
|
+
def lookup_path setting_path, *_
|
35
|
+
Provider.lookup_in_hash(setting_path, @settings) {
|
36
|
+
raise MissingSetting.new "#{setting_path} is not a valid setting." if @raise_on_missing
|
37
|
+
nil
|
38
|
+
}
|
39
|
+
end
|
35
40
|
end
|
36
41
|
end
|
37
|
-
end
|
42
|
+
end
|
data/lib/configurate/proxy.rb
CHANGED
@@ -23,17 +23,17 @@ module Configurate
|
|
23
23
|
!target
|
24
24
|
end
|
25
25
|
|
26
|
-
|
26
|
+
%i(!= == eql? coerce).each do |method|
|
27
27
|
define_method method do |other|
|
28
28
|
target.public_send method, target_or_object(other)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
{
|
33
|
-
|
34
|
-
:
|
35
|
-
|
36
|
-
|
33
|
+
to_int: :to_i,
|
34
|
+
to_hash: :to_h,
|
35
|
+
to_str: :to_s,
|
36
|
+
to_ary: :to_a
|
37
37
|
}.each do |method, converter|
|
38
38
|
define_method method do
|
39
39
|
value = target
|
@@ -75,7 +75,8 @@ module Configurate
|
|
75
75
|
alias_method :get, :target
|
76
76
|
|
77
77
|
private
|
78
|
-
|
78
|
+
|
79
|
+
COMMON_KEY_NAMES = %i(key method)
|
79
80
|
|
80
81
|
def target_respond_to? setting, include_private=false
|
81
82
|
return false if COMMON_KEY_NAMES.include? setting
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "forwardable"
|
2
2
|
|
3
3
|
module Configurate
|
4
4
|
# Class encapsulating the concept of a path to a setting
|
@@ -45,13 +45,13 @@ module Configurate
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
|
48
|
+
%i(join first last shift pop).each do |method|
|
49
49
|
define_method method do |*args|
|
50
50
|
clean_special_characters @path.public_send(method, *args)
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
|
54
|
+
%i(<< unshift push).each do |method|
|
55
55
|
define_method method do |*args|
|
56
56
|
@path.public_send method, *args.map(&:to_s)
|
57
57
|
end
|
@@ -66,7 +66,11 @@ module Configurate
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def inspect
|
69
|
-
"<SettingPath:#{object_id.to_s(16)}
|
69
|
+
"<SettingPath:#{object_id.to_s(16)} "\
|
70
|
+
"path=#{self}:#{@path.object_id.to_s(16)} "\
|
71
|
+
"question=#{question?} "\
|
72
|
+
"action=#{action?} "\
|
73
|
+
"setter=#{setter?}>"
|
70
74
|
end
|
71
75
|
|
72
76
|
private
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
class InvalidConfigurationProvider; end
|
4
4
|
class ValidConfigurationProvider
|
5
|
-
def lookup(
|
5
|
+
def lookup(_setting, *_args); end
|
6
6
|
end
|
7
7
|
|
8
8
|
describe Configurate::LookupChain do
|
@@ -97,7 +97,7 @@ describe Configurate::LookupChain do
|
|
97
97
|
end
|
98
98
|
|
99
99
|
it "returns nil if no value is found" do
|
100
|
-
@provider.each {
|
100
|
+
@provider.each {|p| allow(p).to receive(:lookup).and_raise(Configurate::SettingNotFoundError) }
|
101
101
|
expect(subject.lookup "not.me").to be_nil
|
102
102
|
end
|
103
103
|
end
|
@@ -1,16 +1,16 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Configurate::Provider::Dynamic do
|
4
4
|
subject { described_class.new }
|
5
5
|
describe "#lookup_path" do
|
6
6
|
it "returns nil if the setting was never set" do
|
7
|
-
expect(subject.lookup_path Configurate::SettingPath.new(["not_me"])
|
7
|
+
expect(subject.lookup_path Configurate::SettingPath.new(["not_me"])).to be_nil
|
8
8
|
end
|
9
9
|
|
10
10
|
it "remembers the setting if it ends with =" do
|
11
11
|
subject.lookup_path Configurate::SettingPath.new(["find_me", "later="]), "there"
|
12
12
|
|
13
|
-
expect(subject.lookup_path Configurate::SettingPath.new(
|
13
|
+
expect(subject.lookup_path Configurate::SettingPath.new(%w(find_me later))).to eq "there"
|
14
14
|
end
|
15
15
|
|
16
16
|
it "calls .get on the argument if a proxy object is given" do
|
@@ -20,14 +20,14 @@ describe Configurate::Provider::Dynamic do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
it "resolves nested calls after group assignment" do
|
23
|
-
subject.lookup_path Configurate::SettingPath.new(
|
24
|
-
expect(subject.lookup_path Configurate::SettingPath.new(
|
23
|
+
subject.lookup_path Configurate::SettingPath.new(%w(find_me later=)), "a" => "b"
|
24
|
+
expect(subject.lookup_path Configurate::SettingPath.new(%w(find_me later a))).to eq "b"
|
25
25
|
end
|
26
26
|
|
27
27
|
it "clears out all overrides on reset_dynamic!" do
|
28
28
|
subject.lookup_path Configurate::SettingPath.new(["find_me", "later="]), "there"
|
29
29
|
subject.lookup_path Configurate::SettingPath.new(["reset_dynamic!"])
|
30
|
-
expect(subject.lookup_path Configurate::SettingPath.new(
|
30
|
+
expect(subject.lookup_path Configurate::SettingPath.new(%w(find_me later))).to_not eq "there"
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -1,21 +1,21 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Configurate::Provider::Env do
|
4
4
|
subject { described_class.new }
|
5
|
-
let(:existing_path) {
|
6
|
-
let(:not_existing_path) {
|
7
|
-
let(:array_path) { [
|
5
|
+
let(:existing_path) { %w(existing setting) }
|
6
|
+
let(:not_existing_path) { %w(not existing path) }
|
7
|
+
let(:array_path) { ["array"] }
|
8
8
|
before(:all) do
|
9
|
-
ENV[
|
10
|
-
ENV[
|
9
|
+
ENV["EXISTING_SETTING"] = "there"
|
10
|
+
ENV["ARRAY"] = "foo,bar,baz"
|
11
11
|
end
|
12
12
|
|
13
13
|
after(:all) do
|
14
|
-
ENV[
|
15
|
-
ENV[
|
14
|
+
ENV["EXISTING_SETTING"] = nil
|
15
|
+
ENV["ARRAY"] = nil
|
16
16
|
end
|
17
17
|
|
18
|
-
describe
|
18
|
+
describe "#lookup_path" do
|
19
19
|
it "joins and upcases the path" do
|
20
20
|
expect(ENV).to receive(:[]).with("EXISTING_SETTING")
|
21
21
|
subject.lookup_path existing_path
|
@@ -26,7 +26,7 @@ describe Configurate::Provider::Env do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
it "makes an array out of comma separated values" do
|
29
|
-
expect(subject.lookup_path array_path).to eq
|
29
|
+
expect(subject.lookup_path array_path).to eq %w(foo bar baz)
|
30
30
|
end
|
31
31
|
|
32
32
|
it "returns a unfrozen string" do
|
@@ -1,11 +1,14 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Configurate::Provider::YAML do
|
4
|
-
let(:settings) {
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
let(:settings) {
|
5
|
+
{
|
6
|
+
"toplevel" => "bar",
|
7
|
+
"some" => {
|
8
|
+
"nested" => {"some" => "lala", "setting" => "foo"}
|
9
|
+
}
|
10
|
+
}
|
11
|
+
}
|
9
12
|
|
10
13
|
describe "#initialize" do
|
11
14
|
it "loads the file" do
|
@@ -23,26 +26,25 @@ describe Configurate::Provider::YAML do
|
|
23
26
|
}.to raise_error Errno::ENOENT
|
24
27
|
end
|
25
28
|
|
26
|
-
|
27
29
|
context "with a namespace" do
|
28
30
|
it "looks in the file for that namespace" do
|
29
31
|
namespace = "some.nested"
|
30
32
|
allow(::YAML).to receive(:load_file).and_return(settings)
|
31
|
-
provider = described_class.new
|
32
|
-
expect(provider.instance_variable_get :@settings).to eq settings[
|
33
|
+
provider = described_class.new "bla", namespace: namespace
|
34
|
+
expect(provider.instance_variable_get :@settings).to eq settings["some"]["nested"]
|
33
35
|
end
|
34
36
|
|
35
37
|
it "raises if the namespace isn't found" do
|
36
38
|
allow(::YAML).to receive(:load_file).and_return({})
|
37
39
|
expect {
|
38
|
-
described_class.new
|
40
|
+
described_class.new "bla", namespace: "bar"
|
39
41
|
}.to raise_error
|
40
42
|
end
|
41
43
|
|
42
44
|
it "works with an empty namespace in the file" do
|
43
|
-
allow(::YAML).to receive(:load_file).and_return(
|
45
|
+
allow(::YAML).to receive(:load_file).and_return("foo" => {"bar" => nil})
|
44
46
|
expect {
|
45
|
-
described_class.new
|
47
|
+
described_class.new "bla", namespace: "foo.bar"
|
46
48
|
}.to_not raise_error
|
47
49
|
end
|
48
50
|
end
|
@@ -58,7 +60,7 @@ describe Configurate::Provider::YAML do
|
|
58
60
|
it "doesn't raise if a namespace isn't found" do
|
59
61
|
allow(::YAML).to receive(:load_file).and_return({})
|
60
62
|
expect {
|
61
|
-
described_class.new
|
63
|
+
described_class.new "bla", namespace: "foo", required: false
|
62
64
|
}.not_to raise_error
|
63
65
|
end
|
64
66
|
end
|
@@ -67,15 +69,31 @@ describe Configurate::Provider::YAML do
|
|
67
69
|
describe "#lookup_path" do
|
68
70
|
before do
|
69
71
|
allow(::YAML).to receive(:load_file).and_return(settings)
|
70
|
-
@provider = described_class.new
|
72
|
+
@provider = described_class.new "dummy"
|
71
73
|
end
|
72
74
|
|
73
75
|
it "looks up the whole nesting" do
|
74
|
-
expect(@provider.lookup_path
|
76
|
+
expect(@provider.lookup_path %w(some nested some)).to eq settings["some"]["nested"]["some"]
|
75
77
|
end
|
76
78
|
|
77
79
|
it "returns nil if no setting is found" do
|
78
80
|
expect(@provider.lookup_path ["not_me"]).to be_nil
|
79
81
|
end
|
82
|
+
|
83
|
+
context "with raise_on_missing set to true" do
|
84
|
+
before do
|
85
|
+
@provider = described_class.new "dummy", raise_on_missing: true
|
86
|
+
end
|
87
|
+
|
88
|
+
it "looks up the whole nesting" do
|
89
|
+
expect(@provider.lookup_path %w(some nested some)).to eq settings["some"]["nested"]["some"]
|
90
|
+
end
|
91
|
+
|
92
|
+
it "returns nil if no setting is found" do
|
93
|
+
expect {
|
94
|
+
@provider.lookup_path ["not_me"]
|
95
|
+
}.to raise_error Configurate::MissingSetting
|
96
|
+
end
|
97
|
+
end
|
80
98
|
end
|
81
99
|
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Configurate::Provider::Base do
|
4
4
|
describe "#lookup" do
|
5
5
|
subject { described_class.new }
|
6
6
|
it "calls #lookup_path" do
|
7
|
-
path = Configurate::SettingPath.new(
|
7
|
+
path = Configurate::SettingPath.new(%w(foo bar))
|
8
8
|
expect(subject).to receive(:lookup_path).with(path).and_return("something")
|
9
9
|
expect(subject.lookup(path)).to eq "something"
|
10
10
|
end
|
@@ -15,5 +15,17 @@ describe Configurate::Provider::Base do
|
|
15
15
|
subject.lookup("bla")
|
16
16
|
}.to raise_error Configurate::SettingNotFoundError
|
17
17
|
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "::lookup_in_hash" do
|
22
|
+
let(:hash) { {foo: {bar: nil}} }
|
23
|
+
it "returns nil if key is nil" do
|
24
|
+
expect(Configurate::Provider.lookup_in_hash(%i(foo bar), hash) { :fallback }).to be_nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns fallback for a non-existent key" do
|
28
|
+
expect(Configurate::Provider.lookup_in_hash(%i(foo bar baz), hash) { :fallback }).to eq :fallback
|
29
|
+
end
|
18
30
|
end
|
19
31
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Configurate::Proxy do
|
4
4
|
let(:lookup_chain) { double(lookup: "something") }
|
@@ -9,9 +9,9 @@ describe Configurate::Proxy do
|
|
9
9
|
pending "If anyone knows a sane way to overwrite Module#===, please tell me :P"
|
10
10
|
result = case proxy
|
11
11
|
when String
|
12
|
-
|
12
|
+
"string"
|
13
13
|
else
|
14
|
-
|
14
|
+
"wrong"
|
15
15
|
end
|
16
16
|
expect(result).to eq "string"
|
17
17
|
end
|
@@ -54,9 +54,8 @@ describe Configurate::Proxy do
|
|
54
54
|
end
|
55
55
|
|
56
56
|
describe "#target" do
|
57
|
-
|
58
|
-
|
59
|
-
:start_with?, :end_with?].each do |method|
|
57
|
+
%i(to_s to_xml respond_to? present? != eql? each try size length
|
58
|
+
count == =~ gsub blank? chop start_with? end_with?).each do |method|
|
60
59
|
it "is called for accessing #{method} on the proxy" do
|
61
60
|
target = double(respond_to?: true, _proxy?: false)
|
62
61
|
allow(lookup_chain).to receive(:lookup).and_return(target)
|
@@ -80,22 +79,22 @@ describe Configurate::Proxy do
|
|
80
79
|
|
81
80
|
it "converts to a string" do
|
82
81
|
allow(lookup_chain).to receive(:lookup).and_return("bar")
|
83
|
-
expect("foo
|
82
|
+
expect("foo#{proxy.something}").to eq "foobar"
|
84
83
|
end
|
85
84
|
|
86
85
|
it "converts to a number" do
|
87
86
|
allow(lookup_chain).to receive(:lookup).and_return(1)
|
88
|
-
expect(2+proxy.something).to eq 3
|
87
|
+
expect(2 + proxy.something).to eq 3
|
89
88
|
end
|
90
89
|
|
91
90
|
it "converts to an array" do
|
92
91
|
allow(lookup_chain).to receive(:lookup).and_return([1, 2])
|
93
|
-
expect(
|
92
|
+
expect(%i(a b).zip(proxy.something)).to eq [[:a, 1], [:b, 2]]
|
94
93
|
end
|
95
94
|
|
96
95
|
it "converts to a hash" do
|
97
|
-
allow(lookup_chain).to receive(:lookup).and_return(
|
98
|
-
expect({c: :d}.merge(proxy.something)).to eq
|
96
|
+
allow(lookup_chain).to receive(:lookup).and_return(a: :b)
|
97
|
+
expect({c: :d}.merge(proxy.something)).to eq a: :b, c: :d
|
99
98
|
end
|
100
99
|
end
|
101
100
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Configurate::SettingPath do
|
4
4
|
let(:normal_path) { described_class.new([:foo]) }
|
@@ -53,7 +53,7 @@ describe Configurate::SettingPath do
|
|
53
53
|
|
54
54
|
describe "#initialize_copy" do
|
55
55
|
it "modifying a copy leaves the original unchanged" do
|
56
|
-
original = described_class.new
|
56
|
+
original = described_class.new %w(foo bar)
|
57
57
|
copy = original.clone
|
58
58
|
copy << "baz"
|
59
59
|
expect(copy).to include "baz"
|
@@ -61,7 +61,6 @@ describe Configurate::SettingPath do
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
-
|
65
64
|
describe "#question_action_or_setter?" do
|
66
65
|
context "with a question signature as setting" do
|
67
66
|
subject { question_path.question_action_or_setter? }
|
@@ -86,22 +85,22 @@ describe Configurate::SettingPath do
|
|
86
85
|
|
87
86
|
describe "#each" do
|
88
87
|
it "should strip special characters" do
|
89
|
-
expect(long_path.all? {
|
88
|
+
expect(long_path.all? {|c| c.include? "?" }).to be_falsey
|
90
89
|
end
|
91
90
|
end
|
92
91
|
|
93
|
-
|
92
|
+
%i(join first last shift pop).each do |method|
|
94
93
|
describe "##{method}" do
|
95
94
|
subject { question_path.public_send method }
|
96
95
|
it { should_not include "?" }
|
97
96
|
end
|
98
97
|
end
|
99
98
|
|
100
|
-
|
99
|
+
%i(<< unshift push).each do |method|
|
101
100
|
describe "##{method}" do
|
102
|
-
it
|
101
|
+
it "converts the argument to a string" do
|
103
102
|
arg = double
|
104
|
-
expect(arg).to receive(:to_s).and_return(
|
103
|
+
expect(arg).to receive(:to_s).and_return("bar")
|
105
104
|
described_class.new.public_send method, arg
|
106
105
|
end
|
107
106
|
end
|
@@ -120,7 +119,7 @@ describe Configurate::SettingPath do
|
|
120
119
|
|
121
120
|
describe "#inspect" do
|
122
121
|
it "includes the dotted path" do
|
123
|
-
path = described_class.new(
|
122
|
+
path = described_class.new(%i(foo bar))
|
124
123
|
expect(path.inspect).to include "foo.bar"
|
125
124
|
end
|
126
125
|
end
|
data/spec/configurate_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Configurate::Settings do
|
4
4
|
describe "#method_missing" do
|
@@ -12,7 +12,7 @@ describe Configurate::Settings do
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
|
15
|
+
%i(lookup add_provider []).each do |method|
|
16
16
|
describe "#{method}" do
|
17
17
|
subject { described_class.create }
|
18
18
|
|
data/spec/spec_helper.rb
CHANGED
@@ -5,13 +5,12 @@
|
|
5
5
|
#
|
6
6
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
7
|
|
8
|
-
|
9
8
|
begin
|
10
|
-
require
|
9
|
+
require "coveralls"
|
11
10
|
Coveralls.wear!
|
12
11
|
rescue LoadError; end
|
13
12
|
|
14
|
-
require
|
13
|
+
require "configurate"
|
15
14
|
|
16
15
|
def silence_stderr
|
17
16
|
$stderr = StringIO.new
|
@@ -27,7 +26,7 @@ RSpec.configure do |config|
|
|
27
26
|
# order dependency and want to debug it, you can fix the order by providing
|
28
27
|
# the seed, which is printed after each run.
|
29
28
|
# --seed 1234
|
30
|
-
config.order =
|
29
|
+
config.order = "random"
|
31
30
|
|
32
31
|
config.expect_with :rspec do |expect_config|
|
33
32
|
expect_config.syntax = :expect
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: configurate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonne Haß
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -85,18 +85,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
85
|
version: '0'
|
86
86
|
requirements: []
|
87
87
|
rubyforge_project:
|
88
|
-
rubygems_version: 2.4.
|
88
|
+
rubygems_version: 2.4.5
|
89
89
|
signing_key:
|
90
90
|
specification_version: 4
|
91
91
|
summary: Flexbile configuration system
|
92
92
|
test_files:
|
93
|
-
- spec/configurate/provider_spec.rb
|
94
|
-
- spec/configurate/lookup_chain_spec.rb
|
95
|
-
- spec/configurate/provider/yaml_spec.rb
|
96
|
-
- spec/configurate/provider/env_spec.rb
|
97
93
|
- spec/configurate/provider/dynamic_spec.rb
|
94
|
+
- spec/configurate/provider/env_spec.rb
|
95
|
+
- spec/configurate/provider/yaml_spec.rb
|
98
96
|
- spec/configurate/setting_path_spec.rb
|
99
97
|
- spec/configurate/proxy_spec.rb
|
98
|
+
- spec/configurate/provider_spec.rb
|
99
|
+
- spec/configurate/lookup_chain_spec.rb
|
100
100
|
- spec/spec_helper.rb
|
101
101
|
- spec/configurate_spec.rb
|
102
102
|
has_rdoc:
|
checksums.yaml.gz.asc
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
-----BEGIN PGP SIGNATURE-----
|
2
|
-
Version: GnuPG v2
|
3
|
-
|
4
|
-
iQEcBAABAgAGBQJULyg7AAoJEPNH4OtHrHDWLzkIAIwwqTjkZlNOPS2D7tUOcNJY
|
5
|
-
ZF/zxymbrSL9yjzXwvYExgKy2i1xV5LrWpWP/mCiX9RX2eLxv8LcQGlWKupCwMc9
|
6
|
-
2ca/yy1wziXLhLY6zJhWF5j6WNOfRlJTGaAUPSHtbCeT9WOjbpnDWfWTDZKNuonb
|
7
|
-
i1HPUCZPx+YAXb6Gzgl39FcCH1UgEZy3D3ijc3FCSHigfnwSEDcjCwQtQuMedwNu
|
8
|
-
l1/V5UdTPDiWPBxeGMucyZLBKdN8r70wfgNKvDZ1XHolO+9HUOsmcS6St1P5OpUp
|
9
|
-
dJ25Tm3ACv+uydyQLr/e2bPJs+Lm901rKUMb+gIozoQCYMTRnpAoNMVNqK+KRBI=
|
10
|
-
=+ZIR
|
11
|
-
-----END PGP SIGNATURE-----
|
data.tar.gz.asc
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
-----BEGIN PGP SIGNATURE-----
|
2
|
-
Version: GnuPG v2
|
3
|
-
|
4
|
-
iQEcBAABAgAGBQJULyg7AAoJEPNH4OtHrHDWgO0H/jLKCQPi2kguHzfJU/k4hII8
|
5
|
-
VITtYbNZb4ZBbHecgiam4mI+m5EvDCfQu3KEzSN3w06czUoVFW0uCABJkAqb43He
|
6
|
-
EvITE2z36GKFb8GqfA5EXnRPjmsGTvH8EnUG8DetTRNjFkERvNSi6t3RxgfNQ8yw
|
7
|
-
UFwtascrsmM5vjzCvgRlJ0cm1HA3LZFqoEyw/MovOLDviLTz1ECKqxNmaEULdhp9
|
8
|
-
Fb10e5Y9XalRbbF6wSOKWp06owiEcTVY/lqNOZBJ+ZIG1RQUD73yhAGW2b7bM6rg
|
9
|
-
tiBEAal1Tt6c5v5SvucCcMrKxd3R8CXCtwETQVFl4rxB4eYhSgx0PkFiQ3OPicY=
|
10
|
-
=hJkd
|
11
|
-
-----END PGP SIGNATURE-----
|
metadata.gz.asc
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
-----BEGIN PGP SIGNATURE-----
|
2
|
-
Version: GnuPG v2
|
3
|
-
|
4
|
-
iQEcBAABAgAGBQJULyg7AAoJEPNH4OtHrHDWD0IH/0e90hWnDOQqWhUnKY3JM+gf
|
5
|
-
wOdHXiyB4p7cPIoO6QFsZq0Mm4t+bYLADI3adDq9kQAtIjo6s3jUJzK84QNjnsNS
|
6
|
-
8Sc1OWNFYLrMVi/7rkJfyjiV6rMHYyB9O76vxH3w7/CZAl7fscadF4BW1PTqcti8
|
7
|
-
z4IoXtBs5KVxk1U3vtpPLaYitYIx/mc2voL0Z5wEuMeBhTYHjx4XraLrNzuSh6yN
|
8
|
-
cRnItaD70Z2uIvRF6bSyazDLWEO2cUfH/kTjsjHja4xwa4yYm3/ZkFZ2YZAXJNvU
|
9
|
-
P5mtnv5cCcJKZy1uNKV5DRj9zATL+yrzgSaSKV1O9BPW7zL3eHeu156TOxIRW48=
|
10
|
-
=sUo3
|
11
|
-
-----END PGP SIGNATURE-----
|