mc-settings 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 32996c683ae9a0437ef3b40f2cbba22b967c69f6527e3b62ca272e48c06b8597
4
+ data.tar.gz: a7779f2a1334f8b0b7324fedc44209773bb50973b3f2a422a2e47b37e344a6ef
5
+ SHA512:
6
+ metadata.gz: fb499eda38d18f7dc13b1f94a93c5adb8779f9c8e9875981150075c1b4f5505940b86c0b3c87a49c4805f2871c03180b9eb132398a41439e43804989f2f9697c
7
+ data.tar.gz: 0c08e73de2e86263ab0742e69b04725272e3fa9e42f84507c4ff9d3354460dd7c7741fb852f255c15f822a43dc34a7e298b965e9471f54aceb708866f77db00f
@@ -0,0 +1,24 @@
1
+ name: Ruby
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ build:
11
+
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ - uses: actions/checkout@v2
16
+ - name: Set up Ruby 2.6
17
+ uses: actions/setup-ruby@v1
18
+ with:
19
+ ruby-version: 2.6.x
20
+ - name: Run Tests
21
+ run: |
22
+ gem install bundler
23
+ bundle install --jobs 4 --retry 3
24
+ bundle exec rspec
@@ -0,0 +1,45 @@
1
+ # rcov generated
2
+ coverage
3
+
4
+ # rdoc generated
5
+ rdoc
6
+
7
+ # yard generated
8
+ doc
9
+ .yardoc
10
+
11
+ # bundler
12
+ .bundle
13
+
14
+ # jeweler generated
15
+ pkg
16
+
17
+ # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
18
+ #
19
+ # * Create a file at ~/.gitignore
20
+ # * Include files you want ignored
21
+ # * Run: git config --global core.excludesfile ~/.gitignore
22
+ #
23
+ # After doing this, these files will be ignored in all your git projects,
24
+ # saving you from having to 'pollute' every project you touch with them
25
+ #
26
+ # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
27
+ #
28
+ # For MacOS:
29
+ #
30
+ #.DS_Store
31
+ #
32
+ # For TextMate
33
+ #*.tmproj
34
+ #tmtags
35
+ #
36
+ # For emacs:
37
+ #*~
38
+ #\#*
39
+ #.\#*
40
+ #
41
+ # For vim:
42
+ #*.swp
43
+ .idea
44
+ .rvmrc
45
+ Gemfile.lock
data/Gemfile CHANGED
@@ -1,14 +1,3 @@
1
- source "http://rubygems.org"
2
- # Add dependencies required to use your gem here.
3
- # Example:
4
- # gem "activesupport", ">= 2.3.5"
1
+ source "https://rubygems.org"
5
2
 
6
- # Add dependencies to develop your gem here.
7
- # Include everything needed to run rake, tests, features, etc.
8
- group :development do
9
- gem "rspec"
10
- gem "bundler", "~> 1.0.0"
11
- gem "jeweler", "~> 1.5.1"
12
- gem "rcov", ">= 0"
13
- gem "ruby-debug"
14
- end
3
+ gemspec
@@ -1,36 +1,55 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ mc-settings (0.2.0)
5
+
1
6
  GEM
2
- remote: http://rubygems.org/
7
+ remote: https://rubygems.org/
3
8
  specs:
4
- columnize (0.3.2)
5
- diff-lcs (1.1.2)
6
- git (1.2.5)
7
- jeweler (1.5.1)
8
- bundler (~> 1.0.0)
9
- git (>= 1.2.5)
10
- rake
11
- linecache (0.43)
12
- rake (0.8.7)
13
- rcov (0.9.9)
14
- rspec (2.3.0)
15
- rspec-core (~> 2.3.0)
16
- rspec-expectations (~> 2.3.0)
17
- rspec-mocks (~> 2.3.0)
18
- rspec-core (2.3.0)
19
- rspec-expectations (2.3.0)
20
- diff-lcs (~> 1.1.2)
21
- rspec-mocks (2.3.0)
22
- ruby-debug (0.10.4)
23
- columnize (>= 0.1)
24
- ruby-debug-base (~> 0.10.4.0)
25
- ruby-debug-base (0.10.4)
26
- linecache (>= 0.3)
9
+ asciidoctor (2.0.10)
10
+ byebug (11.1.3)
11
+ coderay (1.1.3)
12
+ diff-lcs (1.4.4)
13
+ docile (1.3.2)
14
+ method_source (1.0.0)
15
+ pry (0.13.1)
16
+ coderay (~> 1.1)
17
+ method_source (~> 1.0)
18
+ pry-byebug (3.9.0)
19
+ byebug (~> 11.0)
20
+ pry (~> 0.13.0)
21
+ rake (13.0.1)
22
+ rspec (3.9.0)
23
+ rspec-core (~> 3.9.0)
24
+ rspec-expectations (~> 3.9.0)
25
+ rspec-mocks (~> 3.9.0)
26
+ rspec-core (3.9.2)
27
+ rspec-support (~> 3.9.3)
28
+ rspec-expectations (3.9.2)
29
+ diff-lcs (>= 1.2.0, < 2.0)
30
+ rspec-support (~> 3.9.0)
31
+ rspec-mocks (3.9.1)
32
+ diff-lcs (>= 1.2.0, < 2.0)
33
+ rspec-support (~> 3.9.0)
34
+ rspec-support (3.9.3)
35
+ simplecov (0.19.0)
36
+ docile (~> 1.1)
37
+ simplecov-html (~> 0.11)
38
+ simplecov-html (0.12.2)
27
39
 
28
40
  PLATFORMS
29
41
  ruby
30
42
 
31
43
  DEPENDENCIES
32
- bundler (~> 1.0.0)
33
- jeweler (~> 1.5.1)
34
- rcov
35
- rspec
36
- ruby-debug
44
+ asciidoctor
45
+ bundler
46
+ mc-settings!
47
+ pry-byebug
48
+ rake
49
+ rspec (~> 3.0)
50
+ rspec-expectations
51
+ rspec-mocks
52
+ simplecov
53
+
54
+ BUNDLED WITH
55
+ 2.1.4
@@ -1,20 +1,7 @@
1
- Copyright (c) 2010 Edwin Cruz
1
+ Copyright 2010-2020 Edwin Cruz, Colin Shield, Konstantin Gredeskoul
2
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:
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10
4
 
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
13
6
 
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.
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,217 @@
1
+ = MC-Settings — An Application Settings Manager
2
+ :toc:
3
+ :toclevels: 4
4
+ :sectnums:
5
+
6
+
7
+ image:https://github.com/kigster/mc-settings/workflows/Ruby/badge.svg[Ruby,link=https://github.com/kigster/kitchen/actions?query=workflow%3ARuby]
8
+
9
+ == Description
10
+
11
+ This Ruby gem provides a an easy way to manage application configuration across multiple environments, such as development, QA, staging, production, etc.
12
+ It should be compatible with Capistrano deployments.
13
+
14
+ === Background
15
+
16
+ Applications typically rely on configuration settings, such as host names, URLs, usernames and many more.
17
+ Some values change between deployment environemnts, some do not.
18
+
19
+ The library assumes that application configuration is represented by a Hash of arbitrary depth, and provides a convenient and a compact syntax to access the settings through a singleton instance inside Setting class.
20
+
21
+ Configuration is stored in one or more YAML files with the top-level Hash, having the keys as names of individual settings.
22
+
23
+ === Example
24
+
25
+ For example, consider the following sample application configuration file:
26
+
27
+ [source,yaml]
28
+ ----
29
+ tax:
30
+ default: 0.0
31
+ california: 7.5
32
+ states:
33
+ default:
34
+ - 'CA'
35
+ - 'WA'
36
+ - 'NY'
37
+ ship_to:
38
+ - 'CA'
39
+ - 'NY'
40
+ math_pi: 3.14159526
41
+ ----
42
+
43
+ Setting Gem provides `Setting.load(..)` method to load configuration from files in a way that allows some configuration files to override previously loaded values, and then offers a simple method API to access the values, for example `Setting.tax(:california)` or `Setting.tax`.
44
+ Supporting default values in 2nd, 3rd, .. - level hashes is one of the advantages of using this gem.
45
+
46
+ By loading configuration from YAML files, Setting gem is inherently compatible with Capistrano deployment methodology, where a certain set of files may become "activated" by simply sym-linking them into the appropriate settings folder.
47
+
48
+ Note: using example above, "1st level" hash is the one with keys `tax`, `states` and `math_pi`.
49
+ The 2nd-level hash is, for example, the tax definition one, with keys `default` and `california`.
50
+
51
+ == Usage
52
+
53
+ Once configuration is initialized using `Setting#load` or `Setting#reload` methods (see below), they can be used in code in the following way:
54
+
55
+ * `Setting.key_name` is optimized to return default value if available instead of a Hash.
56
+ * `Setting.key_name(:sub_key_name)` returns a value from the 2nd level hash.
57
+ * `Setting.key_name(:sub_key_name, :sub_sub_key_name)` returns value from the 3rd level hash if available.
58
+ +
59
+ The algorithm is recursive, so only the maximum method stack depth will limit the number of nested hash values you can access this way.
60
+ * Special syntax `Setting[:key_name]`, `Setting[:key_name][:sub_key_name]`, etc also supported.
61
+ This method, however, does not support default values (see below).
62
+
63
+ NOTE: Method notation is recommended over square bracket accessing single values.
64
+
65
+ However, square bracket notation may be useful when you want to fetch the entire 2nd-level hash that includes the default value.
66
+
67
+ For example, given the above YAML file, you can access the settings in your code as follows:
68
+
69
+ [source,ruby]
70
+ ----
71
+ Setting.tax => 0.0
72
+ Setting.tax(:california) => 7.5
73
+ Setting.math_pi => 3.14159526
74
+ Setting[:math_pi] => 3.14159526
75
+ Setting.states => [ 'CA', 'WA', 'NY' ]
76
+ Setting.states['ship_to'] => [ 'CA', 'NY' ]
77
+ ----
78
+
79
+ Method-calling notation allows passing an array of keys to fetch a value from a nested hash.
80
+ This method also supports returning a default value, stored against the "default" key.
81
+
82
+ [source,ruby]
83
+ ----
84
+ Setting.tax => 0.0
85
+ ----
86
+
87
+ Square bracket syntax returns the actual nested hash, without any regard for the default value:
88
+
89
+ [source,ruby]
90
+ ----
91
+ Setting[:tax] => { 'default' => 0.0, 'california' => 7.5 }
92
+ ----
93
+
94
+ == Loading Settings
95
+
96
+ The gem should be initialized in your environment.rb (if using Rails), or in any other application initialization block. `Setting.load()` method is provided for loading settings, and it can be called only once in application life cycle, or it will throw an exception.
97
+
98
+ If you need to reload settings, use the `reload()` method with similar arguments.
99
+
100
+ Consider an example:
101
+
102
+ [source,ruby]
103
+ ----
104
+ Setting.load(
105
+ path: "#{Rails.root}/config/settings",
106
+ files: ["default.yml", "environments/#{Rails.env}.yml"],
107
+ local: true
108
+ )
109
+ ----
110
+
111
+ The argument is an options hash that configures which YAML files to load, in what order, and from where.
112
+
113
+ * *path* specifies the "root" folder where settings files will be loaded from
114
+ * *files* is an array that lists file names relative to the path.
115
+ * *local* can be optionally specified as a true value, and if the specified Setting gem will load all `*.yml` files that live under the :path/local folder.
116
+
117
+ Below is list of YAML files loaded in order specified in the above example, assuming that "development" is the Rails environment, and "local" folder exists with 3 additional YAML files in it:
118
+
119
+ config/settings/default.yml
120
+ config/settings/environments/development.yml
121
+ config/settings/local/authorize-net.yml
122
+ config/settings/local/paypal.yml
123
+ config/settings/local/other.yml
124
+
125
+ Each YML file defines a ruby Hash.
126
+ During file loading, the hashes are merged, so that values loaded in early files may be overwritten by values in subsequent files.
127
+ This is deliberate and by design: it allows you to create small "override" files for each environment, or even each machine you want to deploy to.
128
+ Exactly how you split your application settings in files is up to you.
129
+
130
+ === Nested Hashes and Default Values
131
+
132
+ MC Setting gem provides a convenient way to access nested values, including full support for the default values within nested hashes (as of 0.1.1).
133
+
134
+ Consider the following nested hash example:
135
+
136
+ *default.yml*
137
+
138
+ [source,yaml]
139
+ ----
140
+ services:
141
+ inventory:
142
+ url: http://ims.mycompany.com:3443/inventory_manager
143
+ name: Inventory Management
144
+ shipping:
145
+ url: http://ship.mycompany.com:3443/shipper
146
+ name: Shipping
147
+ ----
148
+
149
+ [source,ruby]
150
+ ----
151
+ Setting.load(:files => ['default.yml'], :path => ...)
152
+
153
+ Setting.services(:inventory)
154
+ # => {
155
+ # :url => "http://localhost:3443/inventory_manager",
156
+ # :name => "Inventory Management"
157
+ # }
158
+
159
+ Setting.services(:inventory, :url)
160
+ # => "http://localhost:3443/inventory_manager"
161
+
162
+ ----
163
+
164
+ *staging.yml*
165
+
166
+ We are changing URLs for services in staging.yml, so they work in the staging environment. Service URLs have been updated to use localhost:
167
+
168
+ [source,yaml]
169
+ ----
170
+ services:
171
+ inventory:
172
+ url: http://localhost:8009/inventory_manager
173
+ shipping:
174
+ url: http://localhost:8008/shipper
175
+ ----
176
+
177
+ [source,ruby]
178
+ ----
179
+ Setting.load(:files => ['default.yml', 'staging.yml'], :path => ...)
180
+
181
+ Setting.services(:inventory)
182
+ # => {
183
+ # :url => "http://localhost:8009/inventory_manager",
184
+ # :name => "Inventory Management"
185
+ # }
186
+
187
+ Setting.services(:inventory, :url)
188
+ # => "http://localhost:8008/inventory_manager"
189
+ ----
190
+
191
+ == Capistrano Recommendations
192
+
193
+ Assume the directory structure of your Rails application is as follows:
194
+
195
+ config/settings/default.yml
196
+ config/settings/environments/development.yml
197
+ config/settings/environments/staging.yml
198
+ config/settings/environments/production.yml
199
+ config/settings/local
200
+ config/settings/systems/reporting.yml
201
+ config/settings/systems/admin.yml
202
+
203
+ Note that the "local" directory is empty, and that the "systems" directory contains several YAML files which provide alternative configuration for a reporting server and the admin server, both of which run in the "production" rails environment.
204
+
205
+ When deploying to the main production site, neither YAML files inside "systems" folder are activated or used.
206
+
207
+ But upon deployment to the admin server, Capistrano could symlink "admin.yml" from `config/settings/local` folder, so the Setting gem would load these values. So for each Capistrano role, you can define which files need to be symlinked into local, thus creating a flexible configuration scheme which can be easily managed by Capistrano.
208
+
209
+ == Copyright
210
+
211
+ Copyright 2010-2020 © ModCloth Inc & Contributors.
212
+
213
+ Authors: 2010-2020 Edwin Cruz, Colin Shield & Konstantin Gredeskoul
214
+
215
+ == License
216
+
217
+ This software is distributed under the xref:LICENSE.txt[MIT License].
data/Rakefile CHANGED
@@ -1,50 +1,29 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+ require 'timeout'
6
+
7
+ def shell(*args)
8
+ puts "running: #{args.join(' ')}"
9
+ system(args.join(' '))
9
10
  end
10
- require 'rake'
11
-
12
- require 'jeweler'
13
- Jeweler::Tasks.new do |gem|
14
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
- gem.name = "mc-settings"
16
- gem.homepage = "http://github.com/modcloth/mc-settings"
17
- gem.license = "MIT"
18
- gem.summary = %Q{Manage settings per environment}
19
- gem.description = %Q{implement custom keys indenendently of environment}
20
- gem.email = "rubydev@modcloth.com"
21
- gem.authors = ["Edwin Cruz", "Colin Shield"]
22
- # Include your dependencies below. Runtime dependencies are required when using your gem,
23
- # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
24
- # gem.add_runtime_dependency 'jabber4r', '> 0.1'
25
- # gem.add_development_dependency 'rspec', '> 1.2.3'
11
+
12
+ task :clean do
13
+ shell('rm -rf pkg/ tmp/ coverage/ doc/ ' )
26
14
  end
27
- Jeweler::RubygemsDotOrgTasks.new
28
15
 
29
- require 'rspec/core'
30
- require 'rspec/core/rake_task'
31
- require 'ruby-debug'
32
- RSpec::Core::RakeTask.new(:spec) do |spec|
33
- spec.pattern = FileList['spec/**/*_spec.rb']
16
+ task gem: [:build] do
17
+ shell('gem install pkg/*')
34
18
  end
35
19
 
36
- RSpec::Core::RakeTask.new(:rcov) do |spec|
37
- spec.pattern = 'spec/**/*_spec.rb'
20
+ task permissions: [:clean] do
21
+ shell("chmod -v o+r,g+r * */* */*/* */*/*/* */*/*/*/* */*/*/*/*/*")
22
+ shell("find . -type d -exec chmod o+x,g+x {} \\;")
38
23
  end
39
24
 
40
- task :default => :spec
25
+ task build: :permissions
41
26
 
42
- require 'rake/rdoctask'
43
- Rake::RDocTask.new do |rdoc|
44
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
27
+ RSpec::Core::RakeTask.new(:spec)
45
28
 
46
- rdoc.rdoc_dir = 'rdoc'
47
- rdoc.title = "mc-settings #{version}"
48
- rdoc.rdoc_files.include('README*')
49
- rdoc.rdoc_files.include('lib/**/*.rb')
50
- end
29
+ task default: :spec