omniconf 0.0.1.pre

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.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ *.swp
3
+ *.sqlite3
4
+ .bundle
5
+ Gemfile.lock
6
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format progress
3
+ --drb
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create ree@omniconf
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in omniconf.gemspec
4
+ gemspec
5
+
6
+ # FIXME: remove this as soon as the official Gem works with Ruby 1.8
7
+ # (see https://github.com/Offirmo/recursive-open-struct/pull/1)
8
+ gem "recursive-open-struct", :git => "git://github.com/Picklive/recursive-open-struct.git"
data/README.md ADDED
@@ -0,0 +1,70 @@
1
+ *THIS STUFF IS STILL ALPHA!*
2
+
3
+ # Setup
4
+
5
+ Configure and load desired backends by creating a new initializer `config/initializers/omniconf.rb`:
6
+
7
+ Omniconf.setup do |config|
8
+ config.sources = {
9
+ :yaml_config => {
10
+ :type => :yaml,
11
+ :file => "config/settings.yml"
12
+ },
13
+ :database_config => {
14
+ :type => :active_record,
15
+ :model_name => :ConfigValue
16
+ }
17
+ }
18
+ end
19
+
20
+ # Usage
21
+
22
+ $ rails c
23
+ > Omniconf.configuration.some_config_from_database # value from ConfigValue model
24
+ "abc"
25
+ > Omniconf.configuration_hash["some_config_from_database"] # if you prefer the hash way
26
+ "abc"
27
+ > Omniconf.configuration.some_config_from_yaml # value from config/settings.yml
28
+ 123
29
+ > Omniconf.configuration.api.username # it works with nested values too
30
+ "root"
31
+
32
+ ## Backend sources
33
+
34
+ `:type` is the only required parameter.
35
+ Other parameters default to standard values for Rails.
36
+
37
+ ### Yaml
38
+
39
+ Nothing to configure apart from a YAML file.
40
+
41
+ _Note: read-only._
42
+
43
+ ### ActiveRecord
44
+
45
+ Add `gem 'activerecord'` in your `Gemfile`.
46
+
47
+ Create a new migration to add the config table: _(FIXME: add a rake task for this)_
48
+
49
+ class CreateConfigValues < ActiveRecord::Migration
50
+ def change
51
+ create_table :config_values do |t|
52
+ t.string :key, :null => false
53
+ t.string :value, :null => false
54
+ end
55
+ add_index :config_values, :key, :unique => true
56
+ end
57
+ end
58
+
59
+ ### Redis
60
+
61
+ Add `gem 'redis'` in your `Gemfile`.
62
+
63
+ Not yet implemented.
64
+
65
+ # Testing
66
+
67
+ `rake`
68
+
69
+ Tested on _ree-1.8.7_ and _ruby-1.9.3_.
70
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task :default => :spec
6
+
@@ -0,0 +1,72 @@
1
+ require 'active_record'
2
+
3
+ module Omniconf
4
+ module Adapter
5
+ class ActiveRecord < Base
6
+ attr_reader :model
7
+
8
+ def initialize params
9
+ defaults = {
10
+ :model_name => :ConfigValue,
11
+ :environment => Rails.env,
12
+ :config_file => File.join(Rails.root, 'config/database.yml')
13
+ }
14
+ @params = defaults.merge params
15
+ end
16
+
17
+ def load_configuration!
18
+ setup
19
+
20
+ @configuration_hash = {}
21
+ @model.all.map do |record|
22
+ @configuration_hash[record.key] = record.value
23
+ end
24
+ merge_configuration! @configuration_hash
25
+ end
26
+
27
+ def setup
28
+ unless Object.const_defined? @params[:model_name]
29
+ unless ::ActiveRecord::Base.connected?
30
+ ::ActiveRecord::Base.configurations = YAML::load(IO.read(@params[:config_file]))
31
+ ::ActiveRecord::Base.establish_connection(@params[:environment])
32
+ end
33
+
34
+ klass = Class.new ::ActiveRecord::Base do
35
+ validates_uniqueness_of :key
36
+
37
+ def self.[]=(key, value)
38
+ if item = self.find_by_key(key.to_s)
39
+ item.value = value.to_s
40
+ else
41
+ item = self.new(:key => key.to_s, :value => value.to_s)
42
+ end
43
+ item.save!
44
+ item.value
45
+ end
46
+
47
+ def self.[](key)
48
+ if item = find_by_key(key.to_s)
49
+ return item.value
50
+ end
51
+ end
52
+
53
+ def self.get_or_default(key, default)
54
+ if item = find_by_key(key.to_s)
55
+ return item.value
56
+ else
57
+ self[key] = default
58
+ return default
59
+ end
60
+ end
61
+
62
+ end
63
+
64
+ Object.const_set @params[:model_name], klass
65
+ end
66
+
67
+ @model ||= @params[:model_name].to_s.constantize
68
+ end
69
+ end
70
+ end
71
+ end
72
+
@@ -0,0 +1,28 @@
1
+ require 'recursive_open_struct'
2
+
3
+ module Omniconf
4
+ module Adapter
5
+ class Base
6
+ attr_accessor :configuration_hash
7
+
8
+ def configuration
9
+ RecursiveOpenStruct.new @configuration_hash
10
+ end
11
+
12
+ def merge_configuration! with_config
13
+ Omniconf.logger.debug "Merged global configuration BEFORE: #{Omniconf.configuration_hash.inspect}"
14
+ adapter = self.class.ancestors.first.to_s.split(':').last
15
+ Omniconf.logger.debug "Merging from #{adapter} configuration: #{with_config.inspect}"
16
+ Omniconf.configuration_hash.merge!(with_config) do |key, old_val, new_val|
17
+ Omniconf.logger.warn \
18
+ "'#{key}' has been overriden with value from #{adapter} configuration " <<
19
+ "(old value: #{old_val.inspect}, new value: #{new_val.inspect})" if new_val != old_val
20
+ new_val
21
+ end
22
+ Omniconf.logger.debug "Merged global configuration AFTER: #{Omniconf.configuration_hash.inspect}"
23
+ Omniconf.configuration = RecursiveOpenStruct.new Omniconf.configuration_hash
24
+ end
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,22 @@
1
+ module Omniconf
2
+ module Adapter
3
+ class Yaml < Base
4
+
5
+ def initialize params
6
+ defaults = {
7
+ :environment => Rails.env,
8
+ :file => File.join(Rails.root, 'config/settings.yml')
9
+ }
10
+ @params = defaults.merge params
11
+ end
12
+
13
+ def load_configuration!
14
+ yaml = ::YAML.load_file(@params[:file])
15
+ @configuration_hash = yaml[@params[:environment]]
16
+ merge_configuration! @configuration_hash
17
+ end
18
+
19
+ end
20
+ end
21
+ end
22
+
@@ -0,0 +1,7 @@
1
+ module Omniconf
2
+ class Settings
3
+ attr_accessor :load_configuration
4
+ attr_accessor :sources
5
+ attr_accessor :logger_level
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module Omniconf
2
+ VERSION = "0.0.1.pre"
3
+ end
data/lib/omniconf.rb ADDED
@@ -0,0 +1,60 @@
1
+ require 'logger'
2
+ require "omniconf/version"
3
+ require "omniconf/settings"
4
+
5
+ module Omniconf
6
+ class << self
7
+ attr_reader :settings # Omniconf settings
8
+ attr_accessor :configuration # Global configuration as a RecursiveOpenStruct
9
+ attr_writer :configuration_hash # Global configuration as an Hash
10
+
11
+ def configuration_hash
12
+ @configuration_hash ||= {}
13
+ end
14
+
15
+ def logger
16
+ unless @logger
17
+ # @logger ||= defined? Rails.logger ? Rails.logger : Logger.new(STDOUT)
18
+ @logger = Logger.new(STDOUT)
19
+ @logger.level = @settings.logger_level if @settings
20
+ @logger.level = Logger::INFO if @logger.level.nil?
21
+ end
22
+ @logger
23
+ end
24
+
25
+ def setup
26
+ @settings = Settings.new
27
+ yield @settings
28
+
29
+ register_sources
30
+
31
+ @settings.load_configuration = true if @settings.load_configuration.nil?
32
+ load_configuration! if @settings.load_configuration
33
+ end
34
+
35
+ def load_configuration!
36
+ @settings.sources.each do |source_id, params|
37
+ params[:adapter].load_configuration!
38
+ Omniconf.logger.info "Loaded configuration from #{source_id} source"
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def register_sources
45
+ @settings.sources.each do |source_id, params|
46
+ adapter_file = params[:type].to_s
47
+ require "omniconf/adapters/base"
48
+ require "omniconf/adapters/#{adapter_file}"
49
+ adapter_class = adapter_file.to_s.split('_').map {|w| w.capitalize}.join
50
+ raise unless params[:adapter].nil?
51
+ params[:adapter] = Omniconf::Adapter.class_eval do
52
+ const_get(adapter_class).new(params)
53
+ end
54
+ Omniconf.logger.info "Registered #{adapter_class}::#{source_id} source"
55
+ end
56
+ end
57
+
58
+ end
59
+ end
60
+
data/omniconf.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "omniconf/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "omniconf"
7
+ s.version = Omniconf::VERSION
8
+ s.authors = ["Cédric Felizard"]
9
+ s.email = ["cedric@picklive.com"]
10
+ s.homepage = "https://github.com/Picklive/omniconf"
11
+ s.summary = %q{Merge multiple configuration sources into one.}
12
+ s.description = %q{Merge configurations from multiple backends for easy use in a Rails application.}
13
+
14
+ s.rubyforge_project = "omniconf"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_runtime_dependency "recursive-open-struct"
22
+
23
+ s.add_development_dependency "rake"
24
+ s.add_development_dependency "rspec"
25
+ s.add_development_dependency "sqlite3"
26
+ s.add_development_dependency "activerecord"
27
+ end
data/spec/data.sqlite3 ADDED
Binary file
@@ -0,0 +1,5 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: data.sqlite3
4
+ pool: 5
5
+ timeout: 5000
@@ -0,0 +1,10 @@
1
+ ActiveRecord::Schema.define :version => 0 do
2
+ create_table :config_values, :force => true do |t|
3
+ t.string :key
4
+ t.string :value
5
+ end
6
+ end
7
+
8
+ ConfigValue.create!({:key => 'foo', :value => 'bar'})
9
+ ConfigValue.create!({:key => 'foo2', :value => 'bar2'})
10
+
@@ -0,0 +1,8 @@
1
+ development:
2
+ api:
3
+ username: user
4
+ password: pass
5
+ test:
6
+ api:
7
+ username: test_user
8
+ password: test_password
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ require 'omniconf/adapters/active_record'
3
+
4
+ describe Omniconf::Adapter::ActiveRecord do
5
+ before do
6
+ @database = Omniconf::Adapter::ActiveRecord.new({
7
+ :model_name => :ConfigValue,
8
+ :environment => 'test',
9
+ :config_file => File.join(File.dirname(__FILE__),
10
+ '../../fixtures/omniconf/adapters/active_record/config/database.yml'
11
+ )
12
+ })
13
+ @database.setup
14
+
15
+ require File.join(File.dirname(__FILE__),
16
+ '../../fixtures/omniconf/adapters/active_record/db/schema.rb'
17
+ )
18
+
19
+ @database.load_configuration!
20
+ end
21
+
22
+ describe "#[]" do
23
+ it "returns configuration values from database" do
24
+ @database.configuration.foo.should == 'bar'
25
+ @database.configuration.foo2.should == 'bar2'
26
+ end
27
+
28
+ pending "it doesn't cast values to String" # TODO serialize them and keep type
29
+ end
30
+
31
+ describe "#get_or_default" do
32
+ it "sets default value if new" do
33
+ @database.model.get_or_default('newValue', 'a').should == 'a'
34
+ @database.model.get_or_default('newValue', 'b').should == 'a'
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+ require 'omniconf/adapters/yaml'
3
+
4
+ describe Omniconf::Adapter::Yaml do
5
+ def load_environment env
6
+ @yaml = Omniconf::Adapter::Yaml.new({
7
+ :environment => env,
8
+ :file => File.join(File.dirname(__FILE__),
9
+ '../../fixtures/omniconf/adapters/yaml/config/settings.yml'
10
+ )
11
+ })
12
+ @yaml.load_configuration!
13
+ end
14
+
15
+ it "allows to get nested attributes" do
16
+ load_environment 'test'
17
+ @yaml.configuration.api.username.should == 'test_user'
18
+ @yaml.configuration.api.password.should == 'test_password'
19
+ end
20
+
21
+ it "loads the right environment" do
22
+ load_environment 'development'
23
+ @yaml.configuration.api.username.should == 'user'
24
+ @yaml.configuration.api.password.should == 'pass'
25
+ end
26
+ end
27
+
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+ require 'omniconf'
3
+
4
+ describe Omniconf do
5
+
6
+ describe "#setup" do
7
+ it "reads the settings" do
8
+ Omniconf.setup do |config|
9
+ config.load_configuration = false
10
+ config.sources = {
11
+ :yaml_conf => {:type => :yaml, :file => "settings.yml"}
12
+ }
13
+ end
14
+
15
+ Omniconf.settings.sources[:yaml_conf][:file].should == "settings.yml"
16
+ end
17
+ end
18
+
19
+ describe "#load_configuration!" do
20
+ def setup
21
+ Omniconf.setup do |config|
22
+ config.load_configuration = false
23
+ config.sources = {
24
+ :yaml => {
25
+ :type => :yaml,
26
+ :environment => 'test',
27
+ :file => File.join(File.dirname(__FILE__),
28
+ 'fixtures/omniconf/adapters/yaml/config/settings.yml'
29
+ )
30
+ },
31
+ :database => {
32
+ :type => :active_record,
33
+ :model_name => :ConfigValue,
34
+ :environment => 'test',
35
+ :config_file => File.join(File.dirname(__FILE__),
36
+ 'fixtures/omniconf/adapters/active_record/config/database.yml'
37
+ )
38
+ }
39
+ }
40
+ end
41
+ end
42
+
43
+ def insert_db_fixtures
44
+ @database = Omniconf.settings.sources[:database][:adapter]
45
+ @database.setup
46
+
47
+ require File.join(File.dirname(__FILE__),
48
+ 'fixtures/omniconf/adapters/active_record/db/schema.rb'
49
+ )
50
+ end
51
+
52
+ it "loads and merges all configurations" do
53
+ setup
54
+ insert_db_fixtures
55
+
56
+ Omniconf.load_configuration!
57
+
58
+ Omniconf.configuration.api.password.should == 'test_password'
59
+ Omniconf.configuration.foo.should == 'bar'
60
+ end
61
+ end
62
+ end
63
+
@@ -0,0 +1,3 @@
1
+ require 'lib/omniconf/adapters/base'
2
+ require 'spec/support/mock'
3
+
@@ -0,0 +1,15 @@
1
+ # Mock Rails.{env,root} to test defaults settings
2
+ unless defined? Rails
3
+ class Rails
4
+ class << self
5
+ def env
6
+ 'test'
7
+ end
8
+
9
+ def root
10
+ File.join(File.dirname(__FILE__), '..')
11
+ end
12
+ end
13
+ end
14
+ end
15
+
metadata ADDED
@@ -0,0 +1,167 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: omniconf
3
+ version: !ruby/object:Gem::Version
4
+ hash: 961915968
5
+ prerelease: 6
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ - pre
11
+ version: 0.0.1.pre
12
+ platform: ruby
13
+ authors:
14
+ - "C\xC3\xA9dric Felizard"
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2012-02-01 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: recursive-open-struct
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rake
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: rspec
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :development
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: sqlite3
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :development
76
+ version_requirements: *id004
77
+ - !ruby/object:Gem::Dependency
78
+ name: activerecord
79
+ prerelease: false
80
+ requirement: &id005 !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ type: :development
90
+ version_requirements: *id005
91
+ description: Merge configurations from multiple backends for easy use in a Rails application.
92
+ email:
93
+ - cedric@picklive.com
94
+ executables: []
95
+
96
+ extensions: []
97
+
98
+ extra_rdoc_files: []
99
+
100
+ files:
101
+ - .gitignore
102
+ - .rspec
103
+ - .rvmrc
104
+ - Gemfile
105
+ - README.md
106
+ - Rakefile
107
+ - lib/omniconf.rb
108
+ - lib/omniconf/adapters/active_record.rb
109
+ - lib/omniconf/adapters/base.rb
110
+ - lib/omniconf/adapters/yaml.rb
111
+ - lib/omniconf/settings.rb
112
+ - lib/omniconf/version.rb
113
+ - omniconf.gemspec
114
+ - spec/data.sqlite3
115
+ - spec/fixtures/omniconf/adapters/active_record/config/database.yml
116
+ - spec/fixtures/omniconf/adapters/active_record/db/schema.rb
117
+ - spec/fixtures/omniconf/adapters/yaml/config/settings.yml
118
+ - spec/omniconf/adapters/active_record_spec.rb
119
+ - spec/omniconf/adapters/yaml_spec.rb
120
+ - spec/omniconf_spec.rb
121
+ - spec/spec_helper.rb
122
+ - spec/support/mock.rb
123
+ homepage: https://github.com/Picklive/omniconf
124
+ licenses: []
125
+
126
+ post_install_message:
127
+ rdoc_options: []
128
+
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ none: false
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ hash: 3
137
+ segments:
138
+ - 0
139
+ version: "0"
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ none: false
142
+ requirements:
143
+ - - ">"
144
+ - !ruby/object:Gem::Version
145
+ hash: 25
146
+ segments:
147
+ - 1
148
+ - 3
149
+ - 1
150
+ version: 1.3.1
151
+ requirements: []
152
+
153
+ rubyforge_project: omniconf
154
+ rubygems_version: 1.8.10
155
+ signing_key:
156
+ specification_version: 3
157
+ summary: Merge multiple configuration sources into one.
158
+ test_files:
159
+ - spec/data.sqlite3
160
+ - spec/fixtures/omniconf/adapters/active_record/config/database.yml
161
+ - spec/fixtures/omniconf/adapters/active_record/db/schema.rb
162
+ - spec/fixtures/omniconf/adapters/yaml/config/settings.yml
163
+ - spec/omniconf/adapters/active_record_spec.rb
164
+ - spec/omniconf/adapters/yaml_spec.rb
165
+ - spec/omniconf_spec.rb
166
+ - spec/spec_helper.rb
167
+ - spec/support/mock.rb