configatron 3.2.0 → 4.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +2 -2
- data/History.txt +72 -0
- data/README.md +25 -24
- data/Rakefile +10 -4
- data/configatron.gemspec +1 -0
- data/lib/configatron.rb +22 -4
- data/lib/configatron/core.rb +6 -6
- data/lib/configatron/ext/kernel.rb +5 -0
- data/lib/configatron/integrations.rb +4 -0
- data/lib/configatron/integrations/minitest.rb +29 -0
- data/lib/configatron/{rails.rb → integrations/rails.rb} +1 -1
- data/lib/configatron/root_store.rb +121 -0
- data/lib/configatron/store.rb +104 -67
- data/lib/configatron/version.rb +1 -1
- data/lib/generators/configatron/install/templates/configatron/defaults.rb +2 -2
- data/lib/generators/configatron/install/templates/configatron/development.rb +2 -2
- data/lib/generators/configatron/install/templates/configatron/production.rb +2 -2
- data/lib/generators/configatron/install/templates/configatron/test.rb +2 -2
- data/lib/generators/configatron/install/templates/initializers/configatron.rb +1 -1
- data/test/_lib.rb +17 -0
- data/test/functional/_lib.rb +10 -0
- data/test/functional/_lib/scripts/core.rb +11 -0
- data/test/functional/configatron.rb +165 -0
- data/test/functional/delayed.rb +18 -0
- data/test/functional/loading.rb +10 -0
- data/test/functional/minitest.rb +18 -0
- data/test/unit/_lib.rb +10 -0
- data/test/unit/configatron/proc.rb +24 -0
- data/test/unit/configatron/root_store.rb +37 -0
- data/test/unit/configatron/store.rb +149 -0
- metadata +55 -28
- data/.ruby-version +0 -1
- data/lib/configatron/deep_clone.rb +0 -69
- data/lib/configatron/kernel.rb +0 -21
- data/test/configatron/kernel_test.rb +0 -24
- data/test/configatron/proc_test.rb +0 -27
- data/test/configatron/store_test.rb +0 -256
- data/test/configatron_test.rb +0 -5
- data/test/test_helper.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 132989ab43482032a4a574c7c165e382bd361fb8
|
4
|
+
data.tar.gz: e6774fccb00c33995c109f8ce62e05caa87bebd8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f94da811e4b3add13ef0ae54ade8c6202568eeee89d0b1f803980b1ca1f25d968e99793c515de95566715a7a611a16ca0f2a19c1107f1bf650fd2b650b3381a
|
7
|
+
data.tar.gz: f90d0c18873c458a933e26d58f30eda5e712a7e2f6e34bc752dace68604f4eab75062fd3ac9eb7052afe7bcedc6d1c76ca8f99a9af47a29aade4abcc6114c9b9
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/History.txt
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
=== 4.5.0
|
2
|
+
|
3
|
+
* [backwards-incompatible] Switch from DeepClone to copy-on-write for temp. As part of the implementation, *values* are no longer cloned.
|
4
|
+
|
5
|
+
=== 4.4.1
|
6
|
+
|
7
|
+
* Make lock!/unlock! support blocks
|
8
|
+
|
9
|
+
=== 4.4.0
|
10
|
+
|
11
|
+
* [backwards-incompatible] Make temp preserve locking state across invocations
|
12
|
+
|
13
|
+
=== 4.3.0
|
14
|
+
|
15
|
+
* [backwards-incompatible] Make nil into a valid config value
|
16
|
+
* [backwards-incompatible] Make temp clean up after itself when an exception is thrown
|
17
|
+
|
18
|
+
=== 4.2.1
|
19
|
+
|
20
|
+
* Fix a bug with deep cloning which caused temping to break for nested settings
|
21
|
+
|
22
|
+
=== 4.2.0
|
23
|
+
|
24
|
+
* [backwards-incompatible] Make to_h/to_hash recursively hashify Configatron::Stores, and resolve Configatron::Procs.
|
25
|
+
|
26
|
+
=== 4.1.1
|
27
|
+
|
28
|
+
* Fix delayed attributes
|
29
|
+
|
30
|
+
=== 4.1.0
|
31
|
+
|
32
|
+
* Fix bugs from BasicObject fallout
|
33
|
+
* Have KernelStore proxy calls using `public_send` for consistent shadowing
|
34
|
+
|
35
|
+
=== 4.0.3
|
36
|
+
|
37
|
+
* Switch Store and RootStore to descend from BasicObject
|
38
|
+
|
39
|
+
=== 4.0.2
|
40
|
+
|
41
|
+
* Add missing require of Rails integration
|
42
|
+
|
43
|
+
=== 4.0.1
|
44
|
+
|
45
|
+
* Fix #inspect and #to_s methods on KernelStore to pass through to Store
|
46
|
+
|
47
|
+
=== 4.0.0
|
48
|
+
|
49
|
+
This is largely a restructuring of existing functionality, making it
|
50
|
+
simpler and more consistent. The tests have also been fully
|
51
|
+
refactored.
|
52
|
+
|
53
|
+
Added the following:
|
54
|
+
|
55
|
+
* A Minitest integration at Configatron::Integrations::Minitest
|
56
|
+
* Key errors while locked return the name of the relevant configatron
|
57
|
+
* Configatron::RootStore is now the intended way to start a new configatron hiearchy. (You should likely not initialize a Configatron::Store yourself.)
|
58
|
+
|
59
|
+
Deprecated the following:
|
60
|
+
|
61
|
+
* Initializing a Configatron::Store with a custom hash
|
62
|
+
* Calling .nil?/.empty? on a Configatron::Store
|
63
|
+
* Calling locking, temp, or reset methods directly on a Configatron::Store (moved instead to Configatron::RootStore)
|
64
|
+
* A DeepClone module is no longer defined at the top-level
|
65
|
+
* Removed Configatron::KernelStore
|
66
|
+
|
67
|
+
Other backwards-incompatible changes:
|
68
|
+
|
69
|
+
* Renamespaced Configatron::Rails under Configatron::Integrations::Rails.
|
70
|
+
* Moved locking and temp methods to exist just on Configatron::RootStore.
|
71
|
+
* Configatron::Store.inspect no longer takes a name
|
72
|
+
* key? will now return true for sub-Configatron::Stores
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
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!
|
5
5
|
|
6
|
-
One of the more important changes to V3 is that it now resembles more a `Hash` style interface. You can use `[]`, `fetch`, `each`, etc...
|
6
|
+
One of the more important changes to V3 is that it now resembles more a `Hash` style interface. You can use `[]`, `fetch`, `each`, etc... Actually the hash notation is a bit more robust since the dot notation won't work for a few property names (a few public methods from `Configatron::Store` itself).
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
@@ -66,7 +66,7 @@ Notice how our other configuration parameters haven't changed? Cool, eh?
|
|
66
66
|
|
67
67
|
### Hash/YAML
|
68
68
|
|
69
|
-
You can configure Configatron from a hash as well (this is
|
69
|
+
You can configure Configatron from a hash as well (this is particularly useful if you'd like to have configuration files):
|
70
70
|
|
71
71
|
```ruby
|
72
72
|
configatron.configure_from_hash(email: {pop: {address: 'pop.example.com', port: 110}}, smtp: {address: 'smtp.example.com'})
|
@@ -76,9 +76,11 @@ configatron.email.pop.port # => 110
|
|
76
76
|
# and so on...
|
77
77
|
```
|
78
78
|
|
79
|
-
|
79
|
+
### Method vs hash access
|
80
80
|
|
81
|
-
|
81
|
+
As a note, method (`configatron.foo`) access will be shadowed by public methods defined on the configatron object. (The configatron object descends from [`BasicObject`](http://apidock.com/ruby/BasicObject) and adds a few methods to resemble the `Hash` API and to play nice with `puts`, so it should have a pretty bare set of methods.)
|
82
|
+
|
83
|
+
If you need to use keys that are themselves method names, you can just use hash access (`configatron['foo']`).
|
82
84
|
|
83
85
|
### Namespaces
|
84
86
|
|
@@ -119,7 +121,7 @@ end
|
|
119
121
|
|
120
122
|
### Temp Configurations
|
121
123
|
|
122
|
-
Sometimes in testing, or other situations, you want to temporarily change some settings. You can do this with the `temp` method:
|
124
|
+
Sometimes in testing, or other situations, you want to temporarily change some settings. You can do this with the `temp` method (only available on the top-level configatron `RootStore`):
|
123
125
|
|
124
126
|
```ruby
|
125
127
|
configatron.one = 1
|
@@ -189,17 +191,17 @@ configatron.current.time = Configatron::Dynamic.new {Time.now}
|
|
189
191
|
|
190
192
|
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.
|
191
193
|
|
192
|
-
###
|
194
|
+
### Reseting Configurations
|
193
195
|
|
194
|
-
|
196
|
+
In some testing scenarios, it can be helpful to restore Configatron to its default state. This can be done with:
|
195
197
|
|
196
198
|
```ruby
|
197
|
-
configatron.
|
198
|
-
|
199
|
-
|
200
|
-
|
199
|
+
configatron.reset!
|
200
|
+
```
|
201
|
+
|
202
|
+
### Checking keys
|
201
203
|
|
202
|
-
You can use `.has_key?` to determine if a key already exists.
|
204
|
+
Even if parameters haven't been set, you can still call them, but you'll get a `Configatron::Store` object back. You can use `.has_key?` to determine if a key already exists.
|
203
205
|
|
204
206
|
```ruby
|
205
207
|
configatron.i.dont.has_key?(:exist) # => false
|
@@ -218,16 +220,14 @@ configatron.a.b.c! # => raise Configratron::UndefinedKeyError
|
|
218
220
|
|
219
221
|
### Kernel
|
220
222
|
|
221
|
-
The `configatron` "helper" method is
|
222
|
-
|
223
|
-
Instead of requiring `configatron` simply require `configatron/core`, but then you'll have to set up your own `Configatron::Store` object.
|
223
|
+
The `configatron` "helper" method is stored in the `Kernel` module. You can opt-out of this global monkey-patching by requiring `configatron/core` rather than `configatron`. You'll have to set up your own `Configatron::RootStore` object.
|
224
224
|
|
225
225
|
Example:
|
226
226
|
|
227
227
|
```ruby
|
228
228
|
require 'configatron/core'
|
229
229
|
|
230
|
-
store = Configatron::
|
230
|
+
store = Configatron::RootStore.new
|
231
231
|
store.foo = 'FOO'
|
232
232
|
|
233
233
|
store.to_h #= {foo: 'FOO'}
|
@@ -289,23 +289,24 @@ configatron.to_h # => {:letters=>{:a=>"A", :b=>"BB", :c=>"C"}}
|
|
289
289
|
## Contributors
|
290
290
|
|
291
291
|
* Mark Bates
|
292
|
+
* Greg Brockman
|
292
293
|
* Kurtis Rainbolt-Greene
|
293
294
|
* Rob Sanheim
|
294
|
-
* Greg Brockman
|
295
295
|
* Jérémy Lecour
|
296
296
|
* Cody Maggard
|
297
297
|
* Jean-Denis Vauguet
|
298
|
-
* Torsten Schönebaum
|
299
|
-
* Simon Menke
|
300
|
-
* Gleb Pomykalov
|
301
298
|
* chatgris
|
299
|
+
* Simon Menke
|
302
300
|
* Mat Brown
|
301
|
+
* Torsten Schönebaum
|
302
|
+
* Gleb Pomykalov
|
303
303
|
* Casper Gripenberg
|
304
|
-
* Dan Pickett
|
305
304
|
* Artiom Diomin
|
306
|
-
* Tim Riley
|
307
305
|
* mattelacchiato
|
308
|
-
*
|
309
|
-
*
|
306
|
+
* Dan Pickett
|
307
|
+
* Tim Riley
|
310
308
|
* Rick Fletcher
|
309
|
+
* Jose Antonio Pio
|
310
|
+
* Brandon Dimcheff
|
311
|
+
* joe miller
|
311
312
|
* Josh Nichols
|
data/Rakefile
CHANGED
@@ -3,7 +3,13 @@ require 'rake/testtask'
|
|
3
3
|
|
4
4
|
Bundler::GemHelper.install_tasks
|
5
5
|
|
6
|
-
Rake::TestTask.new
|
7
|
-
t.libs
|
8
|
-
t.
|
9
|
-
|
6
|
+
Rake::TestTask.new do |t|
|
7
|
+
t.libs = ["lib"]
|
8
|
+
# t.warning = true
|
9
|
+
t.verbose = true
|
10
|
+
t.test_files = FileList['test/**/*.rb'].reject do |file|
|
11
|
+
file.end_with?('_lib.rb') || file.include?('/_lib/')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
task :default => :test
|
data/configatron.gemspec
CHANGED
data/lib/configatron.rb
CHANGED
@@ -1,5 +1,23 @@
|
|
1
|
-
require 'singleton'
|
2
1
|
require 'configatron/version'
|
3
|
-
|
4
|
-
require 'configatron/
|
5
|
-
require 'configatron/
|
2
|
+
|
3
|
+
require 'configatron/errors'
|
4
|
+
require 'configatron/integrations'
|
5
|
+
require 'configatron/root_store'
|
6
|
+
require 'configatron/store'
|
7
|
+
|
8
|
+
# Proc *must* load before dynamic/delayed, or else Configatron::Proc
|
9
|
+
# will refer to the global ::Proc
|
10
|
+
require 'configatron/proc'
|
11
|
+
require 'configatron/delayed'
|
12
|
+
require 'configatron/dynamic'
|
13
|
+
|
14
|
+
class Configatron
|
15
|
+
end
|
16
|
+
|
17
|
+
# NO_EXT gets defined when you require "configatron/core", which
|
18
|
+
# signals that you don't want any extensions. It'd be nice to have a
|
19
|
+
# better internal signaling mechanism (could use environment
|
20
|
+
# variables, but then they become part of the public interface).
|
21
|
+
unless defined?(Configatron::NO_EXT)
|
22
|
+
require 'configatron/ext/kernel'
|
23
|
+
end
|
data/lib/configatron/core.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
class Configatron
|
2
|
+
# Signals that we should not load the extensions.
|
3
|
+
NO_EXT = true
|
4
|
+
end
|
5
|
+
|
6
|
+
require 'configatron'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Include in a minitest to restore the global configatron object to
|
2
|
+
# its global state afterwards. Particularly useful if you'd like to test
|
3
|
+
# your application with various config settings.
|
4
|
+
#
|
5
|
+
# ```ruby
|
6
|
+
# class Test::Suite < Minitest::Unit
|
7
|
+
# include Configatron::Integrations::Minitest
|
8
|
+
#
|
9
|
+
# it 'works' do
|
10
|
+
# configatron.unlock! do
|
11
|
+
# configatron.some.setting = true
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# [...]
|
15
|
+
# end
|
16
|
+
# ```
|
17
|
+
module Configatron::Integrations
|
18
|
+
module Minitest
|
19
|
+
def before_setup
|
20
|
+
configatron.temp_start
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def before_teardown
|
25
|
+
super
|
26
|
+
configatron.temp_end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
# This is the root configatron object, and contains methods which
|
5
|
+
# operate on the entire configatron hierarchy.
|
6
|
+
class Configatron::RootStore < BasicObject
|
7
|
+
include ::Singleton
|
8
|
+
extend ::Forwardable
|
9
|
+
|
10
|
+
attr_reader :store
|
11
|
+
|
12
|
+
# Have one global RootStore instance, but allow people to create
|
13
|
+
# their own parallel ones if they desire.
|
14
|
+
class << self
|
15
|
+
public :new
|
16
|
+
end
|
17
|
+
|
18
|
+
@@cow = 0
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@locked = false
|
22
|
+
@cow = nil
|
23
|
+
reset!
|
24
|
+
end
|
25
|
+
|
26
|
+
def __cow
|
27
|
+
@cow
|
28
|
+
end
|
29
|
+
|
30
|
+
def __cow_path(path)
|
31
|
+
start = @store.__cow_clone
|
32
|
+
|
33
|
+
node = start
|
34
|
+
branch = path.map do |key|
|
35
|
+
node = node[key]
|
36
|
+
node.__cow_clone
|
37
|
+
end
|
38
|
+
nodes = [start] + branch
|
39
|
+
|
40
|
+
# [node1, node2, node3] with
|
41
|
+
# [node2, node3, node4] and
|
42
|
+
# ['key1', 'key2, 'key3']
|
43
|
+
nodes[0...-1].zip(nodes[1..-1], path) do |parent, child, key|
|
44
|
+
# These are all cow_clones, so won't trigger a further cow
|
45
|
+
# modification.
|
46
|
+
parent[key] = child
|
47
|
+
end
|
48
|
+
|
49
|
+
@store = nodes.first
|
50
|
+
nodes.last
|
51
|
+
end
|
52
|
+
|
53
|
+
def method_missing(name, *args, &block)
|
54
|
+
store.__send__(name, *args, &block)
|
55
|
+
end
|
56
|
+
|
57
|
+
def reset!
|
58
|
+
@store = ::Configatron::Store.new(self)
|
59
|
+
end
|
60
|
+
|
61
|
+
def temp(&block)
|
62
|
+
temp_start
|
63
|
+
|
64
|
+
begin
|
65
|
+
yield
|
66
|
+
ensure
|
67
|
+
temp_end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def temp_start
|
72
|
+
@temp_locked = @locked
|
73
|
+
@temp_cow = @cow
|
74
|
+
|
75
|
+
# Just need to have a unique Copy-on-Write generation ID
|
76
|
+
@cow = @@cow += 1
|
77
|
+
@temp = @store
|
78
|
+
end
|
79
|
+
|
80
|
+
def temp_end
|
81
|
+
@locked = @temp_locked
|
82
|
+
@cow = @temp_cow
|
83
|
+
|
84
|
+
@store = @temp
|
85
|
+
end
|
86
|
+
|
87
|
+
def locked?
|
88
|
+
@locked
|
89
|
+
end
|
90
|
+
|
91
|
+
def lock!(&blk)
|
92
|
+
if blk
|
93
|
+
orig = @locked
|
94
|
+
begin
|
95
|
+
@locked = true
|
96
|
+
blk.call
|
97
|
+
ensure
|
98
|
+
@locked = orig
|
99
|
+
end
|
100
|
+
else
|
101
|
+
@locked = true
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def unlock!(&blk)
|
106
|
+
if blk
|
107
|
+
orig = @locked
|
108
|
+
begin
|
109
|
+
@locked = false
|
110
|
+
blk.call
|
111
|
+
ensure
|
112
|
+
@locked = orig
|
113
|
+
end
|
114
|
+
else
|
115
|
+
@locked = false
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def_delegator :@store, :to_s
|
120
|
+
def_delegator :@store, :inspect
|
121
|
+
end
|