econfig 0.1.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +80 -47
- data/Rakefile +5 -0
- data/econfig.gemspec +3 -0
- data/lib/econfig.rb +12 -12
- data/lib/econfig/backend_collection.rb +61 -0
- data/lib/econfig/configuration.rb +25 -16
- data/lib/econfig/redis.rb +2 -2
- data/lib/econfig/shortcut.rb +2 -6
- data/lib/econfig/version.rb +1 -1
- data/lib/econfig/yaml.rb +3 -2
- data/spec/backend_collection_spec.rb +101 -0
- data/spec/config/app.yml +1 -0
- data/spec/configuration_spec.rb +61 -28
- data/spec/redis_spec.rb +2 -2
- data/spec/shortcut_spec.rb +3 -9
- data/spec/yaml_spec.rb +15 -1
- metadata +22 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c5fb4ddc1d04e679fa21343c08f42bbe036033b
|
4
|
+
data.tar.gz: 2bbfcc7f840f8332c6257cc7a97937284c78a607
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 62fa0da6fb4838ccca0e12f48c2ee9f8b91ce4641554a3b1f2c88315f09b7b68816170e5a10fa1f684cda33e07a28f78d40d7a59d01cf505993d542fb05c5d0d
|
7
|
+
data.tar.gz: 5f00b0e0828f7084f589ecae5d8ba0594555db22a5d6a6d4d4012099438dee17e3620acfa4ef58e42d4ad8d1df0e4687472ac8adb5c1aca43f815cfa6c4714b2
|
data/README.md
CHANGED
@@ -1,53 +1,48 @@
|
|
1
1
|
# Econfig
|
2
2
|
|
3
|
-
Econfig is a gem which allows you to easily configure your
|
3
|
+
Econfig is a gem which allows you to easily configure your Ruby applications
|
4
4
|
in a multitude of ways.
|
5
5
|
|
6
6
|
## Installation
|
7
7
|
|
8
|
-
Add this to your
|
8
|
+
Add this to your Gemfile:
|
9
9
|
|
10
10
|
``` ruby
|
11
|
-
gem "econfig"
|
11
|
+
gem "econfig"
|
12
12
|
```
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
Econfig extends the Rails configuration, you can use it like this:
|
14
|
+
If you're using Rails, you'll want to require the Rails extension:
|
17
15
|
|
18
16
|
``` ruby
|
19
|
-
|
17
|
+
gem "econfig", require: "econfig/rails"
|
20
18
|
```
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
## Accessing config options
|
21
|
+
|
22
|
+
Extend your main application module with the Econfig shortcut. In Rails, you'll
|
23
|
+
want to add this in `config/application.rb`:
|
25
24
|
|
26
25
|
``` ruby
|
27
26
|
module MyApp
|
28
27
|
extend Econfig::Shortcut
|
29
28
|
|
30
|
-
|
29
|
+
class Application < Rails::Application
|
30
|
+
…
|
31
|
+
end
|
31
32
|
end
|
32
33
|
```
|
33
34
|
|
34
|
-
|
35
|
+
Now you can access configuration like this:
|
35
36
|
|
36
37
|
``` ruby
|
37
|
-
MyApp.aws_access_key_id
|
38
|
+
MyApp.config.aws_access_key_id
|
38
39
|
```
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
## Forcing an option to exist
|
44
|
-
|
45
|
-
Sometimes you want the application to crash early when a given config option is
|
46
|
-
not set. Just add a bang (!) after the option name, and an error will be thrown
|
47
|
-
if it is not set to a value which is present.
|
41
|
+
If the key you accessed is not configured, Econfig will raise an error. To
|
42
|
+
access optional configuration, which can be nil, use brackets:
|
48
43
|
|
49
44
|
``` ruby
|
50
|
-
MyApp.aws_access_key_id
|
45
|
+
MyApp.config[:aws_access_key_id]
|
51
46
|
```
|
52
47
|
|
53
48
|
## Configuring options.
|
@@ -58,14 +53,16 @@ You can specify configuration through:
|
|
58
53
|
2. Redis
|
59
54
|
3. Relational database
|
60
55
|
4. YAML files
|
56
|
+
5. OSX Keychain
|
61
57
|
|
62
|
-
This allows you to set up
|
58
|
+
This allows you to set up Econfig on most kinds of hosting solutions
|
63
59
|
(EngineYard, Heroku, etc) without any additional effort, and to switch between
|
64
|
-
them easily.
|
60
|
+
them easily.
|
65
61
|
|
66
62
|
### ENV variables
|
67
63
|
|
68
|
-
Just set an environment variable whose name is the name of the option being
|
64
|
+
Just set an environment variable whose name is the name of the option being
|
65
|
+
accessed uppercased.
|
69
66
|
|
70
67
|
For example:
|
71
68
|
|
@@ -73,14 +70,46 @@ For example:
|
|
73
70
|
AWS_ACCESS_KEY_ID=xyz rails server
|
74
71
|
```
|
75
72
|
|
73
|
+
You can now read it like this:
|
74
|
+
|
75
|
+
``` ruby
|
76
|
+
MyApp.config.aws_access_key_id # => "xyz"
|
77
|
+
```
|
78
|
+
|
76
79
|
This is especially convenient for Heroku.
|
77
80
|
|
81
|
+
### YAML
|
82
|
+
|
83
|
+
Add a yaml file to `config/app.yml`. This should have a similar layout to `config/database.yml`:
|
84
|
+
|
85
|
+
``` yaml
|
86
|
+
development:
|
87
|
+
aws_access_key_id: "xyz"
|
88
|
+
aws_secret_access_key: "xyz"
|
89
|
+
production:
|
90
|
+
aws_access_key_id: "xyz"
|
91
|
+
aws_secret_access_key: "xyz"
|
92
|
+
```
|
93
|
+
|
94
|
+
Econfig also reads configuration from `config/secret.yml` which is the new
|
95
|
+
standard for secret configuration parameters in Rails 4.1.
|
96
|
+
|
78
97
|
### Relational database
|
79
98
|
|
80
|
-
This needs to be explicitly enabled. In `config/application.rb` add this
|
99
|
+
This needs to be explicitly enabled. In `config/application.rb` add this code:
|
100
|
+
|
101
|
+
``` ruby
|
102
|
+
require "econfig/active_record"
|
103
|
+
Econfig.backends.insert_after :env, :db, Econfig::ActiveRecord.new
|
104
|
+
```
|
105
|
+
|
106
|
+
You probably want environment variables to take precendence over configuration
|
107
|
+
from ActiveRecord, hence the `insert_after`. If you'd rather have ActiveRecord
|
108
|
+
configuration take precendence you can use this instead:
|
81
109
|
|
82
110
|
``` ruby
|
83
|
-
|
111
|
+
require "econfig/active_record"
|
112
|
+
Econfig.backends.unshift :db, Econfig::ActiveRecord.new
|
84
113
|
```
|
85
114
|
|
86
115
|
You will also need to create a migration to create the necessary database tables:
|
@@ -90,41 +119,45 @@ rails generate econfig:migration
|
|
90
119
|
rake db:migrate
|
91
120
|
```
|
92
121
|
|
93
|
-
|
122
|
+
### Redis
|
123
|
+
|
124
|
+
This needs to be explicitly enabled. In `config/application.rb` add this code:
|
94
125
|
|
95
126
|
``` ruby
|
96
|
-
|
127
|
+
require "econfig/redis"
|
128
|
+
redis = Redis.new(:host => "myredis.com")
|
129
|
+
Econfig.backends.insert_after :env, :redis, Econfig::Redis.new(redis)
|
97
130
|
```
|
98
131
|
|
99
|
-
|
132
|
+
If you wish to namespace your keys in Redis, you can use [redis namespace](http://rubygems.org/gems/redis-namespace).
|
100
133
|
|
101
|
-
###
|
134
|
+
### OSX Keychain
|
102
135
|
|
103
|
-
|
136
|
+
For the OSX keychain backend, see [econfig-keychain](https://github.com/elabs/econfig-keychain).
|
104
137
|
|
105
|
-
|
106
|
-
Econfig.use_redis Redis.new(:host => "myredis.com")
|
107
|
-
```
|
138
|
+
## Setting values
|
108
139
|
|
109
|
-
You can
|
140
|
+
You can set options by simply assigning them:
|
110
141
|
|
111
142
|
``` ruby
|
112
|
-
MyApp.aws_access_key_id = "xyz"
|
143
|
+
MyApp.config[:aws_access_key_id] = "xyz"
|
113
144
|
```
|
114
145
|
|
115
|
-
|
146
|
+
This will set the value in the default write backend, which by default is
|
147
|
+
`:memory`. This means that by default, configuration which is set like this is
|
148
|
+
not persisted in any way.
|
116
149
|
|
117
|
-
|
150
|
+
If you always want to assign values to a different backend, for example the
|
151
|
+
database backend, you can set the default write backend like this:
|
118
152
|
|
119
|
-
|
153
|
+
``` ruby
|
154
|
+
Econfig.default_write_backend = :db
|
155
|
+
```
|
120
156
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
production:
|
126
|
-
aws_access_key_id: "xyz"
|
127
|
-
aws_secret_access_key: "xyz"
|
157
|
+
You can also explicitly supply the backend when setting a configuration value:
|
158
|
+
|
159
|
+
``` ruby
|
160
|
+
MyApp.config[:db, :aws_access_key_id] = "xyz"
|
128
161
|
```
|
129
162
|
|
130
163
|
## License
|
data/Rakefile
CHANGED
data/econfig.gemspec
CHANGED
@@ -18,6 +18,9 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
|
21
|
+
gem.required_ruby_version = "~> 2.0"
|
22
|
+
|
23
|
+
gem.add_development_dependency "rake"
|
21
24
|
gem.add_development_dependency "rspec"
|
22
25
|
gem.add_development_dependency "activerecord"
|
23
26
|
gem.add_development_dependency "sqlite3"
|
data/lib/econfig.rb
CHANGED
@@ -1,29 +1,25 @@
|
|
1
|
+
require "forwardable"
|
1
2
|
require "econfig/version"
|
2
3
|
require "econfig/memory"
|
3
4
|
require "econfig/yaml"
|
4
5
|
require "econfig/env"
|
5
6
|
require "econfig/configuration"
|
6
7
|
require "econfig/shortcut"
|
8
|
+
require "econfig/backend_collection"
|
7
9
|
|
8
10
|
module Econfig
|
9
11
|
class NotFound < StandardError; end
|
10
12
|
class UninitializedError < StandardError; end
|
11
13
|
|
12
14
|
class << self
|
15
|
+
extend Forwardable
|
16
|
+
|
13
17
|
attr_accessor :root, :env, :instance
|
14
18
|
|
15
|
-
|
16
|
-
require "econfig/active_record"
|
17
|
-
Econfig.instance.backends << Econfig::ActiveRecord.new
|
18
|
-
end
|
19
|
-
|
20
|
-
def use_redis(redis)
|
21
|
-
require "econfig/redis"
|
22
|
-
Econfig.instance.backends << Econfig::Redis.new(redis)
|
23
|
-
end
|
19
|
+
def_delegators :instance, :backends, :default_write_backend, :default_write_backend=
|
24
20
|
|
25
21
|
def init
|
26
|
-
|
22
|
+
backends.each do |backend|
|
27
23
|
backend.init if backend.respond_to?(:init)
|
28
24
|
end
|
29
25
|
end
|
@@ -31,5 +27,9 @@ module Econfig
|
|
31
27
|
end
|
32
28
|
|
33
29
|
Econfig.instance = Econfig::Configuration.new
|
34
|
-
|
35
|
-
Econfig.
|
30
|
+
|
31
|
+
Econfig.default_write_backend = :memory
|
32
|
+
Econfig.backends.use :memory, Econfig::Memory.new
|
33
|
+
Econfig.backends.use :env, Econfig::ENV.new
|
34
|
+
Econfig.backends.use :secret, Econfig::YAML.new("config/secret.yml")
|
35
|
+
Econfig.backends.use :yaml, Econfig::YAML.new("config/app.yml")
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Econfig
|
2
|
+
class BackendCollection
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@backends = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def [](name)
|
10
|
+
pair = @backends.assoc(name)
|
11
|
+
pair.last if pair
|
12
|
+
end
|
13
|
+
|
14
|
+
def each
|
15
|
+
if block_given?
|
16
|
+
@backends.each { |(name, backend)| yield backend }
|
17
|
+
else
|
18
|
+
enum_for { @backends.length }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def push(name, backend)
|
23
|
+
exists‽(name)
|
24
|
+
@backends.push([name, backend])
|
25
|
+
end
|
26
|
+
alias_method :use, :push
|
27
|
+
|
28
|
+
def unshift(name, backend)
|
29
|
+
exists‽(name)
|
30
|
+
@backends.unshift([name, backend])
|
31
|
+
end
|
32
|
+
|
33
|
+
def insert_before(other, name, backend)
|
34
|
+
exists‽(name)
|
35
|
+
@backends.insert(index_of!(other), [name, backend])
|
36
|
+
end
|
37
|
+
|
38
|
+
def insert_after(other, name, backend)
|
39
|
+
exists‽(name)
|
40
|
+
@backends.insert(index_of!(other) + 1, [name, backend])
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete(name)
|
44
|
+
@backends.delete_at(index_of!(name))
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def exists‽(name)
|
50
|
+
raise KeyError, "#{name} is already set" if index_of(name)
|
51
|
+
end
|
52
|
+
|
53
|
+
def index_of!(name)
|
54
|
+
index_of(name) or raise KeyError, "#{name} is not set"
|
55
|
+
end
|
56
|
+
|
57
|
+
def index_of(name)
|
58
|
+
@backends.index(@backends.assoc(name))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -1,35 +1,44 @@
|
|
1
1
|
module Econfig
|
2
2
|
class Configuration
|
3
|
+
attr_accessor :default_write_backend
|
4
|
+
|
3
5
|
def backends
|
4
|
-
@backends ||=
|
6
|
+
@backends ||= BackendCollection.new
|
5
7
|
end
|
6
8
|
|
7
|
-
def
|
8
|
-
|
9
|
-
backend.get(key) if backend
|
9
|
+
def fetch(key)
|
10
|
+
self[key] or raise Econfig::NotFound, "configuration key '#{key}' is not set"
|
10
11
|
end
|
11
12
|
|
12
|
-
def
|
13
|
-
|
13
|
+
def [](key)
|
14
|
+
backends.each do |backend|
|
15
|
+
value = backend.get(key.to_s)
|
16
|
+
return value if value
|
17
|
+
end
|
18
|
+
nil
|
14
19
|
end
|
15
20
|
|
16
|
-
def
|
17
|
-
|
18
|
-
backend
|
21
|
+
def []=(backend_name = default_write_backend, key, value)
|
22
|
+
raise ArgumentError, "no backend given" unless backend_name
|
23
|
+
if backend = backends[backend_name]
|
24
|
+
backend.set(key, value)
|
25
|
+
else
|
26
|
+
raise KeyError, "#{backend_name} is not set"
|
27
|
+
end
|
19
28
|
end
|
20
29
|
|
21
30
|
def method_missing(name, *args)
|
22
|
-
if
|
23
|
-
|
24
|
-
|
25
|
-
get!(name.to_s.sub(/!$/, ""))
|
31
|
+
if respond_to?(name)
|
32
|
+
raise ArgumentError, "too many arguments (#{args.length} for 0)" if args.length > 0
|
33
|
+
fetch(name)
|
26
34
|
else
|
27
|
-
|
35
|
+
super
|
28
36
|
end
|
29
37
|
end
|
30
38
|
|
31
|
-
def
|
32
|
-
|
39
|
+
def respond_to_missing?(name, *)
|
40
|
+
name = name.to_s
|
41
|
+
not(name.end_with?("=") or name.end_with?("!") or name.end_with?("?"))
|
33
42
|
end
|
34
43
|
end
|
35
44
|
end
|
data/lib/econfig/redis.rb
CHANGED
data/lib/econfig/shortcut.rb
CHANGED
data/lib/econfig/version.rb
CHANGED
data/lib/econfig/yaml.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Econfig
|
2
2
|
class YAML
|
3
|
-
def initialize(path
|
3
|
+
def initialize(path)
|
4
4
|
@path = path
|
5
5
|
end
|
6
6
|
|
@@ -10,8 +10,9 @@ module Econfig
|
|
10
10
|
|
11
11
|
def init
|
12
12
|
require "yaml"
|
13
|
+
require "erb"
|
13
14
|
if File.exist?(path)
|
14
|
-
@options = ::YAML.
|
15
|
+
@options = ::YAML.load(::ERB.new(File.read(path)).result)[Econfig.env]
|
15
16
|
else
|
16
17
|
@options = {}
|
17
18
|
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
describe Econfig::Configuration do
|
2
|
+
let(:collection) { Econfig::BackendCollection.new }
|
3
|
+
let(:memory) { double("memory") }
|
4
|
+
let(:yaml) { double("yaml") }
|
5
|
+
|
6
|
+
describe "#[]" do
|
7
|
+
it "retrieves a backend" do
|
8
|
+
collection.push :memory, memory
|
9
|
+
collection[:memory].should equal(memory)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#each" do
|
14
|
+
it "can be called without a block to receive an enumerator" do
|
15
|
+
collection.push :memory, memory
|
16
|
+
collection.each.take(1).should eq([memory])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#push" do
|
21
|
+
it "adds a new backend at the bottom" do
|
22
|
+
collection.push :memory, memory
|
23
|
+
collection.push :yaml, yaml
|
24
|
+
collection.to_a.should eq([memory, yaml])
|
25
|
+
end
|
26
|
+
|
27
|
+
it "is aliased as `use`" do
|
28
|
+
collection.use :memory, memory
|
29
|
+
collection.use :yaml, yaml
|
30
|
+
collection.to_a.should eq([memory, yaml])
|
31
|
+
end
|
32
|
+
|
33
|
+
it "raises an error if backend already exist" do
|
34
|
+
collection.push :memory, memory
|
35
|
+
expect { collection.push :memory, yaml }.to raise_error(KeyError, "memory is already set")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#unshift" do
|
40
|
+
it "adds a new backend at the top" do
|
41
|
+
collection.unshift :memory, memory
|
42
|
+
collection.unshift :yaml, yaml
|
43
|
+
collection.to_a.should eq([yaml, memory])
|
44
|
+
end
|
45
|
+
|
46
|
+
it "raises an error if backend already exist" do
|
47
|
+
collection.unshift :memory, memory
|
48
|
+
expect { collection.unshift :memory, yaml }.to raise_error(KeyError, "memory is already set")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#insert_before" do
|
53
|
+
it "adds a new before the given backend" do
|
54
|
+
collection.push :quox, :quox
|
55
|
+
collection.push :baz, :baz
|
56
|
+
collection.push :foo, :foo
|
57
|
+
collection.insert_before :baz, :memory, memory
|
58
|
+
collection.to_a.should eq([:quox, memory, :baz, :foo])
|
59
|
+
end
|
60
|
+
|
61
|
+
it "raises an error if the backend does not exist" do
|
62
|
+
expect { collection.insert_before :baz, :memory, memory }.to raise_error(KeyError, /baz is not set/)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "raises an error if the backend already exists" do
|
66
|
+
collection.push :foo, :foo
|
67
|
+
expect { collection.insert_before :foo, :foo, memory }.to raise_error(KeyError, /foo is already set/)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#insert_after" do
|
72
|
+
it "adds a new after the given backend" do
|
73
|
+
collection.push :quox, :quox
|
74
|
+
collection.push :baz, :baz
|
75
|
+
collection.push :foo, :foo
|
76
|
+
collection.insert_after :baz, :memory, memory
|
77
|
+
collection.to_a.should eq([:quox, :baz, memory, :foo])
|
78
|
+
end
|
79
|
+
|
80
|
+
it "raises an error if the backend does not exist" do
|
81
|
+
expect { collection.insert_after :baz, :memory, memory }.to raise_error(KeyError, /baz is not set/)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "raises an error if the backend already exists" do
|
85
|
+
collection.push :foo, :foo
|
86
|
+
expect { collection.insert_after :foo, :foo, memory }.to raise_error(KeyError, /foo is already set/)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "#delete" do
|
91
|
+
it "removes the given backend" do
|
92
|
+
collection.push :memory, memory
|
93
|
+
collection.delete :memory
|
94
|
+
collection[:memory].should be_nil
|
95
|
+
end
|
96
|
+
|
97
|
+
it "raises an error if the backend does not exist" do
|
98
|
+
expect { collection.delete :redis }.to raise_error(KeyError, /redis is not set/)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
data/spec/config/app.yml
CHANGED
data/spec/configuration_spec.rb
CHANGED
@@ -3,76 +3,109 @@ describe Econfig::Configuration do
|
|
3
3
|
let(:other_backend) { double }
|
4
4
|
let(:config) { Econfig::Configuration.new }
|
5
5
|
|
6
|
-
before
|
6
|
+
before do
|
7
|
+
config.backends.push(:one, backend)
|
8
|
+
config.backends.push(:other, other_backend)
|
9
|
+
end
|
7
10
|
|
8
|
-
describe "#
|
11
|
+
describe "#[]" do
|
9
12
|
it "returns response from first backend" do
|
10
13
|
backend.stub(:get).with("foobar").and_return("elephant")
|
11
|
-
config
|
14
|
+
config["foobar"].should == "elephant"
|
12
15
|
end
|
13
16
|
|
14
17
|
it "tries multiple backends until it finds a response" do
|
15
18
|
backend.stub(:get).with("foobar").and_return(nil)
|
16
19
|
other_backend.stub(:get).with("foobar").and_return("elephant")
|
17
|
-
config
|
20
|
+
config["foobar"].should == "elephant"
|
18
21
|
end
|
19
22
|
|
20
23
|
it "returns nil if the key can't be found in any backend" do
|
21
24
|
backend.stub(:get).with("foobar").and_return(nil)
|
22
25
|
other_backend.stub(:get).with("foobar").and_return(nil)
|
23
|
-
config
|
26
|
+
config["foobar"].should == nil
|
24
27
|
end
|
25
28
|
end
|
26
29
|
|
27
|
-
describe "#
|
30
|
+
describe "#[]=" do
|
31
|
+
it "sets response on given backend" do
|
32
|
+
backend.should_receive(:set).with("foobar", "elephant")
|
33
|
+
config[:one, "foobar"] = "elephant"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "sets response on default backend if default backend is set" do
|
37
|
+
config.default_write_backend = :other
|
38
|
+
other_backend.should_receive(:set).with("foobar", "elephant")
|
39
|
+
config["foobar"] = "elephant"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "raises an error if no backend given and no default backend is set" do
|
43
|
+
config.default_write_backend = nil
|
44
|
+
expect { config["foobar"] = "elephant" }.to raise_error(ArgumentError, "no backend given")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "raises an error if the backend does not exist" do
|
48
|
+
expect { config[:does_not_exist, "foobar"] = "elephant" }.to raise_error(KeyError, "does_not_exist is not set")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#fetch" do
|
28
53
|
it "returns response from first backend" do
|
29
54
|
backend.stub(:get).with("foobar").and_return("elephant")
|
30
|
-
config.
|
55
|
+
config.fetch("foobar").should == "elephant"
|
31
56
|
end
|
32
57
|
|
33
58
|
it "tries multiple backends until it finds a response" do
|
34
59
|
backend.stub(:get).with("foobar").and_return(nil)
|
35
60
|
other_backend.stub(:get).with("foobar").and_return("elephant")
|
36
|
-
config.
|
61
|
+
config.fetch("foobar").should == "elephant"
|
37
62
|
end
|
38
63
|
|
39
64
|
it "raises error if the key can't be found in any backend" do
|
40
65
|
backend.stub(:get).with("foobar").and_return(nil)
|
41
66
|
other_backend.stub(:get).with("foobar").and_return(nil)
|
42
|
-
expect { config.
|
67
|
+
expect { config.fetch("foobar") }.to raise_error(Econfig::NotFound)
|
43
68
|
end
|
44
69
|
end
|
45
70
|
|
46
|
-
describe "#
|
47
|
-
it "
|
48
|
-
backend.
|
49
|
-
config.
|
71
|
+
describe "#method_missing" do
|
72
|
+
it "calls fetch for normal methods" do
|
73
|
+
backend.stub(:get).with("foobar").and_return("elephant")
|
74
|
+
config.foobar.should == "elephant"
|
50
75
|
end
|
51
76
|
|
52
|
-
it "
|
53
|
-
|
54
|
-
|
77
|
+
it "raises NoMethodError for bang methods" do
|
78
|
+
expect { config.foobar! }.to raise_error(NoMethodError)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "raises NoMethodError for query methods" do
|
82
|
+
expect { config.foobar? }.to raise_error(NoMethodError)
|
55
83
|
end
|
56
84
|
|
57
|
-
it "
|
58
|
-
config.
|
85
|
+
it "raises NoMethodError for setter methods" do
|
86
|
+
expect { config.foobar = "bar" }.to raise_error(NoMethodError)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "raises an error when giving arguments to a getter" do
|
90
|
+
expect { config.foobar "Hey" }.to raise_error(ArgumentError, "too many arguments (1 for 0)")
|
59
91
|
end
|
60
92
|
end
|
61
93
|
|
62
|
-
describe "#
|
63
|
-
it "
|
64
|
-
config.
|
65
|
-
|
94
|
+
describe "#respond_to?" do
|
95
|
+
it "return true for normal methods" do
|
96
|
+
config.should respond_to(:foobar)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "return false for bang methods" do
|
100
|
+
config.should_not respond_to(:foobar!)
|
66
101
|
end
|
67
102
|
|
68
|
-
it "
|
69
|
-
config.
|
70
|
-
config.foobar!.should == "elephant"
|
103
|
+
it "return false for query methods" do
|
104
|
+
config.should_not respond_to(:foobar?)
|
71
105
|
end
|
72
106
|
|
73
|
-
it "
|
74
|
-
config.
|
75
|
-
config.foobar = "elephant"
|
107
|
+
it "return false for assignment methods" do
|
108
|
+
config.should_not respond_to(:foobar=)
|
76
109
|
end
|
77
110
|
end
|
78
111
|
end
|
data/spec/redis_spec.rb
CHANGED
@@ -14,7 +14,7 @@ describe Econfig::Redis do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
it "fetches a previously persisted option" do
|
17
|
-
redis.set("
|
17
|
+
redis.set("foo", "bar")
|
18
18
|
backend.get("foo").should == "bar"
|
19
19
|
end
|
20
20
|
|
@@ -26,7 +26,7 @@ describe Econfig::Redis do
|
|
26
26
|
describe "#set" do
|
27
27
|
it "persists keys to database" do
|
28
28
|
backend.set("foo", "bar")
|
29
|
-
redis.get("
|
29
|
+
redis.get("foo").should == "bar"
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
data/spec/shortcut_spec.rb
CHANGED
@@ -2,15 +2,9 @@ describe Econfig::Shortcut do
|
|
2
2
|
let(:mod) { Module.new }
|
3
3
|
before { mod.extend Econfig::Shortcut }
|
4
4
|
|
5
|
-
describe "#
|
6
|
-
it "
|
7
|
-
|
8
|
-
mod.foobar.should == "elephant"
|
9
|
-
end
|
10
|
-
|
11
|
-
it "proxies bang methods to the Econfig instance" do
|
12
|
-
Econfig.instance.should_receive(:get!).with("foobar").and_return("elephant")
|
13
|
-
mod.foobar!.should == "elephant"
|
5
|
+
describe "#config" do
|
6
|
+
it "should be the econfig instance" do
|
7
|
+
mod.config.should equal(Econfig.instance)
|
14
8
|
end
|
15
9
|
end
|
16
10
|
end
|
data/spec/yaml_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
describe Econfig::YAML do
|
2
|
-
let(:backend) { Econfig::YAML.new.tap(&:init) }
|
2
|
+
let(:backend) { Econfig::YAML.new("config/app.yml").tap(&:init) }
|
3
3
|
describe "#get" do
|
4
4
|
it "fetches option from yaml config file" do
|
5
5
|
backend.get("quox").should == "baz"
|
@@ -13,5 +13,19 @@ describe Econfig::YAML do
|
|
13
13
|
backend = Econfig::YAML.new("/does/not/exist").tap(&:init)
|
14
14
|
backend.get("does_not_exist").should be_nil
|
15
15
|
end
|
16
|
+
|
17
|
+
it "evaluates the YAML config as ERB" do
|
18
|
+
with_env do
|
19
|
+
ENV['ECONFIG_EXAMPLE'] = "onment"
|
20
|
+
backend.get("envir").should == "onment"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def with_env(&block)
|
25
|
+
original = ENV.to_hash
|
26
|
+
yield if block_given?
|
27
|
+
ensure
|
28
|
+
ENV.replace(original)
|
29
|
+
end
|
16
30
|
end
|
17
31
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: econfig
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonas Nicklas
|
@@ -9,8 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-05-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
14
28
|
- !ruby/object:Gem::Dependency
|
15
29
|
name: rspec
|
16
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -85,6 +99,7 @@ files:
|
|
85
99
|
- econfig.gemspec
|
86
100
|
- lib/econfig.rb
|
87
101
|
- lib/econfig/active_record.rb
|
102
|
+
- lib/econfig/backend_collection.rb
|
88
103
|
- lib/econfig/configuration.rb
|
89
104
|
- lib/econfig/env.rb
|
90
105
|
- lib/econfig/memory.rb
|
@@ -97,6 +112,7 @@ files:
|
|
97
112
|
- lib/generators/econfig/migration/migration_generator.rb
|
98
113
|
- lib/generators/econfig/migration/templates/migration.rb
|
99
114
|
- spec/active_record_spec.rb
|
115
|
+
- spec/backend_collection_spec.rb
|
100
116
|
- spec/config/app.yml
|
101
117
|
- spec/configuration_spec.rb
|
102
118
|
- spec/env_spec.rb
|
@@ -115,9 +131,9 @@ require_paths:
|
|
115
131
|
- lib
|
116
132
|
required_ruby_version: !ruby/object:Gem::Requirement
|
117
133
|
requirements:
|
118
|
-
- - "
|
134
|
+
- - "~>"
|
119
135
|
- !ruby/object:Gem::Version
|
120
|
-
version: '0'
|
136
|
+
version: '2.0'
|
121
137
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
138
|
requirements:
|
123
139
|
- - ">="
|
@@ -131,6 +147,7 @@ specification_version: 4
|
|
131
147
|
summary: Congifure Ruby apps
|
132
148
|
test_files:
|
133
149
|
- spec/active_record_spec.rb
|
150
|
+
- spec/backend_collection_spec.rb
|
134
151
|
- spec/config/app.yml
|
135
152
|
- spec/configuration_spec.rb
|
136
153
|
- spec/env_spec.rb
|
@@ -139,3 +156,4 @@ test_files:
|
|
139
156
|
- spec/shortcut_spec.rb
|
140
157
|
- spec/spec_helper.rb
|
141
158
|
- spec/yaml_spec.rb
|
159
|
+
has_rdoc:
|