configatron 2.9.1 → 2.10.0
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 +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 [](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
|