configulations 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "http://rubygems.org"
2
+
3
+ group :development do
4
+ gem "rspec", "~> 2.3.0"
5
+ gem "bundler", "~> 1.0.0"
6
+ gem "jeweler", "~> 1.6.2"
7
+ gem "rcov", ">= 0"
8
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,28 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.2)
5
+ git (1.2.5)
6
+ jeweler (1.6.2)
7
+ bundler (~> 1.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ rake (0.9.2)
11
+ rcov (0.9.9)
12
+ rspec (2.3.0)
13
+ rspec-core (~> 2.3.0)
14
+ rspec-expectations (~> 2.3.0)
15
+ rspec-mocks (~> 2.3.0)
16
+ rspec-core (2.3.1)
17
+ rspec-expectations (2.3.0)
18
+ diff-lcs (~> 1.1.2)
19
+ rspec-mocks (2.3.0)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ bundler (~> 1.0.0)
26
+ jeweler (~> 1.6.2)
27
+ rcov
28
+ rspec (~> 2.3.0)
data/LICENSE.txt ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2011 Leon Gersing
2
+ Copyright (c) 2011 No Spoon Software
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ The developers using the software are responsible for having fun.
16
+ It may seem like work, it may seem like the same task that you've
17
+ solved over and over again but it's up to you to shape the experiences
18
+ of your life. Enjoy yourself, it's a celebration.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,58 @@
1
+ = Configulations - You can have a simple configuration class for Ruby apps!
2
+
3
+ This is a bare bones, simple way to add configuration files to your ruby
4
+ apps using either json or yml. Then, you can simply call into the configurator like
5
+ any plain ol' Ruby object using the message passing dot syntax rather than
6
+ hash/ordinal accessors.
7
+
8
+ Included is a module called MagicHash that does all the magic mapping for the object.
9
+ It should be considered pretty dangerous as it augments the expected behavior of Hash.
10
+ To ensure as much flexibility without damaging Hash directly, configurator simply extends
11
+ the instance of the property bag so that we get the power of hash without messing up
12
+ hash for any one that is using it.
13
+
14
+ == EXAMPLE
15
+
16
+ by default, Configulations is going to recursively dive into a "config" directory located
17
+ by the location of the executing ruby process. from there, any files ending in .yml or .json
18
+ with the respetive content-types of YAML or JSON will be loaded. The name of the file is
19
+ the first key and all properties can be fetched from there.
20
+
21
+ config = Configulations.new #=> finds config/server.json and config/admins.yml
22
+ config.server.host #=> "localhost"
23
+ config.admins.include? User.find_by_name("leon") #=> true
24
+
25
+ == Known Issues
26
+
27
+ * Right now data is first in- first out. If you have 2 config files with the same name
28
+ the last one in, wins.
29
+ * There is no inheritence. You can't set global options and then over-ride them with
30
+ another file.
31
+
32
+ You can however, augment the settings anytime you like.
33
+
34
+ config.admins.pop #=> gives one of our admins.
35
+
36
+ == Future
37
+
38
+ This is all I needed for now but I'd love to work out those issues mentioned above
39
+ as well as allow for some robust Ruby configuration files that could take advantage
40
+ of run time-evaluation and flow control for those situations when you'd like to let
41
+ configuration be a bit more flexible than a yml, json file would allow.
42
+
43
+ == Contributing to configulations
44
+
45
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
46
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
47
+ * Fork the project
48
+ * Start a feature/bugfix branch
49
+ * Commit and push until you are happy with your contribution
50
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
51
+ * 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.
52
+ * This list is from Jeweler. Which is awesome...
53
+
54
+ == Copyright
55
+
56
+ Copyright (c) 2011 Leon Gersing. See LICENSE.txt for
57
+ further details.
58
+
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "configulations"
18
+ gem.homepage = "http://github.com/leongersing/configurator"
19
+ gem.license = "MIT"
20
+ gem.summary = "Simple Config class for Ruby apps."
21
+ gem.description = "Auto-create configuration objects for your applications from yml and json files."
22
+ gem.email = "leongersing@gmail.com"
23
+ gem.authors = ["Leon Gersing"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ task :default => :spec
40
+
41
+ require 'rake/rdoctask'
42
+ Rake::RDocTask.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "configurator #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1,2 @@
1
+ 0.1.0
2
+
@@ -0,0 +1,3 @@
1
+ host: "localhost"
2
+ port: 3000
3
+ boo: true
data/config/foo.json ADDED
@@ -0,0 +1,5 @@
1
+ { "name": "foo"
2
+ , "person": "bar"
3
+ , "people":["frank", "sally"]
4
+ , "other":[{"foo":"bar"},{"bar":"baz"}]
5
+ }
data/config/server.yml ADDED
@@ -0,0 +1,7 @@
1
+ host: "localhost"
2
+ port: 8080
3
+ secure: false
4
+ content-types:
5
+ - "html"
6
+ - "json"
7
+ - "xml"
@@ -0,0 +1,65 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{configulations}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Leon Gersing"]
12
+ s.date = %q{2011-07-01}
13
+ s.description = %q{Auto-create configuration objects for your applications from yml and json files.}
14
+ s.email = %q{leongersing@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE.txt",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "config/development.yml",
29
+ "config/foo.json",
30
+ "config/server.yml",
31
+ "configulations.gemspec",
32
+ "lib/configulations.rb",
33
+ "lib/magic_hash.rb",
34
+ "spec/configulations_spec.rb",
35
+ "spec/magic_hash_spec.rb",
36
+ "spec/spec_helper.rb"
37
+ ]
38
+ s.homepage = %q{http://github.com/leongersing/configulations}
39
+ s.licenses = ["MIT"]
40
+ s.require_paths = ["lib"]
41
+ s.rubygems_version = %q{1.6.2}
42
+ s.summary = %q{Simple Config class for Ruby apps.}
43
+
44
+ if s.respond_to? :specification_version then
45
+ s.specification_version = 3
46
+
47
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
48
+ s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
49
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
50
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.2"])
51
+ s.add_development_dependency(%q<rcov>, [">= 0"])
52
+ else
53
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
54
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
55
+ s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
56
+ s.add_dependency(%q<rcov>, [">= 0"])
57
+ end
58
+ else
59
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
60
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
61
+ s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
62
+ s.add_dependency(%q<rcov>, [">= 0"])
63
+ end
64
+ end
65
+
@@ -0,0 +1,37 @@
1
+ require 'yaml'
2
+ require 'json'
3
+ require 'magic_hash'
4
+
5
+ class Configulations
6
+ attr_accessor :properties
7
+
8
+ def initialize
9
+ @properties = {}
10
+ @properties.extend(MagicHash)
11
+
12
+ find_yaml_properties
13
+ find_json_properties
14
+
15
+ @properties.objectify
16
+ yield self if block_given?
17
+ self
18
+ end
19
+
20
+ def find_json_properties
21
+ Dir[File.expand_path(".") << "/config/**/*.json"].each do |json_file|
22
+ @properties[File.basename(json_file, ".json")] = JSON.load(File.read(json_file))
23
+ end
24
+ end
25
+
26
+ def find_yaml_properties
27
+ Dir[File.expand_path(".") << "/config/**/*.yml"].each do |yaml_file|
28
+ @properties[File.basename(yaml_file, ".yml")] = YAML.load(File.read(yaml_file))
29
+ end
30
+ end
31
+
32
+ def method_missing(message_name, *message_arguments, &optional_block)
33
+ result = properties.send message_name.to_sym, *message_arguments
34
+ return result if result
35
+ super message_name, *message_arguments, &optional_block
36
+ end
37
+ end
data/lib/magic_hash.rb ADDED
@@ -0,0 +1,69 @@
1
+ module MagicHash
2
+
3
+ def objectify
4
+ self.make_keys_valid_message_aliases
5
+ self.hash_all_keys
6
+ self
7
+ end
8
+
9
+ def make_keys_valid_message_aliases
10
+ tmp={}
11
+ tmp.extend(MagicHash)
12
+ self.each_pair do |key, value|
13
+ new_key = key.gsub(/\s|-/,"_").to_sym
14
+ if(value.is_a? Hash)
15
+ value.extend(MagicHash) unless value.respond_to? :objectify
16
+ tmp[new_key] = value.make_keys_valid_message_aliases
17
+ elsif(value.is_a? Array)
18
+ tmp[new_key] = value.map do |val|
19
+ if val.is_a?(Hash)
20
+ val.extend(MagicHash) unless val.respond_to? :objectify
21
+ val.make_keys_valid_message_aliases
22
+ else
23
+ val
24
+ end
25
+ end
26
+ else
27
+ tmp[new_key] = value
28
+ end
29
+ end
30
+ self.replace(tmp)
31
+ end
32
+
33
+ def hash_all_keys()
34
+ tmp = {}
35
+ tmp.extend(MagicHash)
36
+ self.each_pair do |k, v|
37
+ if v.is_a? Hash
38
+ v.extend(self) unless v.respond_to? :objectify
39
+ tmp[k.to_sym]= v.hash_all_keys
40
+ elsif v.is_a? Array
41
+ v = v.map do |value|
42
+ if value.is_a?(Hash.class)
43
+ value.extend(MagicHash) unless value.respond_to? :objectify
44
+ value.hash_all_keys
45
+ else
46
+ value
47
+ end
48
+ end
49
+ tmp[k.to_sym]= v
50
+ else
51
+ tmp[k.to_sym]= v
52
+ end
53
+ end
54
+ self.replace(tmp)
55
+ end
56
+
57
+ def method_missing(method_name, *args, &blk)
58
+ message = method_name.to_s.downcase.gsub(/-/,"_").to_sym
59
+ if message =~ /=/
60
+ self[message]= args.flatten.first
61
+ return
62
+ else
63
+ result = self[message]
64
+ return result if result
65
+ end
66
+
67
+ super(method_name, *args, &blk)
68
+ end
69
+ end
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+
3
+ describe Configulations do
4
+ describe "looks like an object" do
5
+ it "allows for dot-style syntax accessors." do
6
+ c = Configulations.new
7
+ c.development.boo = true
8
+ c.development.boo.should == true
9
+ end
10
+
11
+ it "loads yml properties" do
12
+ c = Configulations.new
13
+ c.development.host.should == "localhost"
14
+ end
15
+
16
+ it "loads json properties" do
17
+ c = Configulations.new
18
+ c.foo.name.should == 'foo'
19
+ end
20
+
21
+ it "loves lazy duck typing" do
22
+ c = Configulations.new
23
+ c.server.content_types.should be_a_kind_of Array
24
+ c.server.content_types.length.should == 3
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,19 @@
1
+ require "spec_helper"
2
+
3
+ describe(MagicHash) do
4
+ describe("what makes it magical...") do
5
+ it "gives dot syntax to Hash." do
6
+ options ={:foo => "bar"}
7
+ options.extend(MagicHash)
8
+ options.foo.should == "bar"
9
+ end
10
+
11
+ it "is a hash when asked." do
12
+ options ={:foo => "bar"}
13
+ options.extend(MagicHash)
14
+ options.kind_of?(Hash).should == true
15
+ options.is_a?(Hash).should == true
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'configulations'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: configulations
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Leon Gersing
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-07-01 00:00:00 -04:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rspec
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 2.3.0
24
+ type: :development
25
+ prerelease: false
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 1.0.0
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: jeweler
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.6.2
46
+ type: :development
47
+ prerelease: false
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: rcov
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :development
58
+ prerelease: false
59
+ version_requirements: *id004
60
+ description: Auto-create configuration objects for your applications from yml and json files.
61
+ email: leongersing@gmail.com
62
+ executables: []
63
+
64
+ extensions: []
65
+
66
+ extra_rdoc_files:
67
+ - LICENSE.txt
68
+ - README.rdoc
69
+ files:
70
+ - .document
71
+ - .rspec
72
+ - Gemfile
73
+ - Gemfile.lock
74
+ - LICENSE.txt
75
+ - README.rdoc
76
+ - Rakefile
77
+ - VERSION
78
+ - config/development.yml
79
+ - config/foo.json
80
+ - config/server.yml
81
+ - configurator.gemspec
82
+ - lib/configulations.rb
83
+ - lib/magic_hash.rb
84
+ - spec/configurator_spec.rb
85
+ - spec/magic_hash_spec.rb
86
+ - spec/spec_helper.rb
87
+ has_rdoc: true
88
+ homepage: http://github.com/leongersing/configurator
89
+ licenses:
90
+ - MIT
91
+ post_install_message:
92
+ rdoc_options: []
93
+
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ hash: -1373029058140856963
102
+ segments:
103
+ - 0
104
+ version: "0"
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: "0"
111
+ requirements: []
112
+
113
+ rubyforge_project:
114
+ rubygems_version: 1.6.2
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: Simple Config class for Ruby apps.
118
+ test_files: []
119
+