configatron 3.2.0 → 4.5.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.
- 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
|