runcoderun-configatron 2.2.1.2 → 2.2.2.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.
- data/lib/configatron/blank_slate.rb +61 -0
- data/lib/configatron/configatron.rb +1 -1
- data/lib/configatron/core_ext/class.rb +26 -0
- data/lib/configatron/{kernel.rb → core_ext/kernel.rb} +0 -0
- data/lib/configatron/core_ext/object.rb +9 -0
- data/lib/configatron/core_ext/string.rb +84 -0
- data/lib/configatron/errors.rb +6 -6
- data/lib/configatron/store.rb +6 -6
- data/lib/configatron.rb +6 -2
- data/spec/lib/blank_slate_spec.rb +25 -0
- data/spec/lib/class_spec.rb +28 -0
- data/spec/lib/configatron_spec.rb +17 -4
- data/spec/lib/errors_spec.rb +9 -0
- data/spec/lib/store_spec.rb +10 -0
- metadata +15 -3
@@ -0,0 +1,61 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
|
3
|
+
# All rights reserved.
|
4
|
+
|
5
|
+
# Permission is granted for use, copying, modification, distribution,
|
6
|
+
# and distribution of modified versions of this work as long as the
|
7
|
+
# above copyright notice is included.
|
8
|
+
#++
|
9
|
+
|
10
|
+
# This version of BlankSlate was taken from Builder and modified by Rob Sanheim
|
11
|
+
# to remove hooks into the various built-in callbacks (ie method_added).
|
12
|
+
# Not sure if we need that complexity (yet) in configatron's use case.
|
13
|
+
#
|
14
|
+
######################################################################
|
15
|
+
# BlankSlate provides an abstract base class with no predefined
|
16
|
+
# methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
|
17
|
+
# BlankSlate is useful as a base class when writing classes that
|
18
|
+
# depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
|
19
|
+
#
|
20
|
+
class Configatron
|
21
|
+
class BlankSlate
|
22
|
+
# These methods are used by configatron internals, so we have to whitelist them.
|
23
|
+
# We could probably do some alias magic to get them to be proper __foo style methods
|
24
|
+
#, but this is okay for now.
|
25
|
+
CONFIGATRON_WHITELIST = %w[instance_eval methods instance_variable_get is_a? class]
|
26
|
+
|
27
|
+
class << self
|
28
|
+
|
29
|
+
# Hide the method named +name+ in the BlankSlate class. Don't
|
30
|
+
# hide methods in +CONFIGATRON_WHITELIST+ or any method beginning with "__".
|
31
|
+
def hide(name)
|
32
|
+
if instance_methods.include?(name.to_s) and
|
33
|
+
name !~ /^(__|#{CONFIGATRON_WHITELIST.join("|")})/
|
34
|
+
@hidden_methods ||= {}
|
35
|
+
@hidden_methods[name.to_sym] = instance_method(name)
|
36
|
+
undef_method name
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def find_hidden_method(name)
|
41
|
+
@hidden_methods ||= {}
|
42
|
+
@hidden_methods[name] || superclass.find_hidden_method(name)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Redefine a previously hidden method so that it may be called on a blank
|
46
|
+
# slate object.
|
47
|
+
def reveal(name)
|
48
|
+
bound_method = nil
|
49
|
+
unbound_method = find_hidden_method(name)
|
50
|
+
fail "Don't know how to reveal method '#{name}'" unless unbound_method
|
51
|
+
define_method(name) do |*args|
|
52
|
+
bound_method ||= unbound_method.bind(self)
|
53
|
+
bound_method.call(*args)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
instance_methods.each { |m| hide(m) }
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -12,7 +12,7 @@ class Configatron
|
|
12
12
|
|
13
13
|
# Forwards the method call onto the 'namespaced' Configatron::Store
|
14
14
|
def method_missing(sym, *args)
|
15
|
-
@_store[@_namespace.last].
|
15
|
+
@_store[@_namespace.last].__send__(sym, *args)
|
16
16
|
end
|
17
17
|
|
18
18
|
# Removes ALL configuration parameters
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Class
|
2
|
+
|
3
|
+
# Returns access to configuration parameters named after the class.
|
4
|
+
#
|
5
|
+
# Examples:
|
6
|
+
# configatron.foo.bar = :bar
|
7
|
+
# configatron.a.b.c.d = 'D'
|
8
|
+
#
|
9
|
+
# class Foo
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# module A
|
13
|
+
# module B
|
14
|
+
# class C
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Foo.to_configatron.bar # => :bar
|
20
|
+
# A::B::C.to_configatron.d # => 'D'
|
21
|
+
def to_configatron
|
22
|
+
name_spaces = self.name.split("::").collect{|s| s.methodize}
|
23
|
+
configatron.send_with_chain(name_spaces)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
File without changes
|
@@ -0,0 +1,84 @@
|
|
1
|
+
class String # :nodoc:
|
2
|
+
|
3
|
+
def underscore # :nodoc:
|
4
|
+
self.to_s.gsub(/::/, '/').
|
5
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
6
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
7
|
+
tr("-", "_").
|
8
|
+
downcase
|
9
|
+
end
|
10
|
+
|
11
|
+
def methodize # :nodoc:
|
12
|
+
x = self
|
13
|
+
|
14
|
+
# if we get down to a nil or an empty string raise an exception!
|
15
|
+
raise NameError.new("#{self} cannot be converted to a valid method name!") if x.nil? || x == ''
|
16
|
+
|
17
|
+
# get rid of the big stuff in the front/back
|
18
|
+
x.strip!
|
19
|
+
|
20
|
+
# if we get down to a nil or an empty string raise an exception!
|
21
|
+
raise NameError.new("#{self} cannot be converted to a valid method name!") if x.nil? || x == ''
|
22
|
+
|
23
|
+
x = x.underscore
|
24
|
+
|
25
|
+
# get rid of spaces and make the _
|
26
|
+
x.gsub!(' ', '_')
|
27
|
+
# get rid of everything that isn't 'safe' a-z, 0-9, ?, !, =, _
|
28
|
+
x.gsub!(/([^ a-zA-Z0-9\_\?\!\=]+)/n, '_')
|
29
|
+
|
30
|
+
# if we get down to a nil or an empty string raise an exception!
|
31
|
+
raise NameError.new("#{self} cannot be converted to a valid method name!") if x.nil? || x == ''
|
32
|
+
|
33
|
+
# condense multiple 'safe' non a-z chars to just one.
|
34
|
+
# ie. ___ becomes _ !!!! becomes ! etc...
|
35
|
+
[' ', '_', '?', '!', "="].each do |c|
|
36
|
+
x.squeeze!(c)
|
37
|
+
end
|
38
|
+
|
39
|
+
# if we get down to a nil or an empty string raise an exception!
|
40
|
+
raise NameError.new("#{self} cannot be converted to a valid method name!") if x.nil? || x == ''
|
41
|
+
|
42
|
+
#down case the whole thing
|
43
|
+
x.downcase!
|
44
|
+
|
45
|
+
# get rid of any characters at the beginning that aren't a-z
|
46
|
+
while !x.match(/^[a-z]/)
|
47
|
+
x.slice!(0)
|
48
|
+
|
49
|
+
# if we get down to a nil or an empty string raise an exception!
|
50
|
+
raise NameError.new("#{self} cannot be converted to a valid method name!") if x.nil? || x == ''
|
51
|
+
end
|
52
|
+
|
53
|
+
# let's trim this bad boy down a bit now that we've cleaned it up, somewhat.
|
54
|
+
# we should do this before cleaning up the end character, because it's possible to end up with a
|
55
|
+
# bad char at the end if you trim too late.
|
56
|
+
x = x[0..100] if x.length > 100
|
57
|
+
|
58
|
+
# get rid of any characters at the end that aren't safe
|
59
|
+
while !x.match(/[a-z0-9\?\!\=]$/)
|
60
|
+
x.slice!(x.length - 1)
|
61
|
+
# if we get down to a nil or an empty string raise an exception!
|
62
|
+
raise NameError.new("#{self} cannot be converted to a valid method name!") if x.nil? || x == ''
|
63
|
+
end
|
64
|
+
|
65
|
+
# if we get down to a nil or an empty string raise an exception!
|
66
|
+
raise NameError.new("#{self} cannot be converted to a valid method name!") if x.nil? || x == ''
|
67
|
+
|
68
|
+
# let's get rid of characters that don't belong in the 'middle' of the method.
|
69
|
+
orig_middle = x[1..(x.length - 2)]
|
70
|
+
n_middle = orig_middle.dup
|
71
|
+
|
72
|
+
['?', '!', "="].each do |c|
|
73
|
+
n_middle.gsub!(c, "_")
|
74
|
+
end
|
75
|
+
|
76
|
+
# the previous gsub can leave us with multiple underscores that need cleaning up.
|
77
|
+
n_middle.squeeze!("_")
|
78
|
+
|
79
|
+
x.gsub!(orig_middle, n_middle)
|
80
|
+
x.gsub!("_=", "=")
|
81
|
+
x
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
data/lib/configatron/errors.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
class Configatron
|
2
|
-
class ProtectedParameter <
|
3
|
-
def
|
4
|
-
super("Can not modify protected parameter: '#{
|
2
|
+
class ProtectedParameter < RuntimeError
|
3
|
+
def initialize(_name)
|
4
|
+
super("Can not modify protected parameter: '#{_name}'")
|
5
5
|
end
|
6
6
|
end
|
7
7
|
|
8
|
-
class LockedNamespace <
|
9
|
-
def initialize(
|
10
|
-
super("Cannot add new parameters to locked namespace: #{
|
8
|
+
class LockedNamespace < RuntimeError
|
9
|
+
def initialize(_name)
|
10
|
+
super("Cannot add new parameters to locked namespace: #{_name.inspect}")
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
data/lib/configatron/store.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class Configatron
|
2
|
-
class Store
|
3
|
-
alias_method :
|
2
|
+
class Store < BlankSlate
|
3
|
+
# alias_method :__send!, :__send__
|
4
4
|
|
5
5
|
# Takes an optional Hash of parameters
|
6
6
|
def initialize(options = {}, name = nil, parent = nil)
|
@@ -94,8 +94,8 @@ class Configatron
|
|
94
94
|
def method_missing(sym, *args) # :nodoc:
|
95
95
|
if sym.to_s.match(/(.+)=$/)
|
96
96
|
name = sym.to_s.gsub("=", '').to_sym
|
97
|
-
raise Configatron::ProtectedParameter.new(name) if @_protected.include?(name) || methods_include?(name)
|
98
|
-
raise Configatron::LockedNamespace.new(@_name) if @_locked && !@_store.has_key?(name)
|
97
|
+
raise Configatron::ProtectedParameter.new(name.to_s) if @_protected.include?(name) || methods_include?(name)
|
98
|
+
raise Configatron::LockedNamespace.new(@_name.to_s) if @_locked && !@_store.has_key?(name)
|
99
99
|
@_store[name] = parse_options(*args)
|
100
100
|
elsif @_store.has_key?(sym)
|
101
101
|
return @_store[sym]
|
@@ -120,7 +120,7 @@ class Configatron
|
|
120
120
|
def protect_all!
|
121
121
|
@_protected.clear
|
122
122
|
@_store.keys.each do |k|
|
123
|
-
val = self.
|
123
|
+
val = self.__send__(k)
|
124
124
|
val.protect_all! if val.class == Configatron::Store
|
125
125
|
@_protected << k
|
126
126
|
end
|
@@ -134,7 +134,7 @@ class Configatron
|
|
134
134
|
def unprotect_all!
|
135
135
|
@_protected.clear
|
136
136
|
@_store.keys.each do |k|
|
137
|
-
val = self.
|
137
|
+
val = self.__send__(k)
|
138
138
|
val.unprotect_all! if val.class == Configatron::Store
|
139
139
|
end
|
140
140
|
end
|
data/lib/configatron.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
base = File.join(File.dirname(__FILE__), 'configatron')
|
2
2
|
require 'yaml'
|
3
3
|
require 'erb'
|
4
|
-
require File.join(base, '
|
4
|
+
require File.join(base, 'blank_slate')
|
5
5
|
require File.join(base, 'configatron')
|
6
6
|
require File.join(base, 'store')
|
7
|
-
require File.join(base, 'errors')
|
7
|
+
require File.join(base, 'errors')
|
8
|
+
require File.join(base, 'core_ext', 'kernel')
|
9
|
+
require File.join(base, 'core_ext', 'object')
|
10
|
+
require File.join(base, 'core_ext', 'string')
|
11
|
+
require File.join(base, 'core_ext', 'class')
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe Configatron::BlankSlate do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
configatron.reset!
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should respond to __id__ and __send__ built in methods" do
|
10
|
+
lambda {
|
11
|
+
Configatron::BlankSlate.new.__id__
|
12
|
+
Configatron::BlankSlate.new.__send__
|
13
|
+
}.should_not raise_error(NoMethodError)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should have methods on the CONFIGATRON_WHITELIST" do
|
17
|
+
blank_slate = Configatron::BlankSlate.new
|
18
|
+
Configatron::BlankSlate::CONFIGATRON_WHITELIST.each do |meth|
|
19
|
+
lambda {
|
20
|
+
blank_slate__send__
|
21
|
+
}.should_not raise_error(NoMethodError)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
configatron.foo.bar = :bar
|
4
|
+
configatron.a.b.c.d = 'D'
|
5
|
+
|
6
|
+
class Foo
|
7
|
+
end
|
8
|
+
|
9
|
+
module A
|
10
|
+
module B
|
11
|
+
class C
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe Class do
|
17
|
+
|
18
|
+
describe 'to_configatron' do
|
19
|
+
|
20
|
+
it 'should return a Configatron::Store object based on the name of the class' do
|
21
|
+
Foo.to_configatron.should be_kind_of(Configatron::Store)
|
22
|
+
Foo.to_configatron.bar.should == :bar
|
23
|
+
A::B::C.to_configatron.d.should == 'D'
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -5,17 +5,28 @@ describe "configatron" do
|
|
5
5
|
before(:each) do
|
6
6
|
configatron.reset!
|
7
7
|
end
|
8
|
+
|
9
|
+
describe "can use built in method names on nested stores" do
|
10
|
+
configatron.email.send = "joe@example.com"
|
11
|
+
configatron.email.send.should == "joe@example.com"
|
12
|
+
|
13
|
+
configatron.email.object_id.should == "another"
|
14
|
+
configatron.email.object_id "another"
|
15
|
+
end
|
8
16
|
|
9
17
|
describe 'protect' do
|
10
18
|
|
11
19
|
it 'should protect a parameter and prevent it from being set' do
|
12
20
|
configatron.one = 1
|
13
21
|
configatron.protect(:one)
|
14
|
-
lambda{
|
22
|
+
lambda {
|
23
|
+
configatron.one = 'one'
|
24
|
+
}.should raise_error(Configatron::ProtectedParameter)
|
15
25
|
configatron.one.should == 1
|
16
26
|
end
|
17
27
|
|
18
28
|
it 'should protect basic methods' do
|
29
|
+
pending("Not sure if this really applies any more...there is no reason to _not_ let users set a key called 'object_id' now")
|
19
30
|
lambda{configatron.object_id = 123456}.should raise_error(Configatron::ProtectedParameter)
|
20
31
|
lambda{configatron.foo.object_id = 123456}.should raise_error(Configatron::ProtectedParameter)
|
21
32
|
end
|
@@ -49,9 +60,11 @@ describe "configatron" do
|
|
49
60
|
configatron.letters.a = 'A'
|
50
61
|
configatron.letters.b = 'B'
|
51
62
|
configatron.protect_all!
|
52
|
-
[:a,:b].each do |
|
53
|
-
lambda
|
54
|
-
|
63
|
+
[:a,:b].each do |lowercase_letter|
|
64
|
+
lambda {
|
65
|
+
configatron.configure_from_hash(:letters => { lowercase_letter => lowercase_letter.to_s})
|
66
|
+
}.should raise_error(Configatron::ProtectedParameter)
|
67
|
+
configatron.letters.__send__(lowercase_letter).should == lowercase_letter.to_s.upcase
|
55
68
|
end
|
56
69
|
lambda{configatron.letters.configure_from_hash(:a => 'a')}.should raise_error(Configatron::ProtectedParameter)
|
57
70
|
lambda{configatron.configure_from_hash(:letters => 'letters')}.should raise_error(Configatron::ProtectedParameter)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: runcoderun-configatron
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.1
|
4
|
+
version: 2.2.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- markbates
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-01-
|
12
|
+
date: 2009-01-20 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -22,16 +22,24 @@ extensions: []
|
|
22
22
|
extra_rdoc_files:
|
23
23
|
- README
|
24
24
|
files:
|
25
|
+
- lib/configatron/blank_slate.rb
|
25
26
|
- lib/configatron/configatron.rb
|
27
|
+
- lib/configatron/core_ext/class.rb
|
28
|
+
- lib/configatron/core_ext/kernel.rb
|
29
|
+
- lib/configatron/core_ext/object.rb
|
30
|
+
- lib/configatron/core_ext/string.rb
|
26
31
|
- lib/configatron/errors.rb
|
27
|
-
- lib/configatron/kernel.rb
|
28
32
|
- lib/configatron/store.rb
|
29
33
|
- lib/configatron.rb
|
30
34
|
- README
|
31
35
|
- spec/lib
|
36
|
+
- spec/lib/blank_slate_spec.rb
|
37
|
+
- spec/lib/class_spec.rb
|
32
38
|
- spec/lib/configatron_spec.rb
|
39
|
+
- spec/lib/errors_spec.rb
|
33
40
|
- spec/lib/futurama.yml
|
34
41
|
- spec/lib/lost.yml
|
42
|
+
- spec/lib/store_spec.rb
|
35
43
|
- spec/lib/the_wire.yml
|
36
44
|
- spec/spec.opts
|
37
45
|
- spec/spec_helper.rb
|
@@ -64,9 +72,13 @@ specification_version: 2
|
|
64
72
|
summary: A powerful Ruby configuration system.
|
65
73
|
test_files:
|
66
74
|
- spec/lib
|
75
|
+
- spec/lib/blank_slate_spec.rb
|
76
|
+
- spec/lib/class_spec.rb
|
67
77
|
- spec/lib/configatron_spec.rb
|
78
|
+
- spec/lib/errors_spec.rb
|
68
79
|
- spec/lib/futurama.yml
|
69
80
|
- spec/lib/lost.yml
|
81
|
+
- spec/lib/store_spec.rb
|
70
82
|
- spec/lib/the_wire.yml
|
71
83
|
- spec/spec.opts
|
72
84
|
- spec/spec_helper.rb
|