configatron 2.9.1 → 2.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +21 -0
- data/.rvmrc +2 -0
- data/.travis.yml +8 -0
- data/Gemfile +7 -0
- data/{README.textile → README.md} +59 -61
- data/Rakefile +7 -0
- data/configatron.gemspec +49 -0
- data/lib/configatron/store.rb +11 -3
- data/lib/configatron/version.rb +1 -1
- data/spec/configatron/proc_spec.rb +67 -0
- data/spec/configatron/rails_spec.rb +66 -0
- data/spec/lib/class_spec.rb +45 -0
- data/spec/lib/complex.yml +13 -0
- data/spec/lib/configatron_spec.rb +613 -0
- data/spec/lib/futurama.yml +6 -0
- data/spec/lib/lost.yml +14 -0
- data/spec/lib/math.yml +2 -0
- data/spec/lib/merge.yml +14 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/support/rails.rb +7 -0
- metadata +51 -17
data/.gitignore
ADDED
data/.rvmrc
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -1,112 +1,110 @@
|
|
1
|
-
|
1
|
+
# Configatron [![Build Status](https://travis-ci.org/markbates/configatron.png?branch=master)](https://travis-ci.org/markbates/configatron)
|
2
2
|
|
3
3
|
Configatron makes configuring your applications and scripts incredibly easy. No longer is a there a need to use constants or global variables. Now you can use a simple and painless system to configure your life. And, because it's all Ruby, you can do any crazy thing you would like to!
|
4
4
|
|
5
|
-
|
5
|
+
## Installation
|
6
6
|
|
7
7
|
Installation of Configatron is easy, as it is just a RubyGem:
|
8
8
|
|
9
|
-
|
9
|
+
```ruby
|
10
10
|
$ sudo gem install configatron
|
11
|
-
|
11
|
+
```
|
12
12
|
|
13
13
|
If you'd like to live on the bleedin' edge you can install the development version from GitHub:
|
14
14
|
|
15
|
-
|
15
|
+
```
|
16
16
|
$ sudo gem install markbates-configatron --source=http://gems.github.com
|
17
|
-
|
17
|
+
```
|
18
18
|
|
19
19
|
Once installed you just need to require it:
|
20
20
|
|
21
|
-
|
21
|
+
```ruby
|
22
22
|
require 'configatron'
|
23
|
-
|
23
|
+
```
|
24
24
|
|
25
|
-
|
25
|
+
## Examples
|
26
26
|
|
27
|
-
|
27
|
+
### Simple
|
28
28
|
|
29
|
-
|
29
|
+
```ruby
|
30
30
|
configatron.email = 'me@example.com'
|
31
31
|
configatron.database_url = "postgres://localhost/mack_framework_rocks"
|
32
|
-
|
32
|
+
```
|
33
33
|
|
34
34
|
Now, anywhere in your code you can do the following:
|
35
35
|
|
36
|
-
|
36
|
+
```ruby
|
37
37
|
configatron.email # => "me@example.com"
|
38
38
|
configatron.database_url # => "postgres://localhost/mack_framework_rocks"
|
39
|
-
|
39
|
+
```
|
40
40
|
|
41
41
|
Viola! Simple as can be.
|
42
42
|
|
43
43
|
Now you're saying, what if I want to have a 'default' set of options, but then override them later, based on other information? Simple again. Let's use our above example. We've configured our @database_url@ option to be @postgres://localhost/mack_framework_rocks@. The problem with that is that is our production database url, not our development url. Fair enough, all you have to do is redeclare it:
|
44
44
|
|
45
|
-
|
45
|
+
```ruby
|
46
46
|
configatron.database_url = "postgres://localhost/mack_framework_rocks_development"
|
47
|
-
|
47
|
+
```
|
48
48
|
|
49
49
|
becomes:
|
50
50
|
|
51
|
-
|
51
|
+
```ruby
|
52
52
|
configatron.email # => "me@example.com"
|
53
53
|
configatron.database_url # => "postgres://localhost/mack_framework_rocks_development"
|
54
|
-
|
54
|
+
```
|
55
55
|
|
56
56
|
Notice how our other configuration parameters haven't changed? Cool, eh?
|
57
57
|
|
58
|
-
|
58
|
+
### Hash/YAML
|
59
59
|
|
60
60
|
You can configure configatron from a hash as well (this is really only useful in testing or for data driven configurat, it's not recommended for actual configuration):
|
61
61
|
|
62
|
-
|
63
|
-
configatron.configure_from_hash({:email => {:pop => {:address => 'pop.example.com', :port => 110}}, :smtp => {:address => 'smtp.example.com'}})
|
64
|
-
|
62
|
+
```ruby
|
63
|
+
configatron.configure_from_hash({:email => {:pop => {:address => 'pop.example.com', :port => 110}}, :smtp => {:address => 'smtp.example.com'}})####
|
65
64
|
configatron.email.pop.address # => 'pop.example.com'
|
66
65
|
configatron.email.pop.port # => 110
|
67
66
|
# and so on...
|
68
|
-
|
67
|
+
```
|
69
68
|
|
70
|
-
|
69
|
+
#### YAML
|
71
70
|
|
72
71
|
Support for YAML has been deprecated and will be removed in version 2.9 of Configatron. Please switch to Ruby based configuration of Configatron. Trust me, it's a lot nicer and easier to use. Why would you _not_ want to?
|
73
72
|
|
74
|
-
|
73
|
+
### Namespaces
|
75
74
|
|
76
75
|
The question that should be on your lips is what I need to have namespaced configuration parameters. It's easy! Configatron allows you to create namespaces.
|
77
76
|
|
78
|
-
|
77
|
+
```ruby
|
79
78
|
configatron.website_url = "http://www.mackframework.com"
|
80
79
|
configatron.email.pop.address = "pop.example.com"
|
81
80
|
configatron.email.pop.port = 110
|
82
81
|
configatron.email.smtp.address = "smtp.example.com"
|
83
82
|
configatron.email.smtp.port = 25
|
84
|
-
|
83
|
+
```
|
85
84
|
|
86
85
|
becomes:
|
87
86
|
|
88
|
-
|
87
|
+
```ruby
|
89
88
|
configatron.email.pop.address # => "pop.example.com"
|
90
89
|
configatron.email.smtp.address # => "smtp.example.com"
|
91
90
|
configatron.website_url # => "http://www.mackframework.com"
|
92
|
-
|
93
|
-
|
94
|
-
Configatron allows you to nest namespaces to your hearts content! Just keep going, it's that easy.
|
91
|
+
```
|
92
|
+
####onfigatron allows you to nest namespaces to your hearts content! Just keep going, it's that easy.
|
95
93
|
|
96
94
|
Of course you can update a single parameter n levels deep as well:
|
97
95
|
|
98
|
-
|
96
|
+
```ruby
|
99
97
|
configatron.email.pop.address = "pop2.example.com"
|
100
98
|
|
101
99
|
configatron.email.pop.address # => "pop2.example.com"
|
102
100
|
configatron.email.smtp.address # => "smtp.example.com"
|
103
|
-
|
101
|
+
```
|
104
102
|
|
105
|
-
|
103
|
+
### Temp Configurations
|
106
104
|
|
107
105
|
Sometimes in testing, or other situations, you want to temporarily change some settings. You can do this with the @temp@ method:
|
108
106
|
|
109
|
-
|
107
|
+
```ruby
|
110
108
|
configatron.one = 1
|
111
109
|
configatron.letters.a = 'A'
|
112
110
|
configatron.letters.b = 'B'
|
@@ -122,16 +120,16 @@ Sometimes in testing, or other situations, you want to temporarily change some s
|
|
122
120
|
configatron.letters.a # => 'A'
|
123
121
|
configatron.letters.b # => 'B'
|
124
122
|
configatron.letters.c # => nil
|
125
|
-
|
123
|
+
```
|
126
124
|
|
127
125
|
You can also pass in an optional Hash to the @temp@:
|
128
126
|
|
129
|
-
|
127
|
+
```ruby
|
130
128
|
configatron.one = 1
|
131
129
|
configatron.letters.a = 'A'
|
132
130
|
configatron.letters.b = 'B'
|
133
131
|
configatron.temp(:letters => {:b => 'bb', :c => 'c'}) do
|
134
|
-
|
132
|
+
####one == 1
|
135
133
|
configatron.letters.a # => 'A'
|
136
134
|
configatron.letters.b # => 'bb'
|
137
135
|
configatron.letters.c # => 'c'
|
@@ -140,13 +138,13 @@ You can also pass in an optional Hash to the @temp@:
|
|
140
138
|
configatron.letters.a # => 'A'
|
141
139
|
configatron.letters.b # => 'B'
|
142
140
|
configatron.letters.c # => nil
|
143
|
-
|
141
|
+
```
|
144
142
|
|
145
|
-
|
143
|
+
### Delayed and Dynamic Configurations
|
146
144
|
|
147
145
|
There are times when you want to refer to one configuration setting in another configuration setting. Let's look at a fairly contrived example:
|
148
146
|
|
149
|
-
|
147
|
+
```ruby
|
150
148
|
configatron.memcached.servers = ['127.0.0.1:11211']
|
151
149
|
configatron.page_caching.servers = configatron.memcached.servers
|
152
150
|
configatron.object_caching.servers = configatron.memcached.servers
|
@@ -160,15 +158,15 @@ There are times when you want to refer to one configuration setting in another c
|
|
160
158
|
configatron.page_caching.servers = configatron.memcached.servers
|
161
159
|
configatron.object_caching.servers = configatron.memcached.servers
|
162
160
|
end
|
163
|
-
|
161
|
+
```
|
164
162
|
|
165
|
-
Now, we could've written that slightly differently, but it helps to illustrate the point. With Configatron you can create
|
163
|
+
Now, we could've written that slightly differently, but it helps to illustrate the point. With Configatron you can create `Delayed` and `Dynamic` settings.
|
166
164
|
|
167
|
-
|
165
|
+
#### Delayed
|
168
166
|
|
169
|
-
With
|
167
|
+
With `Delayed` settings execution of the setting doesn't happen until the first time it is executed.
|
170
168
|
|
171
|
-
|
169
|
+
```ruby
|
172
170
|
configatron.memcached.servers = ['127.0.0.1:11211']
|
173
171
|
configatron.page_caching.servers = Configatron::Delayed.new {configatron.memcached.servers}
|
174
172
|
configatron.object_caching.servers = Configatron::Delayed.new {configatron.memcached.servers}
|
@@ -178,49 +176,49 @@ With <code>Delayed</code> settings execution of the setting doesn't happen until
|
|
178
176
|
elsif Rails.env == 'staging'
|
179
177
|
configatron.memcached.servers = ['192.168.0.2:11211']
|
180
178
|
end
|
181
|
-
|
179
|
+
```
|
182
180
|
|
183
|
-
Execution occurs once and after that the result of that execution is returned. So in our case the first time someone calls the setting
|
181
|
+
Execution occurs once and after that the result of that execution is returned. So in our case the first time someone calls the setting `configatron.page_caching.servers` it will find the `configatron.memcached.servers` setting and return that. After that point if the `configatron.memcached.servers` setting is changed, the original settings are returned by `configatron.page_caching.servers`.
|
184
182
|
|
185
|
-
|
183
|
+
#### Dynamic
|
186
184
|
|
187
|
-
|
185
|
+
`Dynamic` settings are very similar to `Delayed` settings, but with one big difference. Every time you call a `Dynamic` setting is executed. Take this example:
|
188
186
|
|
189
|
-
|
187
|
+
```ruby
|
190
188
|
configatron.current.time = Configatron::Dynamic.new {Time.now}
|
191
|
-
|
189
|
+
```
|
192
190
|
|
193
|
-
Each time you call
|
191
|
+
Each time you call `configatron.current.time` it will return a new value to you. While this seems a bit useless, it is pretty useful if you have ever changing configurations.
|
194
192
|
|
195
|
-
|
193
|
+
### Misc.
|
196
194
|
|
197
195
|
Even if parameters haven't been set, you can still call them, but you'll get a @Configatron::Store@ object back. The Configatron::Store class, however, will respond true to @.nil?@ if there are no parameters configured on it.
|
198
196
|
|
199
|
-
|
197
|
+
```ruby
|
200
198
|
configatron.i.dont.exist.nil? # => true
|
201
199
|
configatron.i.dont.exist # => Configatron::Store
|
202
|
-
|
200
|
+
```
|
203
201
|
|
204
202
|
If you want to get back an actual @nil@ then you can use the @retrieve@ method:
|
205
203
|
|
206
|
-
|
204
|
+
```ruby
|
207
205
|
configatron.i.do.exist = [:some, :array]
|
208
206
|
configatron.i.dont.retrieve(:exist, nil) # => nil
|
209
207
|
configatron.i.do.retrieve(:exist, :foo) # => [:some, :array]
|
210
|
-
|
208
|
+
```
|
211
209
|
|
212
210
|
You can set 'default' values for parameters. If there is already a setting, it won't be replaced. This is useful if you've already done your 'configuration' and you call a library, that needs to have parameters set. The library can set its defaults, without worrying that it might have overridden your custom settings.
|
213
211
|
|
214
|
-
|
212
|
+
```ruby
|
215
213
|
configatron.set_default(:name, 'Mark Bates')
|
216
214
|
configatron.name # => 'Mark Bates'
|
217
215
|
configatron.set_default(:name, 'Me')
|
218
216
|
configatron.name # => 'Mark Bates'
|
219
|
-
|
217
|
+
```
|
220
218
|
|
221
219
|
Enjoy!
|
222
220
|
|
223
|
-
|
221
|
+
## Contributors
|
224
222
|
|
225
223
|
* Mark Bates
|
226
224
|
* Kurtis Rainbolt-Greene
|
data/Rakefile
ADDED
data/configatron.gemspec
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'configatron/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "configatron"
|
8
|
+
gem.version = Configatron::VERSION
|
9
|
+
gem.authors = ["Mark Bates"]
|
10
|
+
gem.email = ["mark@markbates.com"]
|
11
|
+
gem.description = %q{A powerful Ruby configuration system.}
|
12
|
+
gem.summary = %q{A powerful Ruby configuration system.}
|
13
|
+
gem.homepage = "http://www.metabates.com"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency("yamler", ">= 0.1.0")
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
# # -*- encoding: utf-8 -*-
|
26
|
+
# require File.expand_path('../lib/configatron/version', __FILE__)
|
27
|
+
|
28
|
+
# Gem::Specification.new do |s|
|
29
|
+
# s.name = "configatron"
|
30
|
+
# s.version = Configatron::VERSION
|
31
|
+
|
32
|
+
# s.authors = ["markbates"]
|
33
|
+
# s.description = "configatron was developed by: markbates"
|
34
|
+
# s.email = "mark@markbates.com"
|
35
|
+
# s.extra_rdoc_files = ["LICENSE"]
|
36
|
+
|
37
|
+
# ignored_files = File.read('.gitignore').split("\n").compact.reject(&:empty?) + ["Rakefile", "Gemfile", "configatron.gemspec"]
|
38
|
+
# test_files = Dir['spec/**/*'].reject {|f| File.directory?(f)}
|
39
|
+
# library_files = Dir['**/*'].reject{|f| File.directory?(f)}
|
40
|
+
# s.files = library_files - test_files - ignored_files
|
41
|
+
# s.homepage = "http://www.metabates.com"
|
42
|
+
# s.require_paths = ["lib"]
|
43
|
+
# s.summary = "A powerful Ruby configuration system."
|
44
|
+
|
45
|
+
# s.add_runtime_dependency "yamler", ">= 0.1.0"
|
46
|
+
# s.add_development_dependency 'rake'
|
47
|
+
# s.add_development_dependency 'rspec'
|
48
|
+
# s.add_development_dependency 'gemstub'
|
49
|
+
# end
|
data/lib/configatron/store.rb
CHANGED
@@ -299,11 +299,19 @@ class Configatron
|
|
299
299
|
self.methods.include?(RUBY_VERSION > '1.9.0' ? name.to_sym : name.to_s)
|
300
300
|
end
|
301
301
|
|
302
|
+
def is_syck?(obj)
|
303
|
+
if defined?(SYCK_CONSTANT)
|
304
|
+
Configatron.log.warn "DEPRECATED! (SYCK) Syck support has been removed from Configatron in Ruby 2.x. This feature will be removed entirely in Configatron 3.0. Please be advised."
|
305
|
+
return obj.is_a?(SYCK_CONSTANT)
|
306
|
+
end
|
307
|
+
return false
|
308
|
+
end
|
309
|
+
|
302
310
|
def parse_options(options)
|
303
311
|
if options.is_a?(Hash)
|
304
312
|
options.each do |k,v|
|
305
313
|
if v.is_a?(Hash)
|
306
|
-
if v.keys.length == 1 && v.keys.first
|
314
|
+
if v.keys.length == 1 && is_syck?(v.keys.first)
|
307
315
|
self.method_missing("#{k}=", v.values.first.flatten)
|
308
316
|
else
|
309
317
|
self.method_missing(k.to_sym).configure_from_hash(v)
|
@@ -324,8 +332,8 @@ class Configatron
|
|
324
332
|
|
325
333
|
if RUBY_PLATFORM == 'java'
|
326
334
|
SYCK_CONSTANT = YAML::Yecht::MergeKey
|
327
|
-
|
328
|
-
SYCK_CONSTANT =
|
335
|
+
elsif RUBY_VERSION.match(/^1\.9/)
|
336
|
+
SYCK_CONSTANT = Syck::MergeKey
|
329
337
|
end
|
330
338
|
|
331
339
|
end # Store
|
data/lib/configatron/version.rb
CHANGED
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Configatron::Proc do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
configatron.temp_start
|
7
|
+
end
|
8
|
+
|
9
|
+
after(:each) do
|
10
|
+
configatron.temp_end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe Configatron::Dynamic do
|
14
|
+
|
15
|
+
it 'should execute the code at a later date' do
|
16
|
+
configatron.tv.shows = ['seinfeld', 'simpsons']
|
17
|
+
configatron.my.tv.shows = Configatron::Dynamic.new do
|
18
|
+
"My shows are: #{configatron.tv.shows.join(', ')}"
|
19
|
+
end
|
20
|
+
configatron.my.tv.shows.should == 'My shows are: seinfeld, simpsons'
|
21
|
+
configatron.tv.shows = ['seinfeld', 'simpsons', 'entourage']
|
22
|
+
configatron.my.tv.shows.should == 'My shows are: seinfeld, simpsons, entourage'
|
23
|
+
configatron.tv.shows = ['seinfeld', 'simpsons', 'entourage', 'office']
|
24
|
+
configatron.my.tv.shows.should == 'My shows are: seinfeld, simpsons, entourage, office'
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should work with retrieve' do
|
28
|
+
configatron.tv.shows = ['seinfeld', 'simpsons']
|
29
|
+
configatron.my.tv.shows = Configatron::Dynamic.new do
|
30
|
+
"My shows are: #{configatron.tv.shows.join(', ')}"
|
31
|
+
end
|
32
|
+
configatron.my.tv.retrieve(:shows).should == 'My shows are: seinfeld, simpsons'
|
33
|
+
configatron.tv.shows = ['seinfeld', 'simpsons', 'entourage']
|
34
|
+
configatron.my.tv.retrieve(:shows).should == 'My shows are: seinfeld, simpsons, entourage'
|
35
|
+
configatron.tv.shows = ['seinfeld', 'simpsons', 'entourage', 'office']
|
36
|
+
configatron.my.tv.retrieve(:shows).should == 'My shows are: seinfeld, simpsons, entourage, office'
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
describe Configatron::Delayed do
|
42
|
+
|
43
|
+
it 'should execute the code once at a later date' do
|
44
|
+
configatron.tv.shows = ['seinfeld', 'simpsons']
|
45
|
+
configatron.my.tv.shows = Configatron::Delayed.new do
|
46
|
+
"My shows are: #{configatron.tv.shows.join(', ')}"
|
47
|
+
end
|
48
|
+
configatron.tv.shows = ['seinfeld', 'simpsons', 'entourage']
|
49
|
+
configatron.my.tv.shows.should == 'My shows are: seinfeld, simpsons, entourage'
|
50
|
+
configatron.tv.shows = ['seinfeld', 'simpsons', 'entourage', 'office']
|
51
|
+
configatron.my.tv.shows.should == 'My shows are: seinfeld, simpsons, entourage'
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should work with retrieve' do
|
55
|
+
configatron.tv.shows = ['seinfeld', 'simpsons']
|
56
|
+
configatron.my.tv.shows = Configatron::Delayed.new do
|
57
|
+
"My shows are: #{configatron.tv.shows.join(', ')}"
|
58
|
+
end
|
59
|
+
configatron.tv.shows = ['seinfeld', 'simpsons', 'entourage']
|
60
|
+
configatron.my.tv.retrieve(:shows).should == 'My shows are: seinfeld, simpsons, entourage'
|
61
|
+
configatron.tv.shows = ['seinfeld', 'simpsons', 'entourage', 'office']
|
62
|
+
configatron.my.tv.retrieve(:shows).should == 'My shows are: seinfeld, simpsons, entourage'
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|