econfig 2.0.0 → 2.1.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 +4 -4
- data/README.md +20 -4
- data/lib/econfig.rb +1 -1
- data/lib/econfig/active_record.rb +27 -1
- data/lib/econfig/backend_collection.rb +32 -8
- data/lib/econfig/configuration.rb +23 -10
- data/lib/econfig/memory.rb +10 -0
- data/lib/econfig/redis.rb +4 -0
- data/lib/econfig/version.rb +1 -1
- data/lib/econfig/yaml.rb +4 -0
- data/spec/active_record_spec.rb +18 -0
- data/spec/configuration_spec.rb +47 -2
- data/spec/env_spec.rb +6 -0
- data/spec/memory_spec.rb +16 -0
- data/spec/redis_spec.rb +8 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/yaml_spec.rb +6 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0662ed0e8cd53281753072640fe6b72f715410b
|
4
|
+
data.tar.gz: e32b3e83e8197a4c353e184f01ad91bdbf89248d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3411a8decc879040d95eaff1124220939c735857777d35689d117cb6198893dae30a44e4d4144066bc427dd33bf021f827554599f507a647ac240265cd4ed742
|
7
|
+
data.tar.gz: ccb73c2eb936443fd533620a2bead57c656325897cd97becec2feaadcff048f757ec3403e0d34d1b96f8d093ee53f3e90b8decf189dfe2a7bc730a1d5b22bc4f
|
data/README.md
CHANGED
@@ -19,20 +19,36 @@ gem "econfig", require: "econfig/rails"
|
|
19
19
|
|
20
20
|
## Accessing config options
|
21
21
|
|
22
|
-
Extend your main application module with the Econfig shortcut.
|
23
|
-
|
22
|
+
Extend your main application module with the Econfig shortcut.
|
23
|
+
|
24
|
+
In Rails, you'll want to add this in `config/application.rb`:
|
24
25
|
|
25
26
|
``` ruby
|
26
27
|
module MyApp
|
27
28
|
extend Econfig::Shortcut
|
28
29
|
|
29
30
|
class Application < Rails::Application
|
30
|
-
…
|
31
|
+
# …
|
31
32
|
end
|
32
33
|
end
|
33
34
|
```
|
34
35
|
|
35
|
-
|
36
|
+
In a modular Sinatra application, extend your controller class and copy its settings to Econfig in `app.rb`:
|
37
|
+
``` ruby
|
38
|
+
require 'sinatra'
|
39
|
+
require 'econfig'
|
40
|
+
|
41
|
+
class MyApp < Sinatra::Base
|
42
|
+
extend Econfig::Shortcut
|
43
|
+
|
44
|
+
Econfig.env = settings.environment.to_s
|
45
|
+
Econfig.root = settings.root
|
46
|
+
|
47
|
+
# …
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
In either case, you can now you can access configuration like this:
|
36
52
|
|
37
53
|
``` ruby
|
38
54
|
MyApp.config.aws_access_key_id
|
data/lib/econfig.rb
CHANGED
@@ -16,7 +16,7 @@ module Econfig
|
|
16
16
|
|
17
17
|
attr_accessor :root, :env, :instance
|
18
18
|
|
19
|
-
def_delegators :instance, :backends, :default_write_backend, :default_write_backend=
|
19
|
+
def_delegators :instance, :backends, :cast, :default_write_backend, :default_write_backend=
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -1,5 +1,16 @@
|
|
1
|
+
require "active_record"
|
2
|
+
|
1
3
|
module Econfig
|
2
4
|
class ActiveRecord
|
5
|
+
MISSING_TABLE_WARNING = <<-WARNING.gsub(/^ */, "")
|
6
|
+
=======================================================================
|
7
|
+
Econfig table not found. Please add the configuration table by running:
|
8
|
+
|
9
|
+
rails generate econfig:migration
|
10
|
+
rake db:migrate
|
11
|
+
=======================================================================
|
12
|
+
WARNING
|
13
|
+
|
3
14
|
class Option < ::ActiveRecord::Base
|
4
15
|
attr_accessible :key, :value rescue nil
|
5
16
|
self.table_name = "econfig_options"
|
@@ -7,13 +18,28 @@ module Econfig
|
|
7
18
|
validates_presence_of :key
|
8
19
|
end
|
9
20
|
|
21
|
+
def keys
|
22
|
+
Set.new(Option.pluck(:key))
|
23
|
+
rescue ::ActiveRecord::StatementInvalid
|
24
|
+
warn MISSING_TABLE_WARNING
|
25
|
+
Set.new([])
|
26
|
+
end
|
27
|
+
|
10
28
|
def get(key)
|
11
|
-
Option.find_by_key(key)
|
29
|
+
if option = Option.find_by_key(key)
|
30
|
+
option.value
|
31
|
+
else
|
32
|
+
yield if block_given?
|
33
|
+
end
|
34
|
+
rescue ::ActiveRecord::StatementInvalid
|
35
|
+
warn MISSING_TABLE_WARNING
|
12
36
|
end
|
13
37
|
|
14
38
|
def set(key, value)
|
15
39
|
option = Option.where(:key => key).first_or_initialize
|
16
40
|
option.update_attributes!(:value => value)
|
41
|
+
rescue ::ActiveRecord::StatementInvalid
|
42
|
+
warn MISSING_TABLE_WARNING
|
17
43
|
end
|
18
44
|
end
|
19
45
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
module Econfig
|
2
3
|
class BackendCollection
|
3
4
|
include Enumerable
|
@@ -6,6 +7,16 @@ module Econfig
|
|
6
7
|
@backends = []
|
7
8
|
end
|
8
9
|
|
10
|
+
def keys
|
11
|
+
@backends.reduce(Set.new) do |agg, (name, backend)|
|
12
|
+
if backend.respond_to?(:keys)
|
13
|
+
agg.union(backend.keys)
|
14
|
+
else
|
15
|
+
agg
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
9
20
|
def [](name)
|
10
21
|
pair = @backends.assoc(name)
|
11
22
|
pair.last if pair
|
@@ -20,23 +31,23 @@ module Econfig
|
|
20
31
|
end
|
21
32
|
|
22
33
|
def push(name, backend)
|
23
|
-
exists
|
34
|
+
exists?(name)
|
24
35
|
@backends.push([name, backend])
|
25
36
|
end
|
26
37
|
alias_method :use, :push
|
27
38
|
|
28
39
|
def unshift(name, backend)
|
29
|
-
exists
|
40
|
+
exists?(name)
|
30
41
|
@backends.unshift([name, backend])
|
31
42
|
end
|
32
43
|
|
33
44
|
def insert_before(other, name, backend)
|
34
|
-
exists
|
45
|
+
exists?(name)
|
35
46
|
@backends.insert(index_of!(other), [name, backend])
|
36
47
|
end
|
37
48
|
|
38
49
|
def insert_after(other, name, backend)
|
39
|
-
exists
|
50
|
+
exists?(name)
|
40
51
|
@backends.insert(index_of!(other) + 1, [name, backend])
|
41
52
|
end
|
42
53
|
|
@@ -44,14 +55,27 @@ module Econfig
|
|
44
55
|
@backends.delete_at(index_of!(name))
|
45
56
|
end
|
46
57
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
58
|
+
def get(key)
|
59
|
+
@backends.each do |(name, backend)|
|
60
|
+
has_key = true
|
61
|
+
|
62
|
+
if backend.respond_to?(:has_key?)
|
63
|
+
has_key = backend.has_key?(key)
|
64
|
+
value = backend.get(key) if has_key
|
65
|
+
else
|
66
|
+
value = backend.get(key) { has_key = false }
|
67
|
+
end
|
68
|
+
|
69
|
+
has_key or next
|
70
|
+
return value
|
71
|
+
end
|
72
|
+
|
73
|
+
yield if block_given?
|
50
74
|
end
|
51
75
|
|
52
76
|
private
|
53
77
|
|
54
|
-
def exists
|
78
|
+
def exists?(name)
|
55
79
|
raise KeyError, "#{name} is already set" if index_of(name)
|
56
80
|
end
|
57
81
|
|
@@ -2,27 +2,39 @@ module Econfig
|
|
2
2
|
class Configuration
|
3
3
|
attr_accessor :default_write_backend
|
4
4
|
|
5
|
-
|
5
|
+
attr_reader :backends, :casts
|
6
|
+
|
7
|
+
def initialize
|
6
8
|
@backends ||= BackendCollection.new
|
9
|
+
@casts ||= {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def cast(key, &block)
|
13
|
+
casts[key.to_s] = block
|
14
|
+
end
|
15
|
+
|
16
|
+
def keys
|
17
|
+
backends.keys
|
7
18
|
end
|
8
19
|
|
9
20
|
def fetch(key)
|
10
|
-
key
|
11
|
-
backend = backends.backend_for(key)
|
12
|
-
if backend
|
13
|
-
backend.get(key)
|
14
|
-
else
|
21
|
+
get(key) do
|
15
22
|
raise Econfig::NotFound, "configuration key '#{key}' is not set"
|
16
23
|
end
|
17
24
|
end
|
18
25
|
|
19
|
-
def
|
26
|
+
def get(key)
|
20
27
|
key = key.to_s
|
21
|
-
|
22
|
-
|
28
|
+
value = backends.get(key) do
|
29
|
+
yield if block_given?
|
30
|
+
return nil
|
31
|
+
end
|
32
|
+
value = casts[key].call(value) if casts[key]
|
33
|
+
value
|
23
34
|
end
|
35
|
+
alias_method :[], :get
|
24
36
|
|
25
|
-
def
|
37
|
+
def set(backend_name = default_write_backend, key, value)
|
26
38
|
raise ArgumentError, "no backend given" unless backend_name
|
27
39
|
if backend = backends[backend_name]
|
28
40
|
backend.set(key.to_s, value)
|
@@ -30,6 +42,7 @@ module Econfig
|
|
30
42
|
raise KeyError, "#{backend_name} is not set"
|
31
43
|
end
|
32
44
|
end
|
45
|
+
alias_method :[]=, :set
|
33
46
|
|
34
47
|
def method_missing(name, *args)
|
35
48
|
if respond_to?(name)
|
data/lib/econfig/memory.rb
CHANGED
@@ -5,6 +5,10 @@ module Econfig
|
|
5
5
|
@options = {}
|
6
6
|
end
|
7
7
|
|
8
|
+
def keys
|
9
|
+
Set.new(@options.keys)
|
10
|
+
end
|
11
|
+
|
8
12
|
def has_key?(key)
|
9
13
|
@options.has_key?(key)
|
10
14
|
end
|
@@ -18,5 +22,11 @@ module Econfig
|
|
18
22
|
@options[key] = value
|
19
23
|
end
|
20
24
|
end
|
25
|
+
|
26
|
+
def clear
|
27
|
+
@mutex.synchronize do
|
28
|
+
@options.clear
|
29
|
+
end
|
30
|
+
end
|
21
31
|
end
|
22
32
|
end
|
data/lib/econfig/redis.rb
CHANGED
data/lib/econfig/version.rb
CHANGED
data/lib/econfig/yaml.rb
CHANGED
data/spec/active_record_spec.rb
CHANGED
@@ -17,6 +17,15 @@ describe Econfig::ActiveRecord do
|
|
17
17
|
raise ActiveRecord::Rollback
|
18
18
|
end
|
19
19
|
end
|
20
|
+
|
21
|
+
describe "#keys" do
|
22
|
+
it "returns a list of set keys" do
|
23
|
+
backend.set("foo", "123")
|
24
|
+
backend.set("bar", "664")
|
25
|
+
backend.keys.should eq(Set.new(["foo", "bar"]))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
20
29
|
describe "#get" do
|
21
30
|
it "fetches a previously set option" do
|
22
31
|
backend.set("foo", "bar")
|
@@ -31,6 +40,15 @@ describe Econfig::ActiveRecord do
|
|
31
40
|
it "returns nil if option is not set" do
|
32
41
|
backend.get("foo").should be_nil
|
33
42
|
end
|
43
|
+
|
44
|
+
it "yields if option is not set" do
|
45
|
+
backend.get("foo") { "blah" }.should eq("blah")
|
46
|
+
end
|
47
|
+
|
48
|
+
it "ignores block if set" do
|
49
|
+
backend.set("foo", "bar")
|
50
|
+
backend.get("foo") { raise "blah" }.should eq("bar")
|
51
|
+
end
|
34
52
|
end
|
35
53
|
|
36
54
|
describe "#set" do
|
data/spec/configuration_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
describe Econfig::Configuration do
|
2
|
-
let(:backend) { double }
|
3
|
-
let(:other_backend) { double }
|
2
|
+
let(:backend) { double("backend") }
|
3
|
+
let(:other_backend) { double("other backend") }
|
4
4
|
let(:config) { Econfig::Configuration.new }
|
5
5
|
|
6
6
|
before do
|
@@ -8,6 +8,19 @@ describe Econfig::Configuration do
|
|
8
8
|
config.backends.push(:other, other_backend)
|
9
9
|
end
|
10
10
|
|
11
|
+
describe "#keys" do
|
12
|
+
it "returns the union of all keys" do
|
13
|
+
backend.stub(:keys).and_return(Set.new(["foo", "bar", "baz"]))
|
14
|
+
other_backend.stub(:keys).and_return(Set.new(["bar", "monkey"]))
|
15
|
+
config.keys.should == Set.new(["foo", "bar", "baz", "monkey"])
|
16
|
+
end
|
17
|
+
|
18
|
+
it "skips over backends which don't return keys" do
|
19
|
+
other_backend.stub(:keys).and_return(Set.new(["bar", "monkey"]))
|
20
|
+
config.keys.should == Set.new(["bar", "monkey"])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
11
24
|
describe "#[]" do
|
12
25
|
it "returns response from first backend" do
|
13
26
|
backend.stub(:has_key?).with("foobar").and_return(true)
|
@@ -21,6 +34,19 @@ describe Econfig::Configuration do
|
|
21
34
|
config[:foobar].should == "elephant"
|
22
35
|
end
|
23
36
|
|
37
|
+
it "casts value if it exists" do
|
38
|
+
config.cast(:foobar) { |val| val.to_i + 10 }
|
39
|
+
backend.stub(:get).with("foobar").and_return("123")
|
40
|
+
config[:foobar].should == 133
|
41
|
+
end
|
42
|
+
|
43
|
+
it "does not cast if there is no value" do
|
44
|
+
config.cast(:foobar) { |val| raise "should not be here" }
|
45
|
+
backend.stub(:has_key?).with("foobar").and_return(false)
|
46
|
+
other_backend.stub(:has_key?).with("foobar").and_return(false)
|
47
|
+
config[:foobar].should == nil
|
48
|
+
end
|
49
|
+
|
24
50
|
it "tries multiple backends until it finds a response" do
|
25
51
|
backend.stub(:has_key?).with("foobar").and_return(false)
|
26
52
|
other_backend.stub(:has_key?).with("foobar").and_return(true)
|
@@ -28,6 +54,12 @@ describe Econfig::Configuration do
|
|
28
54
|
config["foobar"].should == "elephant"
|
29
55
|
end
|
30
56
|
|
57
|
+
it "tries multiple backends which yield from get until it finds one which doesn't" do
|
58
|
+
backend.stub(:get).with("foobar").and_yield
|
59
|
+
other_backend.stub(:get).with("foobar").and_return("elephant")
|
60
|
+
config["foobar"].should == "elephant"
|
61
|
+
end
|
62
|
+
|
31
63
|
it "returns nil if the key can't be found in any backend" do
|
32
64
|
backend.stub(:has_key?).with("foobar").and_return(false)
|
33
65
|
other_backend.stub(:has_key?).with("foobar").and_return(false)
|
@@ -69,6 +101,19 @@ describe Econfig::Configuration do
|
|
69
101
|
config.fetch("foobar").should == "elephant"
|
70
102
|
end
|
71
103
|
|
104
|
+
it "casts value if it exists" do
|
105
|
+
config.cast(:foobar) { |val| val.to_i + 10 }
|
106
|
+
backend.stub(:get).with("foobar").and_return("123")
|
107
|
+
config.fetch(:foobar).should == 133
|
108
|
+
end
|
109
|
+
|
110
|
+
it "does not cast if there is no value" do
|
111
|
+
config.cast(:foobar) { |val| raise "should not be here" }
|
112
|
+
backend.stub(:has_key?).with("foobar").and_return(false)
|
113
|
+
other_backend.stub(:has_key?).with("foobar").and_return(false)
|
114
|
+
expect { config.fetch("foobar") }.to raise_error(Econfig::NotFound)
|
115
|
+
end
|
116
|
+
|
72
117
|
it "tries multiple backends until it finds a response" do
|
73
118
|
backend.stub(:has_key?).with("foobar").and_return(false)
|
74
119
|
other_backend.stub(:has_key?).with("foobar").and_return(true)
|
data/spec/env_spec.rb
CHANGED
@@ -5,6 +5,12 @@ describe Econfig::ENV do
|
|
5
5
|
ENV["FOO_BAR"] = "monkey"
|
6
6
|
end
|
7
7
|
|
8
|
+
describe "#keys" do
|
9
|
+
it "is not supported because it would return a lot of junk" do
|
10
|
+
backend.respond_to?(:keys).should be_falsy
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
8
14
|
describe "#has_key?" do
|
9
15
|
it "returns true if key exists" do
|
10
16
|
backend.has_key?("foo_bar").should eq(true)
|
data/spec/memory_spec.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
describe Econfig::Memory do
|
2
2
|
let(:backend) { Econfig::Memory.new }
|
3
3
|
|
4
|
+
describe "#keys" do
|
5
|
+
it "returns a list of set keys" do
|
6
|
+
backend.set("foo", "123")
|
7
|
+
backend.set("bar", "664")
|
8
|
+
backend.keys.should eq(Set.new(["foo", "bar"]))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
4
12
|
describe "#has_key?" do
|
5
13
|
it "returns true if key exists" do
|
6
14
|
backend.set("foo", "bar")
|
@@ -18,4 +26,12 @@ describe Econfig::Memory do
|
|
18
26
|
backend.get("foo").should == "bar"
|
19
27
|
end
|
20
28
|
end
|
29
|
+
|
30
|
+
describe "#clear" do
|
31
|
+
it "clears all set keys" do
|
32
|
+
backend.set("foo", "bar")
|
33
|
+
backend.clear
|
34
|
+
backend.has_key?("foo").should be_falsy
|
35
|
+
end
|
36
|
+
end
|
21
37
|
end
|
data/spec/redis_spec.rb
CHANGED
@@ -8,6 +8,14 @@ describe Econfig::Redis do
|
|
8
8
|
redis.flushdb
|
9
9
|
end
|
10
10
|
|
11
|
+
describe "#keys" do
|
12
|
+
it "returns a list of set keys" do
|
13
|
+
backend.set("foo", "123")
|
14
|
+
backend.set("bar", "664")
|
15
|
+
backend.keys.should eq(Set.new(["foo", "bar"]))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
11
19
|
describe "#has_key?" do
|
12
20
|
it "returns true if key exists" do
|
13
21
|
backend.set("foo", "bar")
|
data/spec/spec_helper.rb
CHANGED
@@ -2,3 +2,13 @@ require "econfig"
|
|
2
2
|
|
3
3
|
Econfig.root = File.dirname(__FILE__)
|
4
4
|
Econfig.env = "test"
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
config.expect_with :rspec do |c|
|
8
|
+
c.syntax = [:expect, :should]
|
9
|
+
end
|
10
|
+
|
11
|
+
config.mock_with :rspec do |c|
|
12
|
+
c.syntax = [:expect, :should]
|
13
|
+
end
|
14
|
+
end
|
data/spec/yaml_spec.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
describe Econfig::YAML do
|
2
2
|
let(:backend) { Econfig::YAML.new("config/app.yml") }
|
3
3
|
|
4
|
+
describe "#keys" do
|
5
|
+
it "returns keys set in backend" do
|
6
|
+
expect(backend.keys).to eq(Set.new(["quox", "envir"]))
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
4
10
|
describe "#has_key?" do
|
5
11
|
it "returns true if option exists" do
|
6
12
|
expect(backend.has_key?("quox")).to eq(true)
|
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: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonas Nicklas
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2018-10-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
141
|
version: '0'
|
142
142
|
requirements: []
|
143
143
|
rubyforge_project:
|
144
|
-
rubygems_version: 2.
|
144
|
+
rubygems_version: 2.6.13
|
145
145
|
signing_key:
|
146
146
|
specification_version: 4
|
147
147
|
summary: Congifure Ruby apps
|