siliconsalad-settingslogic 2.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +27 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +43 -0
- data/LICENSE +20 -0
- data/README.rdoc +196 -0
- data/Rakefile +26 -0
- data/VERSION.yml +5 -0
- data/init.rb +1 -0
- data/lib/settingslogic.rb +225 -0
- data/rails/init.rb +1 -0
- data/settingslogic.gemspec +67 -0
- data/siliconsalad-settingslogic.gemspec +68 -0
- data/spec/settings.rb +36 -0
- data/spec/settings.yml +27 -0
- data/spec/settings2.yml +5 -0
- data/spec/settings3.yml +1 -0
- data/spec/settings_invalid.yml +2 -0
- data/spec/settingslogic_spec.rb +208 -0
- data/spec/spec_helper.rb +13 -0
- metadata +121 -0
data/CHANGELOG.rdoc
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
== 2.0.2 released 2009-08-22
|
2
|
+
|
3
|
+
* Define methods during method_missing instead of during initialization. Allows for modification on the fly.
|
4
|
+
|
5
|
+
== 2.0.0 released 2009-08-22
|
6
|
+
|
7
|
+
* Less magic, instead of automatically defining a Settings constant, you should define your own constant. See the readme for an example.
|
8
|
+
|
9
|
+
== 1.0.3 released 2009-04-23
|
10
|
+
|
11
|
+
* Fix Settings initialized with a Hash to work with both symbol and string hash keys.
|
12
|
+
|
13
|
+
== 1.0.2 released 2009-04-09
|
14
|
+
|
15
|
+
* Call key? off of the self in the class level name method.
|
16
|
+
|
17
|
+
== 1.0.1 released 2009-04-02
|
18
|
+
|
19
|
+
* Inherit from hash.
|
20
|
+
|
21
|
+
== 1.0.0 released 2008-12-05
|
22
|
+
|
23
|
+
* Only define methods if we have settings.
|
24
|
+
|
25
|
+
== 0.9.0 released 2008-10-30
|
26
|
+
|
27
|
+
* Initial release
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
archive-tar-minitar (0.5.2)
|
5
|
+
columnize (0.3.6)
|
6
|
+
diff-lcs (1.1.3)
|
7
|
+
git (1.2.5)
|
8
|
+
jeweler (1.6.4)
|
9
|
+
bundler (~> 1.0)
|
10
|
+
git (>= 1.2.5)
|
11
|
+
rake
|
12
|
+
linecache19 (0.5.12)
|
13
|
+
ruby_core_source (>= 0.1.4)
|
14
|
+
rake (0.9.2.2)
|
15
|
+
rcov (0.9.11)
|
16
|
+
rspec (2.8.0)
|
17
|
+
rspec-core (~> 2.8.0)
|
18
|
+
rspec-expectations (~> 2.8.0)
|
19
|
+
rspec-mocks (~> 2.8.0)
|
20
|
+
rspec-core (2.8.0)
|
21
|
+
rspec-expectations (2.8.0)
|
22
|
+
diff-lcs (~> 1.1.2)
|
23
|
+
rspec-mocks (2.8.0)
|
24
|
+
ruby-debug-base19 (0.11.25)
|
25
|
+
columnize (>= 0.3.1)
|
26
|
+
linecache19 (>= 0.5.11)
|
27
|
+
ruby_core_source (>= 0.1.4)
|
28
|
+
ruby-debug19 (0.11.6)
|
29
|
+
columnize (>= 0.3.1)
|
30
|
+
linecache19 (>= 0.5.11)
|
31
|
+
ruby-debug-base19 (>= 0.11.19)
|
32
|
+
ruby_core_source (0.1.5)
|
33
|
+
archive-tar-minitar (>= 0.5.2)
|
34
|
+
|
35
|
+
PLATFORMS
|
36
|
+
ruby
|
37
|
+
|
38
|
+
DEPENDENCIES
|
39
|
+
jeweler
|
40
|
+
rake
|
41
|
+
rcov
|
42
|
+
rspec
|
43
|
+
ruby-debug19
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Ben Johnson of Binary Logic (binarylogic.com)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
= Settingslogic
|
2
|
+
|
3
|
+
Settingslogic is a simple configuration / settings solution that uses an ERB enabled YAML file. It has been great for
|
4
|
+
our apps, maybe you will enjoy it too. Settingslogic works with Rails, Sinatra, or any Ruby project.
|
5
|
+
|
6
|
+
So here is my question to you.....is Settingslogic a great settings solution or the greatest?
|
7
|
+
|
8
|
+
== Helpful links
|
9
|
+
|
10
|
+
* <b>Documentation:</b> http://rdoc.info/projects/binarylogic/settingslogic
|
11
|
+
* <b>Repository:</b> http://github.com/binarylogic/settingslogic/tree/master
|
12
|
+
* <b>Issues:</b> http://github.com/binarylogic/settingslogic/issues
|
13
|
+
|
14
|
+
== Installation
|
15
|
+
|
16
|
+
Install from rubyforge/gemcutter:
|
17
|
+
|
18
|
+
sudo gem install siliconsalad-settingslogic
|
19
|
+
|
20
|
+
Or as a Rails plugin:
|
21
|
+
|
22
|
+
script/plugin install git://github.com/binarylogic/settingslogic.git
|
23
|
+
|
24
|
+
Settingslogic does not have any dependencies on Rails. Installing as a gem is recommended.
|
25
|
+
|
26
|
+
== Usage
|
27
|
+
|
28
|
+
=== 1. Define your class
|
29
|
+
|
30
|
+
Instead of defining a Settings constant for you, that task is left to you. Simply create a class in your application
|
31
|
+
that looks like:
|
32
|
+
|
33
|
+
class Settings < Settingslogic
|
34
|
+
source "#{Rails.root}/config/application.yml"
|
35
|
+
namespace Rails.env
|
36
|
+
end
|
37
|
+
|
38
|
+
Name it Settings, name it Config, name it whatever you want. Add as many or as few as you like. A good place to put
|
39
|
+
this file in a rails app is app/models/settings.rb
|
40
|
+
|
41
|
+
I felt adding a settings file in your app was more straightforward, less tricky, and more flexible.
|
42
|
+
|
43
|
+
If multiple files are passed on the source line, comma-separated, they will be loaded in order, with settings in later files overriding any existing keys. This allows you to, for instance, maintain a global settings file in source control, while allowing each developer to override individual settings as needed. Files that are specified but which do not exist will simply be ignored. Thus you can safely do the following without requiring the presence of application_local.yml:
|
44
|
+
|
45
|
+
class Settings < Settingslogic
|
46
|
+
source "#{Rails.root}/config/application.yml", "#{Rails.root}/config/application_local.yml"
|
47
|
+
namespace Rails.env
|
48
|
+
end
|
49
|
+
|
50
|
+
=== 2. Create your settings
|
51
|
+
|
52
|
+
Notice above we specified an absolute path to our settings file called "application.yml". This is just a typical YAML file.
|
53
|
+
Also notice above that we specified a namespace for our environment. A namespace is just an optional string that corresponds
|
54
|
+
to a key in the YAML file.
|
55
|
+
|
56
|
+
Using a namespace allows us to change our configuration depending on our environment:
|
57
|
+
|
58
|
+
# config/application.yml
|
59
|
+
defaults: &defaults
|
60
|
+
cool:
|
61
|
+
saweet: nested settings
|
62
|
+
neat_setting: 24
|
63
|
+
awesome_setting: <%= "Did you know 5 + 5 = #{5 + 5}?" %>
|
64
|
+
|
65
|
+
development:
|
66
|
+
<<: *defaults
|
67
|
+
neat_setting: 800
|
68
|
+
|
69
|
+
test:
|
70
|
+
<<: *defaults
|
71
|
+
|
72
|
+
production:
|
73
|
+
<<: *defaults
|
74
|
+
|
75
|
+
_Note_: Certain Ruby/Bundler versions include a version of the Psych YAML parser which incorrectly handles merges (the `<<` in the example above.)
|
76
|
+
If your default settings seem to be overwriting your environment-specific settings, including the following lines in your config/boot.rb file may solve the problem:
|
77
|
+
|
78
|
+
require 'yaml'
|
79
|
+
YAML::ENGINE.yamler= 'syck'
|
80
|
+
|
81
|
+
=== 3. Access your settings
|
82
|
+
|
83
|
+
>> Rails.env
|
84
|
+
=> "development"
|
85
|
+
|
86
|
+
>> Settings.cool
|
87
|
+
=> "#<Settingslogic::Settings ... >"
|
88
|
+
|
89
|
+
>> Settings.cool.saweet
|
90
|
+
=> "nested settings"
|
91
|
+
|
92
|
+
>> Settings.neat_setting
|
93
|
+
=> 800
|
94
|
+
|
95
|
+
>> Settings.awesome_setting
|
96
|
+
=> "Did you know 5 + 5 = 10?"
|
97
|
+
|
98
|
+
You can use these settings anywhere, for example in a model:
|
99
|
+
|
100
|
+
class Post < ActiveRecord::Base
|
101
|
+
self.per_page = Settings.pagination.posts_per_page
|
102
|
+
end
|
103
|
+
|
104
|
+
=== 4. Optional / dynamic settings
|
105
|
+
|
106
|
+
Often, you will want to handle defaults in your application logic itself, to reduce the number of settings
|
107
|
+
you need to put in your YAML file. You can access an optional setting by using Hash notation:
|
108
|
+
|
109
|
+
>> Settings.messaging.queue_name
|
110
|
+
=> Exception: Missing setting 'queue_name' in 'message' section in 'application.yml'
|
111
|
+
|
112
|
+
>> Settings.messaging['queue_name']
|
113
|
+
=> nil
|
114
|
+
|
115
|
+
>> Settings.messaging['queue_name'] ||= 'user_mail'
|
116
|
+
=> "user_mail"
|
117
|
+
|
118
|
+
>> Settings.messaging.queue_name
|
119
|
+
=> "user_mail"
|
120
|
+
|
121
|
+
Modifying our model example:
|
122
|
+
|
123
|
+
class Post < ActiveRecord::Base
|
124
|
+
self.per_page = Settings.posts['per_page'] || Settings.pagination.per_page
|
125
|
+
end
|
126
|
+
|
127
|
+
This would allow you to specify a custom value for per_page just for posts, or
|
128
|
+
to fall back to your default value if not specified.
|
129
|
+
|
130
|
+
=== 5. Suppressing Exceptions Conditionally
|
131
|
+
|
132
|
+
Raising exceptions for missing settings helps highlight configuration problems. However, in a
|
133
|
+
Rails app it may make sense to suppress this in production and return nil for missing settings.
|
134
|
+
While it's useful to stop and highlight an error in development or test environments, this is
|
135
|
+
often not the right answer for production.
|
136
|
+
|
137
|
+
class Settings < Settingslogic
|
138
|
+
source "#{Rails.root}/config/application.yml"
|
139
|
+
namespace Rails.env
|
140
|
+
suppress_errors Rails.env.production?
|
141
|
+
end
|
142
|
+
|
143
|
+
>> Settings.non_existent_key
|
144
|
+
=> nil
|
145
|
+
|
146
|
+
== Note on Sinatra / Capistrano / Vlad
|
147
|
+
|
148
|
+
Each of these frameworks uses a +set+ convention for settings, which actually defines methods
|
149
|
+
in the global Object namespace:
|
150
|
+
|
151
|
+
set :application, "myapp" # does "def application" globally
|
152
|
+
|
153
|
+
This can cause collisions with Settingslogic, since those methods are global. Luckily, the
|
154
|
+
solution is to just add a call to load! in your class:
|
155
|
+
|
156
|
+
class Settings < Settingslogic
|
157
|
+
source "#{Rails.root}/config/application.yml"
|
158
|
+
namespace Rails.env
|
159
|
+
load!
|
160
|
+
end
|
161
|
+
|
162
|
+
It's probably always safest to add load! to your class, since this guarantees settings will be
|
163
|
+
loaded at that time, rather than lazily later via method_missing.
|
164
|
+
|
165
|
+
Finally, you can reload all your settings later as well:
|
166
|
+
|
167
|
+
Settings.reload!
|
168
|
+
|
169
|
+
This is useful if you want to support changing your settings YAML without restarting your app.
|
170
|
+
|
171
|
+
== [new] Array of source files
|
172
|
+
|
173
|
+
This change allows you to set multiple source files. The main purpose behind adding it was to avoid the huge size of
|
174
|
+
application.yml. Now you can simply have 'defaults.yml', 'production.yml', 'development.yml' and so on. In your class
|
175
|
+
you can have something like:
|
176
|
+
|
177
|
+
class Settings < Settingslogic
|
178
|
+
source ["#{Rails.root}/config/settings/defaults.yml", "#{Rails.root}/config/settings/#{Rails.env}.yml"]
|
179
|
+
end
|
180
|
+
|
181
|
+
Sources are merged in the same order as they are positioned in the array; later settings overwrite earlier ones.
|
182
|
+
Deep merge is used, so settings will be merged on all levels.
|
183
|
+
|
184
|
+
== [new] Adding settings in the runtime
|
185
|
+
|
186
|
+
It is possible to add additional settings (hash, path_to_file or array_of_paths) by using Settings.load_source(hash_or_file_or_array, section, options).
|
187
|
+
This can be useful for example in case of a lib that needs settings. Lib can be loaded with its own settings which
|
188
|
+
can be later extended by part of application ones. It is possible to pass additional options:
|
189
|
+
- {:replace => true} to replace existing settings with the new ones
|
190
|
+
- {:deep_delete_nil => true} to deeply delete nil settings, ex. {:a=>{:b=>nil}}.deep_delete_nil => {}
|
191
|
+
|
192
|
+
|
193
|
+
== Author
|
194
|
+
|
195
|
+
Copyright (c) 2008-2010 {Ben Johnson}[http://github.com/binarylogic] of {Binary Logic}[http://www.binarylogic.com],
|
196
|
+
released under the MIT license. Support for optional settings and reloading by {Nate Wiger}[http://nate.wiger.org].
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "siliconsalad-settingslogic"
|
8
|
+
gem.summary = "A simple and straightforward settings solution that uses an ERB enabled YAML file and a singleton design pattern."
|
9
|
+
gem.email = "bjohnson@binarylogic.com"
|
10
|
+
gem.homepage = "http://github.com/siliconsalad/settingslogic"
|
11
|
+
gem.authors = ["Ben Johnson of Binary Logic"]
|
12
|
+
end
|
13
|
+
Jeweler::GemcutterTasks.new
|
14
|
+
rescue LoadError
|
15
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'rspec/core/rake_task'
|
19
|
+
RSpec::Core::RakeTask.new(:spec)
|
20
|
+
|
21
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
22
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
23
|
+
spec.rcov = true
|
24
|
+
end
|
25
|
+
|
26
|
+
task :default => :spec
|
data/VERSION.yml
ADDED
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/rails/init.rb"
|
@@ -0,0 +1,225 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "erb"
|
3
|
+
require 'open-uri'
|
4
|
+
|
5
|
+
class Hash
|
6
|
+
def deep_merge!(other_hash)
|
7
|
+
other_hash.each_pair do |k,v|
|
8
|
+
tv = self[k]
|
9
|
+
self[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? tv.deep_merge!(v) : v
|
10
|
+
end
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
def deep_delete_nil
|
15
|
+
delete_if{|k, v| v.nil? or v.instance_of?(Hash) && v.deep_delete_nil.empty?}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# A simple settings solution using a YAML file. See README for more information.
|
20
|
+
class Settingslogic < Hash
|
21
|
+
class MissingSetting < StandardError; end
|
22
|
+
class InvalidSettingsFile < StandardError; end
|
23
|
+
|
24
|
+
class << self
|
25
|
+
def name # :nodoc:
|
26
|
+
self.superclass != Hash && instance.key?("name") ? instance.name : super
|
27
|
+
end
|
28
|
+
|
29
|
+
# Enables Settings.get('nested.key.name') for dynamic access
|
30
|
+
def get(key)
|
31
|
+
parts = key.split('.')
|
32
|
+
curs = self
|
33
|
+
while p = parts.shift
|
34
|
+
curs = curs.send(p)
|
35
|
+
end
|
36
|
+
curs
|
37
|
+
end
|
38
|
+
|
39
|
+
def source(value = nil)
|
40
|
+
#puts "source! #{value.inspect}"
|
41
|
+
if value.nil? || value.empty?
|
42
|
+
@source
|
43
|
+
else
|
44
|
+
@source = value
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def namespace(value = nil)
|
49
|
+
if value.nil?
|
50
|
+
@namespace
|
51
|
+
else
|
52
|
+
@namespace = value
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def suppress_errors(value = nil)
|
57
|
+
if value.nil?
|
58
|
+
@suppress_errors
|
59
|
+
else
|
60
|
+
@suppress_errors = value
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def [](key)
|
65
|
+
instance.fetch(key.to_s, nil)
|
66
|
+
end
|
67
|
+
|
68
|
+
def []=(key, val)
|
69
|
+
# Setting[:key][:key2] = 'value' for dynamic settings
|
70
|
+
val = new(val, source) if val.is_a? Hash
|
71
|
+
instance.store(key.to_s, val)
|
72
|
+
instance.create_accessor_for(key, val)
|
73
|
+
end
|
74
|
+
|
75
|
+
def load!
|
76
|
+
instance
|
77
|
+
true
|
78
|
+
end
|
79
|
+
|
80
|
+
def reload!
|
81
|
+
@instance = nil
|
82
|
+
load!
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
def instance
|
87
|
+
return @instance if @instance
|
88
|
+
@instance = new
|
89
|
+
create_accessors!
|
90
|
+
@instance
|
91
|
+
end
|
92
|
+
|
93
|
+
def method_missing(name, *args, &block)
|
94
|
+
instance.send(name, *args, &block)
|
95
|
+
end
|
96
|
+
|
97
|
+
# It would be great to DRY this up somehow, someday, but it's difficult because
|
98
|
+
# of the singleton pattern. Basically this proxies Setting.foo to Setting.instance.foo
|
99
|
+
def create_accessors!
|
100
|
+
instance.each do |key,val|
|
101
|
+
create_accessor_for(key)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def create_accessor_for(key)
|
106
|
+
return unless key.to_s =~ /^\w+$/ # could have "some-setting:" which blows up eval
|
107
|
+
instance_eval "def #{key}; instance.send(:#{key}); end"
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
# Initializes a new settings object. You can initialize an object in any of the following ways:
|
113
|
+
#
|
114
|
+
# Settings.new(:application) # will look for config/application.yml
|
115
|
+
# Settings.new("application.yaml") # will look for application.yaml
|
116
|
+
# Settings.new("/var/configs/application.yml") # will look for /var/configs/application.yml
|
117
|
+
# Settings.new(:config1 => 1, :config2 => 2)
|
118
|
+
# Settings.new(["defaults.yml", "test.yml"]) # will look for defaults.yml and test.yml and merge them
|
119
|
+
#
|
120
|
+
# Basically if you pass a symbol it will look for that file in the configs directory of your rails app, if you are using this in rails.
|
121
|
+
# If you pass a string it should be an absolute path to your settings file.
|
122
|
+
# If you pass an array, it should have strings that are absolute paths to your settings files.
|
123
|
+
# Then you can pass a hash, and it just allows you to access the hash via methods.
|
124
|
+
#
|
125
|
+
# Options
|
126
|
+
# - deep_delete_nil: remove nil values from hash ex. {:a=>{:b=>nil}}.deep_delete_nil => {}
|
127
|
+
# - replace: if true, replace existing value, by new one, otherwise merge
|
128
|
+
def initialize(hash_or_file_or_array = self.class.source, section = nil, options={})
|
129
|
+
load_source(hash_or_file_or_array, section, {:replace => true}.merge(options))
|
130
|
+
end
|
131
|
+
|
132
|
+
def load_source(hash_or_file_or_array, section = nil, options={})
|
133
|
+
hash = case hash_or_file_or_array
|
134
|
+
when nil
|
135
|
+
raise Errno::ENOENT, "No file specified as Settingslogic source"
|
136
|
+
when Hash
|
137
|
+
hash_or_file_or_array
|
138
|
+
when Array
|
139
|
+
merge_settings_from_files(hash_or_file_or_array, options)
|
140
|
+
else
|
141
|
+
merge_settings_from_files([hash_or_file_or_array], options)
|
142
|
+
end
|
143
|
+
hash.deep_delete_nil if options[:deep_delete_nil]
|
144
|
+
options[:replace] ? self.replace(hash) : self.deep_merge!(hash)
|
145
|
+
@section = section || self.class.source # so end of error says "in application.yml"
|
146
|
+
create_accessors!
|
147
|
+
end
|
148
|
+
|
149
|
+
# For each array element - if file exists, parse it to hash
|
150
|
+
# if namespace is present take only specified part
|
151
|
+
def merge_settings_from_files(array, options={})
|
152
|
+
hash = array.inject({}) do |sum, file|
|
153
|
+
if File.exists?(file)
|
154
|
+
begin
|
155
|
+
tmp_hash = YAML.load(ERB.new(open(file).read).result).to_hash
|
156
|
+
if self.class.namespace
|
157
|
+
tmp_hash = tmp_hash[self.class.namespace] || {}
|
158
|
+
end
|
159
|
+
rescue
|
160
|
+
tmp_hash = {}
|
161
|
+
# https://github.com/tenderlove/psych/issues/23 (Psych::SyntaxError doesn't inherit from StandardError)
|
162
|
+
rescue Psych::SyntaxError
|
163
|
+
tmp_hash = {}
|
164
|
+
end
|
165
|
+
sum.deep_merge!(tmp_hash)
|
166
|
+
end
|
167
|
+
sum
|
168
|
+
end
|
169
|
+
raise InvalidSettingsFile, "No correct settings in any of files #{array.inspect}" if hash.empty?
|
170
|
+
hash
|
171
|
+
end
|
172
|
+
|
173
|
+
# Called for dynamically-defined keys, and also the first key deferenced at the top-level, if load! is not used.
|
174
|
+
# Otherwise, create_accessors! (called by new) will have created actual methods for each key.
|
175
|
+
def method_missing(name, *args, &block)
|
176
|
+
key = name.to_s
|
177
|
+
return missing_key("Missing setting '#{key}' in #{@section}") unless has_key? key
|
178
|
+
value = fetch(key)
|
179
|
+
create_accessor_for(key)
|
180
|
+
value.is_a?(Hash) ? self.class.new(value, "'#{key}' section in #{@section}") : value
|
181
|
+
end
|
182
|
+
|
183
|
+
def [](key)
|
184
|
+
fetch(key.to_s, nil)
|
185
|
+
end
|
186
|
+
|
187
|
+
def []=(key,val)
|
188
|
+
# Setting[:key][:key2] = 'value' for dynamic settings
|
189
|
+
val = self.class.new(val, @section) if val.is_a? Hash
|
190
|
+
store(key.to_s, val)
|
191
|
+
create_accessor_for(key, val)
|
192
|
+
end
|
193
|
+
|
194
|
+
# This handles naming collisions with Sinatra/Vlad/Capistrano. Since these use a set()
|
195
|
+
# helper that defines methods in Object, ANY method_missing ANYWHERE picks up the Vlad/Sinatra
|
196
|
+
# settings! So settings.deploy_to title actually calls Object.deploy_to (from set :deploy_to, "host"),
|
197
|
+
# rather than the app_yml['deploy_to'] hash. Jeezus.
|
198
|
+
def create_accessors!
|
199
|
+
self.each do |key,val|
|
200
|
+
create_accessor_for(key)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# Use instance_eval/class_eval because they're actually more efficient than define_method{}
|
205
|
+
# http://stackoverflow.com/questions/185947/ruby-definemethod-vs-def
|
206
|
+
# http://bmorearty.wordpress.com/2009/01/09/fun-with-rubys-instance_eval-and-class_eval/
|
207
|
+
def create_accessor_for(key, val=nil)
|
208
|
+
return unless key.to_s =~ /^\w+$/ # could have "some-setting:" which blows up eval
|
209
|
+
instance_variable_set("@#{key}", val) if val
|
210
|
+
self.class.class_eval <<-EndEval
|
211
|
+
def #{key}
|
212
|
+
return @#{key} if @#{key}
|
213
|
+
return missing_key("Missing setting '#{key}' in " + @section.to_s) unless has_key? '#{key}'
|
214
|
+
value = fetch('#{key}')
|
215
|
+
@#{key} = value.is_a?(Hash) ? self.class.new(value, "'#{key}' section in "+ @section.to_s) : value
|
216
|
+
end
|
217
|
+
EndEval
|
218
|
+
end
|
219
|
+
|
220
|
+
def missing_key(msg)
|
221
|
+
return nil if self.class.suppress_errors
|
222
|
+
|
223
|
+
raise MissingSetting, msg
|
224
|
+
end
|
225
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "settingslogic"
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "settingslogic"
|
8
|
+
s.version = "2.0.8"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Ben Johnson of Binary Logic"]
|
12
|
+
s.date = "2012-02-27"
|
13
|
+
s.email = "bjohnson@binarylogic.com"
|
14
|
+
s.extra_rdoc_files = [
|
15
|
+
"LICENSE",
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
"CHANGELOG.rdoc",
|
20
|
+
"Gemfile",
|
21
|
+
"Gemfile.lock",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION.yml",
|
26
|
+
"init.rb",
|
27
|
+
"lib/settingslogic.rb",
|
28
|
+
"rails/init.rb",
|
29
|
+
"settingslogic.gemspec",
|
30
|
+
"spec/settings.rb",
|
31
|
+
"spec/settings.yml",
|
32
|
+
"spec/settings2.yml",
|
33
|
+
"spec/settings3.yml",
|
34
|
+
"spec/settings_invalid.yml",
|
35
|
+
"spec/settingslogic_spec.rb",
|
36
|
+
"spec/spec_helper.rb"
|
37
|
+
]
|
38
|
+
s.homepage = "http://github.com/siliconsalad/settingslogic"
|
39
|
+
s.require_paths = ["lib"]
|
40
|
+
s.rubygems_version = "1.8.10"
|
41
|
+
s.summary = "A simple and straightforward settings solution that uses an ERB enabled YAML file and a singleton design pattern."
|
42
|
+
|
43
|
+
if s.respond_to? :specification_version then
|
44
|
+
s.specification_version = 3
|
45
|
+
|
46
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
47
|
+
s.add_development_dependency(%q<rake>, [">= 0"])
|
48
|
+
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
49
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
50
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
51
|
+
s.add_development_dependency(%q<ruby-debug19>, [">= 0"])
|
52
|
+
else
|
53
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
54
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
55
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
56
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
57
|
+
s.add_dependency(%q<ruby-debug19>, [">= 0"])
|
58
|
+
end
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
61
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
62
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
63
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
64
|
+
s.add_dependency(%q<ruby-debug19>, [">= 0"])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "siliconsalad-settingslogic"
|
8
|
+
s.version = "2.0.9"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Ben Johnson of Binary Logic"]
|
12
|
+
s.date = "2012-02-27"
|
13
|
+
s.email = "bjohnson@binarylogic.com"
|
14
|
+
s.extra_rdoc_files = [
|
15
|
+
"LICENSE",
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
"CHANGELOG.rdoc",
|
20
|
+
"Gemfile",
|
21
|
+
"Gemfile.lock",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION.yml",
|
26
|
+
"init.rb",
|
27
|
+
"lib/settingslogic.rb",
|
28
|
+
"rails/init.rb",
|
29
|
+
"settingslogic.gemspec",
|
30
|
+
"siliconsalad-settingslogic.gemspec",
|
31
|
+
"spec/settings.rb",
|
32
|
+
"spec/settings.yml",
|
33
|
+
"spec/settings2.yml",
|
34
|
+
"spec/settings3.yml",
|
35
|
+
"spec/settings_invalid.yml",
|
36
|
+
"spec/settingslogic_spec.rb",
|
37
|
+
"spec/spec_helper.rb"
|
38
|
+
]
|
39
|
+
s.homepage = "http://github.com/siliconsalad/settingslogic"
|
40
|
+
s.require_paths = ["lib"]
|
41
|
+
s.rubygems_version = "1.8.17"
|
42
|
+
s.summary = "A simple and straightforward settings solution that uses an ERB enabled YAML file and a singleton design pattern."
|
43
|
+
|
44
|
+
if s.respond_to? :specification_version then
|
45
|
+
s.specification_version = 3
|
46
|
+
|
47
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
48
|
+
s.add_development_dependency(%q<rake>, [">= 0"])
|
49
|
+
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
50
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
51
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
52
|
+
s.add_development_dependency(%q<ruby-debug19>, [">= 0"])
|
53
|
+
else
|
54
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
55
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
56
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
57
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
58
|
+
s.add_dependency(%q<ruby-debug19>, [">= 0"])
|
59
|
+
end
|
60
|
+
else
|
61
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
62
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
63
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
64
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
65
|
+
s.add_dependency(%q<ruby-debug19>, [">= 0"])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
data/spec/settings.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
class SettingsInst < Settingslogic
|
2
|
+
end
|
3
|
+
|
4
|
+
class Settings < Settingslogic
|
5
|
+
source "#{File.dirname(__FILE__)}/settings.yml"
|
6
|
+
end
|
7
|
+
|
8
|
+
class Settings2 < Settingslogic
|
9
|
+
source "#{File.dirname(__FILE__)}/settings.yml"
|
10
|
+
namespace "setting1"
|
11
|
+
end
|
12
|
+
|
13
|
+
class Settings3 < Settingslogic
|
14
|
+
source "#{File.dirname(__FILE__)}/settings.yml"
|
15
|
+
load! # test of load
|
16
|
+
end
|
17
|
+
|
18
|
+
# settings.yml, settings2.yml and settings3.yml should be merged
|
19
|
+
class Settings4 < Settingslogic
|
20
|
+
source ["#{File.dirname(__FILE__)}/settings.yml", "#{File.dirname(__FILE__)}/settings2.yml", "#{File.dirname(__FILE__)}/settings3.yml"]
|
21
|
+
end
|
22
|
+
|
23
|
+
# settings should be taken only from settings.yml
|
24
|
+
class Settings5 < Settingslogic
|
25
|
+
source ["#{File.dirname(__FILE__)}/settings_invalid.yml", "#{File.dirname(__FILE__)}/settings.yml", "#{File.dirname(__FILE__)}/non_exisiting.yml"]
|
26
|
+
end
|
27
|
+
|
28
|
+
# should raise an error - no valid settings file
|
29
|
+
class Settings6 < Settingslogic
|
30
|
+
source ["#{File.dirname(__FILE__)}/settings_invalid.yml", "#{File.dirname(__FILE__)}/non_exisiting.yml"]
|
31
|
+
end
|
32
|
+
|
33
|
+
class Settings7 < Settingslogic
|
34
|
+
source "#{File.dirname(__FILE__)}/settings.yml"
|
35
|
+
suppress_errors true
|
36
|
+
end
|
data/spec/settings.yml
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
setting1:
|
2
|
+
setting1_child: saweet
|
3
|
+
deep:
|
4
|
+
another: my value
|
5
|
+
child:
|
6
|
+
value: 2
|
7
|
+
|
8
|
+
setting2: 5
|
9
|
+
|
10
|
+
setting3: <%= 5 * 5 %>
|
11
|
+
name: test
|
12
|
+
|
13
|
+
level0:
|
14
|
+
level1:
|
15
|
+
is: from_settings
|
16
|
+
|
17
|
+
language:
|
18
|
+
haskell:
|
19
|
+
paradigm: functional
|
20
|
+
smalltalk:
|
21
|
+
paradigm: object oriented
|
22
|
+
|
23
|
+
collides:
|
24
|
+
does: not
|
25
|
+
nested:
|
26
|
+
collides:
|
27
|
+
does: not either
|
data/spec/settings2.yml
ADDED
data/spec/settings3.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
another_setting: from settings3.yml
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
|
2
|
+
|
3
|
+
describe "Settingslogic" do
|
4
|
+
it "should access settings" do
|
5
|
+
Settings.setting2.should == 5
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should access nested settings" do
|
9
|
+
Settings.setting1.setting1_child.should == "saweet"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should access deep nested settings" do
|
13
|
+
Settings.setting1.deep.another.should == "my value"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should access extra deep nested settings" do
|
17
|
+
Settings.setting1.deep.child.value.should == 2
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should enable erb" do
|
21
|
+
Settings.setting3.should == 25
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should namespace settings" do
|
25
|
+
Settings2.setting1_child.should == "saweet"
|
26
|
+
Settings2.deep.another.should == "my value"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return the namespace" do
|
30
|
+
Settings.namespace.should be_nil
|
31
|
+
Settings2.namespace.should == 'setting1'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should distinguish nested keys" do
|
35
|
+
Settings.language.haskell.paradigm.should == 'functional'
|
36
|
+
Settings.language.smalltalk.paradigm.should == 'object oriented'
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should not collide with global methods" do
|
40
|
+
Settings3.nested.collides.does.should == 'not either'
|
41
|
+
Settings3[:nested] = 'fooey'
|
42
|
+
Settings3[:nested].should == 'fooey'
|
43
|
+
Settings3.nested.should == 'fooey'
|
44
|
+
Settings3.collides.does.should == 'not'
|
45
|
+
end
|
46
|
+
|
47
|
+
# multiple settings sources
|
48
|
+
it "should override previous settings with next in array" do
|
49
|
+
Settings4.setting2.should == "overwritten!"
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should override previous settings with next in array (deep)" do
|
53
|
+
Settings4.level0.level1.is.should == "from_settings2"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should not raise error when at least one file is present and valid" do
|
57
|
+
Settings5.name.should == "test"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should raise an error when none of the files is present and valid" do
|
61
|
+
begin
|
62
|
+
Settings6.name
|
63
|
+
rescue => e
|
64
|
+
e.should be_kind_of Settingslogic::InvalidSettingsFile
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should accept an array of file names as a source argument and load all of them" do
|
69
|
+
Settings4.setting1.setting1_child.should == "saweet"
|
70
|
+
Settings4.setting4.should == "from settings2.yml"
|
71
|
+
Settings4.another_setting.should == "from settings3.yml"
|
72
|
+
end
|
73
|
+
|
74
|
+
# loading additional settings in the runtime
|
75
|
+
it "should merge hash into existing settings" do
|
76
|
+
Settings.load_source({"level0" => {"level1" => {"added" => 'this'}}})
|
77
|
+
Settings.level0.level1.is.should == 'from_settings'
|
78
|
+
Settings.level0.level1.added.should == 'this'
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should merge file into existing settings" do
|
82
|
+
Settings.load_source("#{File.dirname(__FILE__)}/settings2.yml")
|
83
|
+
Settings.setting1.setting1_child.should == "saweet"
|
84
|
+
Settings.setting4.should == "from settings2.yml"
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should merge array of files into existing settings" do
|
88
|
+
Settings.load_source(["#{File.dirname(__FILE__)}/settings2.yml", "#{File.dirname(__FILE__)}/settings3.yml"])
|
89
|
+
Settings.setting1.setting1_child.should == "saweet"
|
90
|
+
Settings.another_setting.should == "from settings3.yml"
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should raise a helpful error message" do
|
94
|
+
e = nil
|
95
|
+
begin
|
96
|
+
Settings.missing
|
97
|
+
rescue => e
|
98
|
+
e.should be_kind_of Settingslogic::MissingSetting
|
99
|
+
end
|
100
|
+
e.should_not be_nil
|
101
|
+
e.message.should =~ /Missing setting 'missing' in/
|
102
|
+
|
103
|
+
e = nil
|
104
|
+
begin
|
105
|
+
Settings.language.missing
|
106
|
+
rescue => e
|
107
|
+
e.should be_kind_of Settingslogic::MissingSetting
|
108
|
+
end
|
109
|
+
e.should_not be_nil
|
110
|
+
e.message.should =~ /Missing setting 'missing' in 'language' section/
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should handle optional / dynamic settings" do
|
114
|
+
e = nil
|
115
|
+
begin
|
116
|
+
Settings.language.erlang
|
117
|
+
rescue => e
|
118
|
+
e.should be_kind_of Settingslogic::MissingSetting
|
119
|
+
end
|
120
|
+
e.should_not be_nil
|
121
|
+
e.message.should =~ /Missing setting 'erlang' in 'language' section/
|
122
|
+
|
123
|
+
Settings.language['erlang'].should be_nil
|
124
|
+
Settings.language['erlang'] = 5
|
125
|
+
Settings.language['erlang'].should == 5
|
126
|
+
|
127
|
+
Settings.language['erlang'] = {'paradigm' => 'functional'}
|
128
|
+
Settings.language.erlang.paradigm.should == 'functional'
|
129
|
+
Settings.respond_to?('erlang').should be_false
|
130
|
+
|
131
|
+
Settings.reload!
|
132
|
+
Settings.language['erlang'].should be_nil
|
133
|
+
|
134
|
+
Settings.language[:erlang] ||= 5
|
135
|
+
Settings.language[:erlang].should == 5
|
136
|
+
|
137
|
+
Settings.language[:erlang] = {}
|
138
|
+
Settings.language[:erlang][:paradigm] = 'functional'
|
139
|
+
Settings.language.erlang.paradigm.should == 'functional'
|
140
|
+
|
141
|
+
Settings[:toplevel] = '42'
|
142
|
+
Settings.toplevel.should == '42'
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should raise an error on a nil source argument" do
|
146
|
+
class NoSource < Settingslogic; end
|
147
|
+
e = nil
|
148
|
+
begin
|
149
|
+
NoSource.foo.bar
|
150
|
+
rescue => e
|
151
|
+
e.should be_kind_of Errno::ENOENT
|
152
|
+
end
|
153
|
+
e.should_not be_nil
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should allow suppressing errors" do
|
157
|
+
Settings7.non_existent_key.should be_nil
|
158
|
+
end
|
159
|
+
|
160
|
+
# This one edge case currently does not pass, because it requires very
|
161
|
+
# esoteric code in order to make it pass. It was judged not worth fixing,
|
162
|
+
# as it introduces significant complexity for minor gain.
|
163
|
+
# it "should handle reloading top-level settings"
|
164
|
+
# Settings[:inspect] = 'yeah baby'
|
165
|
+
# Settings.inspect.should == 'yeah baby'
|
166
|
+
# Settings.reload!
|
167
|
+
# Settings.inspect.should == 'Settings'
|
168
|
+
# end
|
169
|
+
|
170
|
+
it "should handle oddly-named settings" do
|
171
|
+
Settings.language['some-dash-setting#'] = 'dashtastic'
|
172
|
+
Settings.language['some-dash-setting#'].should == 'dashtastic'
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should support instance usage as well" do
|
176
|
+
settings = SettingsInst.new(Settings.source)
|
177
|
+
settings.setting1.setting1_child.should == "saweet"
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should be able to get() a key with dot.notation" do
|
181
|
+
Settings.get('setting1.setting1_child').should == "saweet"
|
182
|
+
Settings.get('setting1.deep.another').should == "my value"
|
183
|
+
Settings.get('setting1.deep.child.value').should == 2
|
184
|
+
end
|
185
|
+
|
186
|
+
# If .name is not a property, delegate to superclass
|
187
|
+
it "should respond with Module.name" do
|
188
|
+
Settings2.name.should == "Settings2"
|
189
|
+
end
|
190
|
+
|
191
|
+
# If .name is called on Settingslogic itself, handle appropriately
|
192
|
+
# by delegating to Hash
|
193
|
+
it "should have the parent class always respond with Module.name" do
|
194
|
+
Settingslogic.name.should == 'Settingslogic'
|
195
|
+
end
|
196
|
+
|
197
|
+
# If .name is a property, respond with that instead of delegating to superclass
|
198
|
+
it "should allow a name setting to be overriden" do
|
199
|
+
Settings.name.should == 'test'
|
200
|
+
end
|
201
|
+
|
202
|
+
# Put this test last or else call to .instance will load @instance,
|
203
|
+
# masking bugs.
|
204
|
+
it "should be a hash" do
|
205
|
+
Settings.send(:instance).should be_is_a(Hash)
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'rspec'
|
4
|
+
require 'settingslogic'
|
5
|
+
require 'settings'
|
6
|
+
|
7
|
+
# Needed to test Settings3
|
8
|
+
Object.send :define_method, 'collides' do
|
9
|
+
'collision'
|
10
|
+
end
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: siliconsalad-settingslogic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.9
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ben Johnson of Binary Logic
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &70122421875020 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70122421875020
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: jeweler
|
27
|
+
requirement: &70122422223700 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70122422223700
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70122422219820 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70122422219820
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rcov
|
49
|
+
requirement: &70122422218780 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70122422218780
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: ruby-debug19
|
60
|
+
requirement: &70122422217280 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70122422217280
|
69
|
+
description:
|
70
|
+
email: bjohnson@binarylogic.com
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files:
|
74
|
+
- LICENSE
|
75
|
+
- README.rdoc
|
76
|
+
files:
|
77
|
+
- CHANGELOG.rdoc
|
78
|
+
- Gemfile
|
79
|
+
- Gemfile.lock
|
80
|
+
- LICENSE
|
81
|
+
- README.rdoc
|
82
|
+
- Rakefile
|
83
|
+
- VERSION.yml
|
84
|
+
- init.rb
|
85
|
+
- lib/settingslogic.rb
|
86
|
+
- rails/init.rb
|
87
|
+
- settingslogic.gemspec
|
88
|
+
- siliconsalad-settingslogic.gemspec
|
89
|
+
- spec/settings.rb
|
90
|
+
- spec/settings.yml
|
91
|
+
- spec/settings2.yml
|
92
|
+
- spec/settings3.yml
|
93
|
+
- spec/settings_invalid.yml
|
94
|
+
- spec/settingslogic_spec.rb
|
95
|
+
- spec/spec_helper.rb
|
96
|
+
homepage: http://github.com/siliconsalad/settingslogic
|
97
|
+
licenses: []
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
104
|
+
requirements:
|
105
|
+
- - ! '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ! '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
requirements: []
|
115
|
+
rubyforge_project:
|
116
|
+
rubygems_version: 1.8.17
|
117
|
+
signing_key:
|
118
|
+
specification_version: 3
|
119
|
+
summary: A simple and straightforward settings solution that uses an ERB enabled YAML
|
120
|
+
file and a singleton design pattern.
|
121
|
+
test_files: []
|