mc-settings 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +49 -28
- data/VERSION +1 -1
- data/lib/setting.rb +1 -1
- data/mc-settings.gemspec +3 -4
- data/spec/mc_settings_spec.rb +6 -0
- data/spec/support/settings_helper.rb +8 -0
- metadata +16 -16
data/README.rdoc
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
== Summary
|
4
4
|
|
5
|
-
This gem provides an easy and
|
5
|
+
This gem provides an easy and Capistrano-friendly way to manage application configuration across
|
6
6
|
multiple environments, such as development, QA, staging, production, etc.
|
7
7
|
|
8
8
|
Applications typically rely on configuration settings, such as host names, URLs, usernames and many
|
@@ -30,9 +30,9 @@ application configuration file:
|
|
30
30
|
Setting Gem provides Setting.load(..) method to load configuration from files in a way that allows
|
31
31
|
some configuration files to override previously loaded values, and then offers a simple method API
|
32
32
|
to access the values, for example Setting.tax(:california) or Setting.tax. Supporting default values
|
33
|
-
in 2nd, 3rd,
|
33
|
+
in 2nd, 3rd, .. - level hashes is one of the advantages of using this gem.
|
34
34
|
|
35
|
-
By loading configuration from files, Setting is inherently compatible with Capistrano deployment
|
35
|
+
By loading configuration from YAML files, Setting gem is inherently compatible with Capistrano deployment
|
36
36
|
methodology, where a certain set of files may become "activated" by simply sym-linking them into
|
37
37
|
the appropriate settings folder.
|
38
38
|
|
@@ -49,9 +49,9 @@ code in the following way:
|
|
49
49
|
* Setting.key_name(:sub_key_name, :sub_sub_key_name) returns value from the 3rd level hash if available. The algorithm is recursive, so only the maximum method stack depth will limit the number of nested hash values you can access this way.
|
50
50
|
* Special syntax Setting[:key_name], Setting[:key_name][:sub_key_name], etc also supported. This method, however, does not support default values (see below).
|
51
51
|
|
52
|
-
Method notation is recommended over square bracket notation for
|
53
|
-
may be useful when you want to fetch the entire 2nd level hash that
|
54
|
-
default value itself.
|
52
|
+
Method notation is recommended over square bracket notation for accessing single values. However,
|
53
|
+
square bracket notation may be useful when you want to fetch the entire 2nd level hash that
|
54
|
+
includes the default value, instead of the default value itself.
|
55
55
|
|
56
56
|
For example, given the above YAML file, you can access the settings in your code as follows:
|
57
57
|
|
@@ -62,12 +62,12 @@ For example, given the above YAML file, you can access the settings in your code
|
|
62
62
|
Setting.states => [ 'CA', 'WA', 'NY' ]
|
63
63
|
Setting.states['ship_to'] => [ 'CA', 'NY' ]
|
64
64
|
|
65
|
-
Method
|
66
|
-
|
65
|
+
Method-calling notation allows passing an array of keys to fetch a value from a nested hash.
|
66
|
+
This method also supports returning a default value, stored against the "default" key.
|
67
67
|
|
68
68
|
Setting.tax => 0.0
|
69
69
|
|
70
|
-
Square bracket syntax returns the actual
|
70
|
+
Square bracket syntax returns the actual nested hash, without any regard for the default value:
|
71
71
|
|
72
72
|
Setting[:tax] => { 'default' => 0.0, 'california' => 7.5 }
|
73
73
|
|
@@ -84,14 +84,14 @@ Consider an example:
|
|
84
84
|
:files => ["default.yml", "environments/#{Rails.env}.yml"],
|
85
85
|
:local => true)
|
86
86
|
|
87
|
-
The argument is
|
87
|
+
The argument is an options hash that configures which YAML files to load, in what order, and from where.
|
88
88
|
|
89
|
-
*
|
90
|
-
*
|
91
|
-
*
|
89
|
+
* path specifies the "root" folder where settings files will be loaded from
|
90
|
+
* files is an array that lists file names relative to the :path. In the example above, settings folder contains subfolder "environments" where Rails-specific environment files are located (such as "development.yml", "staging.yml", "production.yml", etc)
|
91
|
+
* local can be optionally specified as a true value, and if specified Setting gem will load all *.yml files that live under the :path/local folder.
|
92
92
|
|
93
|
-
Below is list of
|
94
|
-
the Rails environment, and "local" folder exists with 3 additional
|
93
|
+
Below is list of YAML files loaded in order specified in the above example, assuming that "development" is
|
94
|
+
the Rails environment, and "local" folder exists with 3 additional YAML files in it:
|
95
95
|
|
96
96
|
config/settings/default.yml
|
97
97
|
config/settings/environments/development.yml
|
@@ -99,15 +99,16 @@ the Rails environment, and "local" folder exists with 3 additional YML files in
|
|
99
99
|
config/settings/local/paypal.yml
|
100
100
|
config/settings/local/other.yml
|
101
101
|
|
102
|
-
Each YML file defines a ruby Hash. During file loading, the hashes are merged,
|
103
|
-
|
104
|
-
|
105
|
-
|
102
|
+
Each YML file defines a ruby Hash. During file loading, the hashes are merged,
|
103
|
+
so that values loaded in early files may be overwritten by values in subsequent
|
104
|
+
files. This is deliberate and by design: it allows you to create small "override"
|
105
|
+
files for each environment, or even each machine you want to deploy to. Exactly
|
106
|
+
how you split your application settings in files is up to you.
|
106
107
|
|
107
108
|
== Nested Hashes and Default Values
|
108
109
|
|
109
|
-
MC Setting gem provides a convenient way to access nested values, including full
|
110
|
-
nested hashes (as of 0.1.1).
|
110
|
+
MC Setting gem provides a convenient way to access nested values, including full
|
111
|
+
support for the default values within nested hashes (as of 0.1.1).
|
111
112
|
|
112
113
|
Consider the following nested hash example:
|
113
114
|
|
@@ -123,11 +124,13 @@ default.yml:
|
|
123
124
|
|
124
125
|
Setting.load(:files => ['default.yml'], :path => ...)
|
125
126
|
|
126
|
-
Setting.
|
127
|
-
Setting.
|
127
|
+
Setting.services(:inventory) => { :url => "http://localhost:3443/inventory_manager" :name => "Inventory Management"}
|
128
|
+
Setting.services(:inventory, :url) => "http://localhost:3443/inventory_manager"
|
128
129
|
|
129
|
-
staging.yml
|
130
|
-
|
130
|
+
staging.yml
|
131
|
+
|
132
|
+
We are changing URLs for services in staging.yml, so they work in the staging environment. Service URLs have been updated
|
133
|
+
to use localhost:
|
131
134
|
|
132
135
|
services:
|
133
136
|
inventory:
|
@@ -135,14 +138,32 @@ staging only:
|
|
135
138
|
shipping:
|
136
139
|
url: http://localhost:8008/shipper
|
137
140
|
|
141
|
+
|
138
142
|
Setting.load(:files => ['default.yml', 'staging.yml'], :path => ...)
|
139
143
|
|
140
|
-
Setting.
|
141
|
-
Setting.
|
144
|
+
Setting.services(:inventory) => { :url => "http://localhost:8009/inventory_manager" :name => "Inventory Management"}
|
145
|
+
Setting.services(:inventory, :url) => "http://localhost:8008/inventory_manager"
|
142
146
|
|
143
147
|
== Capistrano Recommendations
|
144
148
|
|
145
|
-
|
149
|
+
Assume the directory structure of your Rails application is as follows:
|
150
|
+
|
151
|
+
config/settings/default.yml
|
152
|
+
config/settings/environments/development.yml
|
153
|
+
config/settings/environments/staging.yml
|
154
|
+
config/settings/environments/production.yml
|
155
|
+
config/settings/local
|
156
|
+
config/settings/systems/reporting.yml
|
157
|
+
config/settings/systems/admin.yml
|
158
|
+
|
159
|
+
Note that the "local" directory is empty, and that "systems" directory contains several YAML files that provide alternative
|
160
|
+
configuration for a reporting server, and an admin server (both of which run in "production" rails environment).
|
161
|
+
|
162
|
+
When deploying to the main production site, neither YAML files inside "systems" folder are activated or used.
|
163
|
+
|
164
|
+
But upon deployment to the admin server, Capistrano could symlink "admin.yml" from config/settings/local folder, so the Setting gem
|
165
|
+
would load these values. So for each Capistrano role, you can define which files need to be symlinked into local, thus creating
|
166
|
+
a very flexible configuration scheme that's easily managed by Capistrano.
|
146
167
|
|
147
168
|
== Copyright
|
148
169
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.3
|
data/lib/setting.rb
CHANGED
data/mc-settings.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{mc-settings}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Edwin Cruz", "Colin Shield"]
|
12
|
-
s.date = %q{2011-01
|
12
|
+
s.date = %q{2011-06-01}
|
13
13
|
s.description = %q{implement custom keys indenendently of environment}
|
14
14
|
s.email = %q{rubydev@modcloth.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -36,7 +36,7 @@ Gem::Specification.new do |s|
|
|
36
36
|
s.homepage = %q{http://github.com/modcloth/mc-settings}
|
37
37
|
s.licenses = ["MIT"]
|
38
38
|
s.require_paths = ["lib"]
|
39
|
-
s.rubygems_version = %q{1.3
|
39
|
+
s.rubygems_version = %q{1.5.3}
|
40
40
|
s.summary = %q{Manage settings per environment}
|
41
41
|
s.test_files = [
|
42
42
|
"spec/mc_settings_spec.rb",
|
@@ -45,7 +45,6 @@ Gem::Specification.new do |s|
|
|
45
45
|
]
|
46
46
|
|
47
47
|
if s.respond_to? :specification_version then
|
48
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
49
48
|
s.specification_version = 3
|
50
49
|
|
51
50
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
data/spec/mc_settings_spec.rb
CHANGED
@@ -52,6 +52,12 @@ describe Setting do
|
|
52
52
|
it "should create keys if it does not exist" do
|
53
53
|
Setting.test_specific.should == "exist"
|
54
54
|
end
|
55
|
+
|
56
|
+
context "working with arrays" do
|
57
|
+
it "should replace the whole array instead of appending new values" do
|
58
|
+
Setting.nested_array.should == ['first', 'four', 'five']
|
59
|
+
end
|
60
|
+
end
|
55
61
|
end
|
56
62
|
|
57
63
|
context "When running with threads" do
|
@@ -20,6 +20,10 @@ def stub_setting_files
|
|
20
20
|
default: 7
|
21
21
|
flag_false:
|
22
22
|
default: false
|
23
|
+
nested_array:
|
24
|
+
- first
|
25
|
+
- second
|
26
|
+
- third
|
23
27
|
CONTENT
|
24
28
|
test = <<-CONTENT
|
25
29
|
one: test
|
@@ -30,6 +34,10 @@ CONTENT
|
|
30
34
|
six:
|
31
35
|
extra: "recursively overriden"
|
32
36
|
test_specific: "exist"
|
37
|
+
nested_array:
|
38
|
+
- first
|
39
|
+
- four
|
40
|
+
- five
|
33
41
|
CONTENT
|
34
42
|
|
35
43
|
empty = <<-CONTENT
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mc-settings
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 3
|
10
|
+
version: 0.1.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Edwin Cruz
|
@@ -16,12 +16,10 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-01
|
19
|
+
date: 2011-06-01 00:00:00 -05:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
23
|
-
prerelease: false
|
24
|
-
type: :development
|
25
23
|
name: rspec
|
26
24
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
27
25
|
none: false
|
@@ -32,10 +30,10 @@ dependencies:
|
|
32
30
|
segments:
|
33
31
|
- 0
|
34
32
|
version: "0"
|
35
|
-
requirement: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
33
|
prerelease: false
|
38
34
|
type: :development
|
35
|
+
requirement: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
39
37
|
name: bundler
|
40
38
|
version_requirements: &id002 !ruby/object:Gem::Requirement
|
41
39
|
none: false
|
@@ -48,10 +46,10 @@ dependencies:
|
|
48
46
|
- 0
|
49
47
|
- 0
|
50
48
|
version: 1.0.0
|
51
|
-
requirement: *id002
|
52
|
-
- !ruby/object:Gem::Dependency
|
53
49
|
prerelease: false
|
54
50
|
type: :development
|
51
|
+
requirement: *id002
|
52
|
+
- !ruby/object:Gem::Dependency
|
55
53
|
name: jeweler
|
56
54
|
version_requirements: &id003 !ruby/object:Gem::Requirement
|
57
55
|
none: false
|
@@ -64,10 +62,10 @@ dependencies:
|
|
64
62
|
- 5
|
65
63
|
- 1
|
66
64
|
version: 1.5.1
|
67
|
-
requirement: *id003
|
68
|
-
- !ruby/object:Gem::Dependency
|
69
65
|
prerelease: false
|
70
66
|
type: :development
|
67
|
+
requirement: *id003
|
68
|
+
- !ruby/object:Gem::Dependency
|
71
69
|
name: rcov
|
72
70
|
version_requirements: &id004 !ruby/object:Gem::Requirement
|
73
71
|
none: false
|
@@ -78,10 +76,10 @@ dependencies:
|
|
78
76
|
segments:
|
79
77
|
- 0
|
80
78
|
version: "0"
|
81
|
-
requirement: *id004
|
82
|
-
- !ruby/object:Gem::Dependency
|
83
79
|
prerelease: false
|
84
80
|
type: :development
|
81
|
+
requirement: *id004
|
82
|
+
- !ruby/object:Gem::Dependency
|
85
83
|
name: ruby-debug
|
86
84
|
version_requirements: &id005 !ruby/object:Gem::Requirement
|
87
85
|
none: false
|
@@ -92,6 +90,8 @@ dependencies:
|
|
92
90
|
segments:
|
93
91
|
- 0
|
94
92
|
version: "0"
|
93
|
+
prerelease: false
|
94
|
+
type: :development
|
95
95
|
requirement: *id005
|
96
96
|
description: implement custom keys indenendently of environment
|
97
97
|
email: rubydev@modcloth.com
|
@@ -148,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
148
|
requirements: []
|
149
149
|
|
150
150
|
rubyforge_project:
|
151
|
-
rubygems_version: 1.3
|
151
|
+
rubygems_version: 1.5.3
|
152
152
|
signing_key:
|
153
153
|
specification_version: 3
|
154
154
|
summary: Manage settings per environment
|