conf 0.0.1

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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Jari Bakken
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,51 @@
1
+ = conf
2
+
3
+ Simple configuration that supports inheritance.
4
+
5
+ = Example
6
+
7
+ Conf.define(:parent) do
8
+ properties.like.syntax = :nice
9
+
10
+ single "pair"
11
+
12
+ nested {
13
+ ruby {
14
+ blocks true
15
+ }
16
+ }
17
+ end
18
+
19
+ Conf.define(:child, :parent) do
20
+ nested {
21
+ ruby {
22
+ blocks false
23
+ }
24
+ }
25
+ end
26
+
27
+ c = Conf.get(:child)
28
+ c.nested.ruby.blocks #=> false
29
+ c.single #=> "pair"
30
+ c.properties.like.syntax #=> :nice
31
+
32
+ c.yet.another :value
33
+ c.yet.another #=> :value
34
+
35
+ c.freeze
36
+ c.yet.another :changed #=> can't modify frozen config
37
+
38
+
39
+ == Note on Patches/Pull Requests
40
+
41
+ * Fork the project.
42
+ * Make your feature addition or bug fix.
43
+ * Add tests for it. This is important so I don't break it in a
44
+ future version unintentionally.
45
+ * Commit, do not mess with rakefile, version, or history.
46
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
47
+ * Send me a pull request. Bonus points for topic branches.
48
+
49
+ == Copyright
50
+
51
+ Copyright (c) 2010 Jari Bakken. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "conf"
8
+ gem.summary = %Q{Simple configuraton library that supports inheritance.}
9
+ gem.description = %Q{Simple configuraton library that supports inheritance.}
10
+ gem.email = "jari.bakken@gmail.com"
11
+ gem.homepage = "http://github.com/jarib/conf"
12
+ gem.authors = ["Jari Bakken"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.add_development_dependency "yard", ">= 0"
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ require 'spec/rake/spectask'
23
+ Spec::Rake::SpecTask.new(:spec) do |spec|
24
+ spec.libs << 'lib' << 'spec'
25
+ spec.spec_files = FileList['spec/**/*_spec.rb']
26
+ end
27
+
28
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
29
+ spec.libs << 'lib' << 'spec'
30
+ spec.pattern = 'spec/**/*_spec.rb'
31
+ spec.rcov_opts = %w[--exclude spec,ruby-debug,/Library/Ruby,.gem --include lib/conf]
32
+ spec.rcov = true
33
+ end
34
+
35
+ task :spec => :check_dependencies
36
+
37
+ task :default => :spec
38
+
39
+ begin
40
+ require 'yard'
41
+ YARD::Rake::YardocTask.new
42
+ rescue LoadError
43
+ task :yardoc do
44
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
45
+ end
46
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/lib/conf.rb ADDED
@@ -0,0 +1,108 @@
1
+ class Conf
2
+
3
+ class InvalidKeyError < StandardError
4
+ end
5
+
6
+ def self.configs
7
+ @configs ||= {}
8
+ end
9
+
10
+ def self.define(name, parent = nil, &blk)
11
+ case parent
12
+ when String, Symbol
13
+ parent = get(parent)
14
+ when Configuration, nil
15
+ # ok
16
+ else
17
+ raise TypeError, "expected String, Symbol, Configuration or nil, got #{parent.inspect}:#{parent.class}"
18
+ end
19
+
20
+ conf = configs[name] ||= Configuration.new(parent)
21
+
22
+ conf.instance_eval(&blk)
23
+ conf.freeze
24
+ conf
25
+ end
26
+
27
+ def self.get(name)
28
+ configs[name] or raise ArgumentError, "no config named #{name.inspect}"
29
+ end
30
+
31
+ class Configuration
32
+ def initialize(parent = nil)
33
+ if parent and not parent.kind_of? self.class
34
+ raise TypeError, "expected #{self.class}, got #{parent.inspect}:#{parent.class}"
35
+ end
36
+
37
+ @parent = parent
38
+ @data = {}
39
+ @current_nesting = []
40
+ end
41
+
42
+ def freeze
43
+ @parent && @parent.freeze
44
+ super
45
+ end
46
+
47
+ protected
48
+
49
+ def data() @data end
50
+
51
+ def [](key)
52
+ k = expand_key(key)
53
+ val = @data[k]
54
+ val.nil? ? @parent && @parent[k] : val
55
+ end
56
+
57
+ def []=(key, value)
58
+ @data[expand_key(key)] = value
59
+ @current_nesting.clear
60
+ end
61
+
62
+ def expand_key(key)
63
+ [@current_nesting, key].flatten.compact.join "."
64
+ end
65
+
66
+ def method_missing(meth, *args, &blk)
67
+ m = meth.to_s
68
+
69
+ if m =~ /^(\w+)=/ || args.size == 1
70
+ check_frozen
71
+ key = $1 || m
72
+ self[key] = args.first
73
+ elsif blk
74
+ check_frozen
75
+ @current_nesting << m
76
+ instance_eval(&blk)
77
+ @current_nesting.pop
78
+ else
79
+ obj = self[m]
80
+ if obj != nil
81
+ @current_nesting.clear
82
+ obj
83
+ else
84
+ @current_nesting << m
85
+ validate_nesting if frozen?
86
+ self
87
+ end
88
+ end
89
+ end
90
+
91
+ def validate_nesting
92
+ current = expand_key(nil)
93
+ unless @data.any? { |key,_| key.start_with?(current)} || (@parent && @parent.data.any? { |key,_| key.start_with?(current)})
94
+ @current_nesting.clear
95
+ raise InvalidKeyError, "no such key: #{current.inspect}"
96
+ end
97
+ end
98
+
99
+ def check_frozen
100
+ if frozen?
101
+ @current_nesting.clear
102
+ raise "can't modify frozen config"
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+
data/spec/conf_spec.rb ADDED
@@ -0,0 +1,94 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Conf" do
4
+ before { Conf.configs.clear }
5
+
6
+ it "should set a single value" do
7
+ conf = Conf.define(:tmp) { bar "baz" }
8
+ conf.bar.should == "baz"
9
+ end
10
+
11
+ it "can be defined with a String parent" do
12
+ parent = Conf.define('parent') {}
13
+ lambda { Conf.define('child', 'parent') {} }.should_not raise_error
14
+ end
15
+
16
+ it "can be defined with a Symbol parent" do
17
+ parent = Conf.define(:parent) {}
18
+ lambda { Conf.define(:child, :parent) {} }.should_not raise_error
19
+ end
20
+
21
+ it "can be defined with a Configuration parent" do
22
+ parent = Conf.define(:parent) {}
23
+ lambda { Conf.define(:child, :parent) {} }.should_not raise_error
24
+ end
25
+
26
+ it "can be defined with a Configuration parent" do
27
+ parent = Conf.define(:parent) {}
28
+ lambda { Conf.define(:child, parent) {} }.should_not raise_error
29
+ end
30
+
31
+ it "raises a TypeError if parent is not a known type" do
32
+ lambda { Conf.define(:foo, {}) {} }.should raise_error(TypeError)
33
+ end
34
+
35
+ it "should set a nested properties-style value" do
36
+ conf = Conf.define(:tmp) { bar.baz :boo }
37
+ conf.bar.baz.should == :boo
38
+ end
39
+
40
+ it "should set a value with nested blocks" do
41
+ conf = Conf.define(:tmp) do
42
+ nested { block { also { works true }}}
43
+ end
44
+
45
+ conf.nested.block.also.works.should be_true
46
+ end
47
+
48
+ it "should inherit properties from parent" do
49
+ parent = Conf.define(:parent) { foo.bar.baz = false }
50
+ child = Conf.define(:child, parent) { foo.bar.boo = true }
51
+
52
+ child.foo.bar.baz.should be_false
53
+ child.foo.bar.boo.should be_true
54
+ end
55
+
56
+ it "should override parent properties" do
57
+ parent = Conf.define(:parent) { foo.bar.baz = true }
58
+ child = Conf.define(:child, parent) { foo.bar.baz = false }
59
+
60
+ parent.foo.bar.baz.should be_true
61
+ child.foo.bar.baz.should be_false
62
+ end
63
+
64
+ it "should inherit nested blocks from parent" do
65
+ parent = Conf.define(:parent) { foo { bar { baz true }}}
66
+ child = Conf.define(:child, parent) { foo { bar { boo false }}}
67
+
68
+ child.foo.bar.baz.should be_true
69
+ child.foo.bar.boo.should be_false
70
+ end
71
+
72
+ it "should override parent nested blocks" do
73
+ parent = Conf.define(:parent) { foo { bar { baz true }}}
74
+ child = Conf.define(:child, parent) { foo { bar { baz false }}}
75
+
76
+ parent.foo.bar.baz.should be_true
77
+ child.foo.bar.baz.should be_false
78
+ end
79
+
80
+ it "cannot be changed after being defined" do
81
+ conf = Conf.define(:tmp) { foo "bar" }
82
+ conf.foo.should == "bar"
83
+ lambda { conf.foo "baz" }.should raise_error
84
+ end
85
+
86
+ it "raises a TypeError if parent is not nil or Configuration instance" do
87
+ lambda { Conf::Configuration.new({}) }.should raise_error(TypeError)
88
+ end
89
+
90
+ it "raises an error if the key is not found" do
91
+ conf = Conf.define(:tmp) { foo.bar.baz false }
92
+ lambda { conf.bar }.should raise_error(Conf::InvalidKeyError)
93
+ end
94
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color --backtrace
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'conf'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+ require 'pp'
7
+
8
+ Spec::Runner.configure do |config|
9
+
10
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: conf
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Jari Bakken
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-08-27 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 13
30
+ segments:
31
+ - 1
32
+ - 2
33
+ - 9
34
+ version: 1.2.9
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: yard
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ type: :development
50
+ version_requirements: *id002
51
+ description: Simple configuraton library that supports inheritance.
52
+ email: jari.bakken@gmail.com
53
+ executables: []
54
+
55
+ extensions: []
56
+
57
+ extra_rdoc_files:
58
+ - LICENSE
59
+ - README.rdoc
60
+ files:
61
+ - .document
62
+ - .gitignore
63
+ - LICENSE
64
+ - README.rdoc
65
+ - Rakefile
66
+ - VERSION
67
+ - lib/conf.rb
68
+ - spec/conf_spec.rb
69
+ - spec/spec.opts
70
+ - spec/spec_helper.rb
71
+ has_rdoc: true
72
+ homepage: http://github.com/jarib/conf
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options:
77
+ - --charset=UTF-8
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !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
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project:
101
+ rubygems_version: 1.3.7
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Simple configuraton library that supports inheritance.
105
+ test_files:
106
+ - spec/conf_spec.rb
107
+ - spec/spec_helper.rb