zen_config 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in zen_config.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Gauthier Delacroix
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # ZenConfig
2
+
3
+ ZenConfig is an attempt to rewrite Zend Framework's Zend_Config for Ruby.
4
+
5
+ It allows easy management of configuration objects and files.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'zen_config'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install zen_config
20
+
21
+ ## Usage
22
+
23
+ Instantiate ZenConfig with a configuration hash :
24
+
25
+ config_hash = { :foo => "foo value" }
26
+ MyConfig = ZenConfig.new config_hash
27
+ MyConfig.foo
28
+ => "foo value"
29
+
30
+ By default, ZenConfig is read only :
31
+
32
+ MyConfig.foo = "bar value"
33
+ NoMethodError: undefined method `foo=' for #<ZenConfig:0x00000002ee52f8>
34
+
35
+ But changes can be allowed on build time :
36
+
37
+ MyConfig = ZenConfig.new config_hash, true
38
+ MyConfig.foo = "bar value"
39
+ => "bar value"
40
+ MyConfig.foo
41
+ => "bar value"
42
+
43
+ Then the object can be locked to read only again :
44
+
45
+ MyConfig.read_only
46
+ MyConfig.read_only?
47
+ => true
48
+ MyConfig.foo = "foo value"
49
+ NoMethodError: undefined method `foo=' for #<ZenConfig:0x00000002ee52f8>
50
+
51
+ And there's no way to unlock write.
52
+ This guarantees that ZenConfig data hasn't been altered since read-only lock has been set.
53
+ You should not use unlocked ZenConfig in your application code, since you don't know when and where it has been modified.
54
+ Dynamic persistent writes functions will come in future versions.
55
+
56
+ Sub configurations can be nested (if ZenConfig object is not locked) :
57
+
58
+ MyConfig.new :bar
59
+ MyConfig.bar.baz = "baz value"
60
+
61
+ Nested configurations are ZenConfigs. This allow accessing configuration on a specific context :
62
+
63
+ MyBarConfig = MyConfig.bar
64
+ MyBarConfig.class
65
+ => ZenConfig
66
+ MyBarConfig.baz
67
+ => "baz value"
68
+
69
+ Nested ZenConfigs can access their parent :
70
+
71
+ MyBarConfig.parent.foo
72
+ => "bar value"
73
+
74
+ Of course, root ZenConfig has no parent :
75
+
76
+ MyConfig.parent
77
+ => nil
78
+
79
+ You can check if a config key exists :
80
+
81
+ MyConfig.foo_exists?
82
+ => true
83
+
84
+ Count keys :
85
+
86
+ MyConfig.count
87
+ => 2
88
+ MyConfig.bar.count
89
+ => 1
90
+
91
+ ZenConfigs can be converted to hashs :
92
+
93
+ MyConfig.to_hash
94
+ => {:foo=>"bar value", :bar=>{:baz=>"baz value"}}
95
+
96
+ And finally, config keys can be deleted (if ZenConfig is unlocked) :
97
+
98
+ MyConfig.delete :foo
99
+ MyConfig.to_hash
100
+ => {:bar=>{:baz=>"baz value"}}
101
+
102
+ Note : ZenConfig methods are reserved words that can not be used as config keys.
103
+ They'll probably be renamed with a leading underscore in future versions.
104
+
105
+ ## Goals
106
+
107
+ - Provide hierarchical configuration objects => Done!
108
+ - Bring a read-only lock mode to guarantee config values haven't been modified => Done!
109
+ - Allow config file loading.
110
+ - Allow config file writing.
111
+ - Provide full unit tests.
112
+
113
+ ## Known bugs
114
+
115
+ - Nested hashs raise an error on init
116
+ - Merging doesn't always work
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,3 @@
1
+ class ZenConfig
2
+ VERSION = "0.0.1"
3
+ end
data/lib/zen_config.rb ADDED
@@ -0,0 +1,193 @@
1
+ require 'zen_config/version'
2
+ require 'forwardable'
3
+
4
+ class ZenConfig
5
+ include Enumerable
6
+ extend Forwardable
7
+
8
+ def_delegators :@data, :each, :<<
9
+
10
+ def initialize hash, allow_modifications = false
11
+ @allow_modifications = !!allow_modifications
12
+ @loaded_section = nil
13
+ @index = 0
14
+ @data = {}
15
+
16
+ hash.each do |key, value|
17
+ key = key.to_sym
18
+
19
+ if value.is_a? Hash
20
+ @data[key] = self.new value, @allow_modifications
21
+ else
22
+ @data[key] = value
23
+ end
24
+
25
+ set_key_parent key
26
+ end
27
+
28
+ update_count
29
+ end
30
+
31
+ # Accessors
32
+
33
+ def get name, default = nil
34
+ result = default
35
+
36
+ if @data.has_key? name
37
+ result = @data[name]
38
+ end
39
+
40
+ return result
41
+ end
42
+
43
+ def set key, value
44
+ if @allow_modifications
45
+ if value.is_a? Hash
46
+ @data[key] = self.new value, true
47
+ else
48
+ @data[key] = value
49
+ end
50
+
51
+ set_key_parent key
52
+ update_count
53
+
54
+ return value
55
+ end
56
+ end
57
+
58
+ # Data
59
+
60
+ def count
61
+ @count
62
+ end
63
+
64
+ def delete key
65
+ if @allow_modifications
66
+ backup = @data[key]
67
+ @data.delete key
68
+ update_count
69
+ return backup
70
+ end
71
+ end
72
+
73
+ def exists? key
74
+ @data.has_key? key
75
+ end
76
+
77
+ def new key, force = false
78
+ key = key.to_sym
79
+
80
+ if @allow_modifications
81
+ if (!exists? key) || force
82
+ @data[key] = ZenConfig.new({}, true)
83
+ set_key_parent key
84
+ else
85
+ raise "'#{key}' key already exists."
86
+ end
87
+ end
88
+ end
89
+
90
+ #Global
91
+
92
+ def merge merge
93
+ raise "Merged configuration must be a ZenConfig" unless merge.kind_of? ZenConfig
94
+
95
+ merge.each do |key, value|
96
+ if @data.has_key? key
97
+ if (value.kind_of? ZenConfig) && (@data[key].kind_of? ZenConfig)
98
+ @data[key] = @data[key].merge(ZenConfig.new value.to_hash, !read_only?)
99
+ else
100
+ @data[key] = value
101
+ end
102
+ else
103
+ if value.kind_of? ZenConfig
104
+ @data[key] = ZenConfig.new value.to_hash, read_only?
105
+ else
106
+ @data[key] = value
107
+ end
108
+ end
109
+
110
+ set_key_parent key
111
+ end
112
+
113
+ return self
114
+ end
115
+
116
+ def method_missing method, *args
117
+ value = args.first
118
+
119
+ # Checks if a key exists
120
+ if /\A(.*)_exists\?\Z/.match method
121
+ exists? $1
122
+
123
+ # Delete a key
124
+ elsif /\Adelete_(.*)\Z/.match method
125
+ delete $1 if exists? $1
126
+
127
+ # Writes a key value
128
+ elsif (method[-1] == '=') && @allow_modifications
129
+ key = method[0..-2].to_sym
130
+ set key, value
131
+
132
+ # Reads a key value
133
+ elsif (args.count == 0)
134
+ get method
135
+
136
+ # Unknown method
137
+ else
138
+ super
139
+ end
140
+ end
141
+
142
+ def read_only
143
+ @allow_modifications = false
144
+ @data.each do |key, value|
145
+ if value.kind_of? ZenConfig
146
+ value.read_only
147
+ end
148
+ end
149
+ end
150
+
151
+ def read_only?
152
+ !@allow_modifications
153
+ end
154
+
155
+ def to_hash
156
+ hash = {}
157
+ @data.each do |key, value|
158
+ if value.kind_of? ZenConfig
159
+ hash[key] = value.to_hash
160
+ else
161
+ hash[key] = value
162
+ end
163
+ end
164
+
165
+ return hash
166
+ end
167
+
168
+ # Parent
169
+
170
+ def parent
171
+ return @parent
172
+ end
173
+
174
+ def set_key_parent key
175
+ if @data[key].kind_of? ZenConfig
176
+ @data[key].set_parent self
177
+ end
178
+ end
179
+
180
+ def set_parent parent
181
+ if parent.kind_of? ZenConfig
182
+ @parent = parent
183
+ else
184
+ raise "Parent must be a ZenConfig"
185
+ end
186
+ end
187
+
188
+ private
189
+
190
+ def update_count
191
+ @count = @data.count
192
+ end
193
+ end
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+
3
+ require 'zen_config'
4
+
5
+ RSpec.configure do |config|
6
+
7
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe ZenConfig do
4
+
5
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/zen_config/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Gauthier Delacroix"]
6
+ gem.email = ["gauthier.delacroix@gmail.com"]
7
+ gem.description = "Zend_Config translated into Ruby"
8
+ gem.summary = "Brings Ruby config objects as with Zend Framework's Zend_Config"
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "zen_config"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = ZenConfig::VERSION
17
+
18
+ gem.add_development_dependency "rspec"
19
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zen_config
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gauthier Delacroix
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: Zend_Config translated into Ruby
31
+ email:
32
+ - gauthier.delacroix@gmail.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .gitignore
38
+ - Gemfile
39
+ - LICENSE
40
+ - README.md
41
+ - Rakefile
42
+ - lib/zen_config.rb
43
+ - lib/zen_config/version.rb
44
+ - spec/spec_helper.rb
45
+ - spec/zen_config_spec.rb
46
+ - zen_config.gemspec
47
+ homepage: ''
48
+ licenses: []
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubyforge_project:
67
+ rubygems_version: 1.8.21
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: Brings Ruby config objects as with Zend Framework's Zend_Config
71
+ test_files:
72
+ - spec/spec_helper.rb
73
+ - spec/zen_config_spec.rb