appcfg 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +30 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +55 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/lib/appcfg.rb +9 -0
- data/lib/appcfg/retrieval.rb +25 -0
- data/lib/appcfg/source.rb +72 -0
- data/lib/appcfg/sources/model_source.rb +14 -0
- data/lib/appcfg/sources/yaml_source.rb +13 -0
- data/spec/hash_source_config_spec.rb +34 -0
- data/spec/model_source_spec.rb +35 -0
- data/spec/source_spec.rb +103 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/classes/sample_config.rb +23 -0
- data/spec/support/sample_config.yml +6 -0
- data/spec/support/sample_env_config.yml +20 -0
- data/spec/yaml_source_spec.rb +67 -0
- metadata +150 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "rspec", "~> 2.3.0"
|
10
|
+
gem "bundler", "~> 1.0.0"
|
11
|
+
gem "jeweler", "~> 1.5.2"
|
12
|
+
gem 'simplecov', '>= 0.4.0', :require => false
|
13
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.1.2)
|
5
|
+
git (1.2.5)
|
6
|
+
jeweler (1.5.2)
|
7
|
+
bundler (~> 1.0.0)
|
8
|
+
git (>= 1.2.5)
|
9
|
+
rake
|
10
|
+
rake (0.8.7)
|
11
|
+
rspec (2.3.0)
|
12
|
+
rspec-core (~> 2.3.0)
|
13
|
+
rspec-expectations (~> 2.3.0)
|
14
|
+
rspec-mocks (~> 2.3.0)
|
15
|
+
rspec-core (2.3.1)
|
16
|
+
rspec-expectations (2.3.0)
|
17
|
+
diff-lcs (~> 1.1.2)
|
18
|
+
rspec-mocks (2.3.0)
|
19
|
+
simplecov (0.4.2)
|
20
|
+
simplecov-html (~> 0.4.4)
|
21
|
+
simplecov-html (0.4.4)
|
22
|
+
|
23
|
+
PLATFORMS
|
24
|
+
ruby
|
25
|
+
|
26
|
+
DEPENDENCIES
|
27
|
+
bundler (~> 1.0.0)
|
28
|
+
jeweler (~> 1.5.2)
|
29
|
+
rspec (~> 2.3.0)
|
30
|
+
simplecov (>= 0.4.0)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Toms Mikoss
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
= appconfig
|
2
|
+
|
3
|
+
A gem for centralizing different sources of application configuration data. Supports YAML files, ActiveRecord models and simple hashes as data sources.
|
4
|
+
|
5
|
+
== Usage
|
6
|
+
|
7
|
+
=== Adding configuration sources
|
8
|
+
|
9
|
+
[From YAML file] AppCfg::Source.add('/path/to/configuration.yml')
|
10
|
+
|
11
|
+
[From namespaced YAML file] AppCfg::Source.add('/path/to/configuration.yml', :env => Rails.env)
|
12
|
+
|
13
|
+
[From ActiveRecord model] AppCfg::Source.add(ConfigurationModel)
|
14
|
+
|
15
|
+
[From hash object] AppCfg::Source.add({:some_key => 'value'})
|
16
|
+
|
17
|
+
=== Accessing configuration values
|
18
|
+
|
19
|
+
Configuration data can be accessed via both object and hash syntax, called on AppCfg module:
|
20
|
+
|
21
|
+
AppCfg.some_key # => 'value'
|
22
|
+
AppCfg['some_key'] # => 'value'
|
23
|
+
|
24
|
+
Note that these options differ when trying to access inexistent key:
|
25
|
+
|
26
|
+
AppCfg.wrong_key # => raises exception
|
27
|
+
AppCfg['wrong_key'] # => nil
|
28
|
+
|
29
|
+
=== Overwriting and reloading
|
30
|
+
|
31
|
+
Configuration sources are stacked in the order of being added:
|
32
|
+
|
33
|
+
AppCfg::Source.add({:some_key => 'some value'})
|
34
|
+
AppCfg::Source.add({:some_key => 'other value'})
|
35
|
+
AppCfg.some_key # => 'other value'
|
36
|
+
|
37
|
+
Configuration values are cached at the moment of being added. If sources are modified (for example, configuration values stored in database change), data can be refreshed via:
|
38
|
+
|
39
|
+
AppCfg::Source.reload_sources!
|
40
|
+
|
41
|
+
== Contributing to appconfig
|
42
|
+
|
43
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
44
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
45
|
+
* Fork the project
|
46
|
+
* Start a feature/bugfix branch
|
47
|
+
* Commit and push until you are happy with your contribution
|
48
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
49
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
50
|
+
|
51
|
+
== Copyright
|
52
|
+
|
53
|
+
Copyright (c) 2011 Toms Mikoss. See LICENSE.txt for
|
54
|
+
further details.
|
55
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "appcfg"
|
16
|
+
gem.homepage = "http://github.com/tmikoss/appconfig"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{A gem for centralizing different sources of application configuration data.}
|
19
|
+
gem.description = %Q{A gem for centralizing different sources of application configuration data. Supports YAML files, ActiveRecord models and simple hashes as data sources.}
|
20
|
+
gem.email = "toms.mikoss@gmail.com"
|
21
|
+
gem.authors = ["Toms Mikoss"]
|
22
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
25
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rspec/core'
|
30
|
+
require 'rspec/core/rake_task'
|
31
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
32
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
33
|
+
end
|
34
|
+
|
35
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
36
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
37
|
+
spec.rcov = true
|
38
|
+
end
|
39
|
+
|
40
|
+
task :default => :spec
|
41
|
+
|
42
|
+
require 'rake/rdoctask'
|
43
|
+
Rake::RDocTask.new do |rdoc|
|
44
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
45
|
+
|
46
|
+
rdoc.rdoc_dir = 'rdoc'
|
47
|
+
rdoc.title = "appcfg #{version}"
|
48
|
+
rdoc.rdoc_files.include('README*')
|
49
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
50
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/appcfg.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module AppCfg
|
2
|
+
def self.[](key)
|
3
|
+
if @@cache.respond_to?(key)
|
4
|
+
@@cache.send(key)
|
5
|
+
else
|
6
|
+
nil
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.method_missing(method_sym, *arguments, &block)
|
11
|
+
if @@cache.respond_to?(method_sym)
|
12
|
+
@@cache.send(method_sym)
|
13
|
+
else
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.respond_to?(method_sym, include_private = false)
|
19
|
+
if @@cache.respond_to?(method_sym)
|
20
|
+
true
|
21
|
+
else
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module AppCfg
|
2
|
+
class Source
|
3
|
+
@@sources = []
|
4
|
+
|
5
|
+
def initialize(options={})
|
6
|
+
@hash = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_hash
|
10
|
+
@hash
|
11
|
+
end
|
12
|
+
|
13
|
+
def reload_data!
|
14
|
+
#Do nothing
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.add(source_object, options={})
|
18
|
+
if source_object.is_a?(String) && source_object[-4..-1] == '.yml'
|
19
|
+
#YAML
|
20
|
+
raise "File #{source_object} could not be located" unless File.exist? source_object
|
21
|
+
add_source(YamlSource.new(options.merge(:file => source_object)))
|
22
|
+
elsif source_object.is_a?(Class) && source_object.respond_to?(:all)
|
23
|
+
#AR Model
|
24
|
+
add_source(ModelSource.new(options.merge(:class => source_object)))
|
25
|
+
elsif source_object.is_a?(Hash)
|
26
|
+
#Simple hash
|
27
|
+
add_source(Source.new(source_object))
|
28
|
+
else
|
29
|
+
raise 'Could not match source object to any known types'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.list
|
34
|
+
@@sources
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.reload_sources!
|
38
|
+
cache = {}
|
39
|
+
|
40
|
+
@@sources.each do |source|
|
41
|
+
source.reload_data!
|
42
|
+
cache = cache.merge(source.to_hash)
|
43
|
+
end
|
44
|
+
|
45
|
+
AppCfg.class_variable_set '@@cache', hash_to_object(cache)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def self.add_source(source)
|
51
|
+
@@sources << source
|
52
|
+
reload_sources!
|
53
|
+
end
|
54
|
+
|
55
|
+
#Credit to http://blog.jayfields.com/2008/01/ruby-hashtomod.html
|
56
|
+
def self.hash_to_object(hash)
|
57
|
+
mod = Module.new do
|
58
|
+
hash.each_pair do |key, value|
|
59
|
+
define_method key do
|
60
|
+
value.is_a?(Hash) ? AppCfg::Source.hash_to_object(value) : value
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
new_hash = hash.dup
|
66
|
+
|
67
|
+
new_hash.extend mod
|
68
|
+
|
69
|
+
new_hash
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module AppCfg
|
2
|
+
class YamlSource < Source
|
3
|
+
def initialize(options = {})
|
4
|
+
@filename = options[:file]
|
5
|
+
@namespace = options[:env]
|
6
|
+
end
|
7
|
+
|
8
|
+
def reload_data!
|
9
|
+
yaml_structure = YAML.load(File.open @filename)
|
10
|
+
@hash = @namespace ? yaml_structure[@namespace] : yaml_structure
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "AppCfg retrieval from simple hash" do
|
4
|
+
before(:each) do
|
5
|
+
@config_hash = {'app_name' => 'AppCfg', 'admin_credentials' => {'username' => 'admin', 'password' => 'testpass'}}
|
6
|
+
AppCfg::Source.add(@config_hash)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should support hash syntax for access" do
|
10
|
+
AppCfg['app_name'].should == 'AppCfg'
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should support object syntax for access" do
|
14
|
+
AppCfg.app_name.should == 'AppCfg'
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should allow multi-level access with hash syntax" do
|
18
|
+
AppCfg['admin_credentials']['username'].should == 'admin'
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should allow multi-level access with object syntax" do
|
22
|
+
AppCfg.admin_credentials.username.should == 'admin'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should return nil on non-existent key, hash syntax" do
|
26
|
+
AppCfg['wrong_key'].should be_nil
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should raise error on non-existent key, object syntax" do
|
30
|
+
lambda {
|
31
|
+
AppCfg.wrong_key
|
32
|
+
}.should raise_error
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "AppCfg retrieval from AR model" do
|
4
|
+
before(:each) do
|
5
|
+
SampleConfig.create(:key => 'app_name', :value => 'AppCfg')
|
6
|
+
SampleConfig.create(:key => 'admin_credentials', :value => {'username' => 'admin', 'password' => 'testpass'})
|
7
|
+
AppCfg::Source.add(SampleConfig)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should support hash syntax for access" do
|
11
|
+
AppCfg['app_name'].should == 'AppCfg'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should support object syntax for access" do
|
15
|
+
AppCfg.app_name.should == 'AppCfg'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should allow multi-level access with hash syntax" do
|
19
|
+
AppCfg['admin_credentials']['username'].should == 'admin'
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should allow multi-level access with object syntax" do
|
23
|
+
AppCfg.admin_credentials.username.should == 'admin'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should return nil on non-existent key, hash syntax" do
|
27
|
+
AppCfg['wrong_key'].should be_nil
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should raise error on non-existent key, object syntax" do
|
31
|
+
lambda {
|
32
|
+
AppCfg.wrong_key
|
33
|
+
}.should raise_error
|
34
|
+
end
|
35
|
+
end
|
data/spec/source_spec.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "AppCfg source setup" do
|
4
|
+
describe "Adding YAML source" do
|
5
|
+
it "when passed a string ending in .yml, should treat it as file path and add it as a YAML source" do
|
6
|
+
AppCfg::Source.add(@sample_yaml_file_path)
|
7
|
+
AppCfg::Source.list.size.should == 1
|
8
|
+
AppCfg::Source.list.first.should be_is_a AppCfg::YamlSource
|
9
|
+
end
|
10
|
+
|
11
|
+
it "when passed a non-existent file path, should raise exception" do
|
12
|
+
lambda{
|
13
|
+
AppCfg::Source.add(File.expand_path(File.dirname(__FILE__) + '/this_file_does_not_exist.yml'))
|
14
|
+
}.should raise_error
|
15
|
+
AppCfg::Source.list.should be_empty
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "Adding ActiveRecord model source" do
|
20
|
+
it "when passed a class that responds to slef.all, should treat it as a ActiveRecord model" do
|
21
|
+
AppCfg::Source.add(SampleConfig)
|
22
|
+
AppCfg::Source.list.size.should == 1
|
23
|
+
AppCfg::Source.list.first.should be_is_a AppCfg::ModelSource
|
24
|
+
end
|
25
|
+
|
26
|
+
it "when passed a class that does not respond to slef.all, should not treat it as a ActiveRecord model" do
|
27
|
+
lambda{
|
28
|
+
AppCfg::Source.add(Object)
|
29
|
+
}.should raise_error
|
30
|
+
AppCfg::Source.list.should be_empty
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "Adding simple hash model source" do
|
35
|
+
it "when passed a hash object, should treat it as simple hash source" do
|
36
|
+
AppCfg::Source.add({:foo => 'bar'})
|
37
|
+
AppCfg::Source.list.size.should == 1
|
38
|
+
AppCfg::Source.list.first.should be_is_a AppCfg::Source
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "Adding unknown source" do
|
43
|
+
it "should raise error when adding a source that does not match any known sources" do
|
44
|
+
lambda{
|
45
|
+
AppCfg::Source.add(:foobar)
|
46
|
+
}.should raise_error
|
47
|
+
AppCfg::Source.list.should be_empty
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "Source priority" do
|
52
|
+
it "If adding multiple sources, keys from them all should be available" do
|
53
|
+
AppCfg::Source.add({:one => 1})
|
54
|
+
AppCfg::Source.add({:two => 2})
|
55
|
+
|
56
|
+
AppCfg.one.should == 1
|
57
|
+
AppCfg.two.should == 2
|
58
|
+
end
|
59
|
+
|
60
|
+
it "If adding multiple sources of different types, keys from them all should be available" do
|
61
|
+
AppCfg::Source.add(@sample_yaml_file_path)
|
62
|
+
AppCfg::Source.add({:one => 1})
|
63
|
+
|
64
|
+
AppCfg.app_name.should == 'AppCfg'
|
65
|
+
AppCfg.one.should == 1
|
66
|
+
end
|
67
|
+
|
68
|
+
it "If keys from multiple sources overlap, the one added last should be returned" do
|
69
|
+
AppCfg::Source.add({:one => 1})
|
70
|
+
AppCfg::Source.add({:one => 2})
|
71
|
+
|
72
|
+
AppCfg.one.should == 2
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "Reloading sources" do
|
77
|
+
it "should not automatically reflect changes in source" do
|
78
|
+
SampleConfig.create(:key => 'app_name', :value => 'AppCfg')
|
79
|
+
AppCfg::Source.add(SampleConfig)
|
80
|
+
|
81
|
+
AppCfg.app_name.should == 'AppCfg'
|
82
|
+
|
83
|
+
SampleConfig.create(:key => 'something_else', :value => 'something')
|
84
|
+
|
85
|
+
lambda{
|
86
|
+
AppCfg.something_else
|
87
|
+
}.should raise_error
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should reflect changes in model after reload has been called" do
|
91
|
+
SampleConfig.create(:key => 'app_name', :value => 'AppCfg')
|
92
|
+
AppCfg::Source.add(SampleConfig)
|
93
|
+
|
94
|
+
AppCfg.app_name.should == 'AppCfg'
|
95
|
+
|
96
|
+
SampleConfig.create(:key => 'something_else', :value => 'something')
|
97
|
+
|
98
|
+
AppCfg::Source.reload_sources!
|
99
|
+
|
100
|
+
AppCfg.something_else.should == 'something'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start do
|
3
|
+
add_filter "/spec/"
|
4
|
+
end
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
+
require 'rspec'
|
9
|
+
require 'appcfg'
|
10
|
+
|
11
|
+
# Requires supporting files with custom matchers and macros, etc,
|
12
|
+
# in ./support/ and its subdirectories.
|
13
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.before(:each) do
|
17
|
+
AppCfg::Source.class_variable_set '@@sources', []
|
18
|
+
@sample_env_yaml_file_path = File.expand_path(File.dirname(__FILE__) + '/support/sample_env_config.yml')
|
19
|
+
@sample_yaml_file_path = File.expand_path(File.dirname(__FILE__) + '/support/sample_config.yml')
|
20
|
+
end
|
21
|
+
|
22
|
+
config.after(:each) do
|
23
|
+
SampleConfig.reset_storage!
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class SampleConfig
|
2
|
+
@@storage = []
|
3
|
+
|
4
|
+
attr_accessor :key
|
5
|
+
attr_accessor :value
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
@key = options[:key]
|
9
|
+
@value = options[:value]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.create(options = {})
|
13
|
+
@@storage << SampleConfig.new(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.all
|
17
|
+
@@storage
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.reset_storage!
|
21
|
+
@@storage = []
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
common: &common
|
2
|
+
app_name: "AppCfg"
|
3
|
+
admin_credentials:
|
4
|
+
username: admin
|
5
|
+
worker_count: 2
|
6
|
+
development:
|
7
|
+
<<: *common
|
8
|
+
mail_server: "dev.mailserver.com"
|
9
|
+
admin_credentials:
|
10
|
+
password: devpass
|
11
|
+
test:
|
12
|
+
<<: *common
|
13
|
+
mail_server: "test.mailserver.com"
|
14
|
+
admin_credentials:
|
15
|
+
password: testpass
|
16
|
+
production:
|
17
|
+
<<: *common
|
18
|
+
mail_server: "prod.mailserver.com"
|
19
|
+
admin_credentials:
|
20
|
+
password: prodpass
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "AppCfg retrieval from YAML" do
|
4
|
+
describe "not environment namespaced" do
|
5
|
+
before(:each) do
|
6
|
+
AppCfg::Source.add(@sample_yaml_file_path)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should support hash syntax for access" do
|
10
|
+
AppCfg['app_name'].should == 'AppCfg'
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should support object syntax for access" do
|
14
|
+
AppCfg.app_name.should == 'AppCfg'
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should allow multi-level access with hash syntax" do
|
18
|
+
AppCfg['admin_credentials']['username'].should == 'admin'
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should allow multi-level access with object syntax" do
|
22
|
+
AppCfg.admin_credentials.username.should == 'admin'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should return nil on non-existent key, hash syntax" do
|
26
|
+
AppCfg['wrong_key'].should be_nil
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should raise error on non-existent key, object syntax" do
|
30
|
+
lambda {
|
31
|
+
AppCfg.wrong_key
|
32
|
+
}.should raise_error
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "environment namespaced" do
|
37
|
+
before(:each) do
|
38
|
+
AppCfg::Source.add(@sample_env_yaml_file_path, :env => 'test')
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should support hash syntax for access" do
|
42
|
+
AppCfg['app_name'].should == 'AppCfg'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should support object syntax for access" do
|
46
|
+
AppCfg.app_name.should == 'AppCfg'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should allow multi-level access with hash syntax" do
|
50
|
+
AppCfg['admin_credentials']['password'].should == 'testpass'
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should allow multi-level access with object syntax" do
|
54
|
+
AppCfg.admin_credentials.password.should == 'testpass'
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should return nil on non-existent key, hash syntax" do
|
58
|
+
AppCfg['wrong_key'].should be_nil
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should raise error on non-existent key, object syntax" do
|
62
|
+
lambda {
|
63
|
+
AppCfg.wrong_key
|
64
|
+
}.should raise_error
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
metadata
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: appcfg
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Toms Mikoss
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-04-11 00:00:00 +03:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 2
|
29
|
+
- 3
|
30
|
+
- 0
|
31
|
+
version: 2.3.0
|
32
|
+
type: :development
|
33
|
+
prerelease: false
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: bundler
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ~>
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
segments:
|
43
|
+
- 1
|
44
|
+
- 0
|
45
|
+
- 0
|
46
|
+
version: 1.0.0
|
47
|
+
type: :development
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: jeweler
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ~>
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
segments:
|
58
|
+
- 1
|
59
|
+
- 5
|
60
|
+
- 2
|
61
|
+
version: 1.5.2
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: *id003
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: simplecov
|
67
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
- 4
|
75
|
+
- 0
|
76
|
+
version: 0.4.0
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *id004
|
80
|
+
description: A gem for centralizing different sources of application configuration data. Supports YAML files, ActiveRecord models and simple hashes as data sources.
|
81
|
+
email: toms.mikoss@gmail.com
|
82
|
+
executables: []
|
83
|
+
|
84
|
+
extensions: []
|
85
|
+
|
86
|
+
extra_rdoc_files:
|
87
|
+
- LICENSE.txt
|
88
|
+
- README.rdoc
|
89
|
+
files:
|
90
|
+
- .document
|
91
|
+
- .rspec
|
92
|
+
- Gemfile
|
93
|
+
- Gemfile.lock
|
94
|
+
- LICENSE.txt
|
95
|
+
- README.rdoc
|
96
|
+
- Rakefile
|
97
|
+
- VERSION
|
98
|
+
- lib/appcfg.rb
|
99
|
+
- lib/appcfg/retrieval.rb
|
100
|
+
- lib/appcfg/source.rb
|
101
|
+
- lib/appcfg/sources/model_source.rb
|
102
|
+
- lib/appcfg/sources/yaml_source.rb
|
103
|
+
- spec/hash_source_config_spec.rb
|
104
|
+
- spec/model_source_spec.rb
|
105
|
+
- spec/source_spec.rb
|
106
|
+
- spec/spec_helper.rb
|
107
|
+
- spec/support/classes/sample_config.rb
|
108
|
+
- spec/support/sample_config.yml
|
109
|
+
- spec/support/sample_env_config.yml
|
110
|
+
- spec/yaml_source_spec.rb
|
111
|
+
has_rdoc: true
|
112
|
+
homepage: http://github.com/tmikoss/appconfig
|
113
|
+
licenses:
|
114
|
+
- MIT
|
115
|
+
post_install_message:
|
116
|
+
rdoc_options: []
|
117
|
+
|
118
|
+
require_paths:
|
119
|
+
- lib
|
120
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
hash: 1567332367739853291
|
126
|
+
segments:
|
127
|
+
- 0
|
128
|
+
version: "0"
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
131
|
+
requirements:
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
segments:
|
135
|
+
- 0
|
136
|
+
version: "0"
|
137
|
+
requirements: []
|
138
|
+
|
139
|
+
rubyforge_project:
|
140
|
+
rubygems_version: 1.3.7
|
141
|
+
signing_key:
|
142
|
+
specification_version: 3
|
143
|
+
summary: A gem for centralizing different sources of application configuration data.
|
144
|
+
test_files:
|
145
|
+
- spec/hash_source_config_spec.rb
|
146
|
+
- spec/model_source_spec.rb
|
147
|
+
- spec/source_spec.rb
|
148
|
+
- spec/spec_helper.rb
|
149
|
+
- spec/support/classes/sample_config.rb
|
150
|
+
- spec/yaml_source_spec.rb
|