settei 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/LICENSE.txt +9 -0
- data/README.md +136 -37
- data/lib/settei.rb +1 -1
- data/lib/settei/version.rb +1 -1
- data/lib/tasks/settei_tasks.rake +17 -1
- data/misc/illustrated.png +0 -0
- data/settei.gemspec +2 -2
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea3ce2375e85ac9e98985d0ec6ae3876f0698fd9
|
4
|
+
data.tar.gz: 534303064fc333645a928ebb3fcde9272a82289f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65ac49d58685f659586bf9f4fead8b5f99efdd217f7691fbcad2b6dbb7f5338da211553eae50e599c39bb481129894269ba3acf1d29dec38f96f280e5efd42ae
|
7
|
+
data.tar.gz: d1720aac8d9f8ced2326cc36917ebda0cd912d79bc8aad4d38f406c766032319be613f5108a981ce5b74815cc7b62e06f139935007a0e780faf034dbe56bdcde
|
data/Gemfile.lock
CHANGED
data/LICENSE.txt
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 lulalala (mark@goodlife.tw)
|
4
|
+
|
5
|
+
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:
|
6
|
+
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
|
9
|
+
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.
|
data/README.md
CHANGED
@@ -1,13 +1,18 @@
|
|
1
1
|
# Settei
|
2
2
|
|
3
|
-
|
3
|
+
Config as YAML file yet still being 12-factor compliant...
|
4
4
|
|
5
|
-
|
5
|
+
...by serializing the file as one environment variable.
|
6
|
+
|
7
|
+
![Settei Illustrated](misc/illustrated.png?raw=true "Settei Illustrated")
|
8
|
+
|
9
|
+
## Features
|
10
|
+
|
11
|
+
* Can be read without loading Rails
|
12
|
+
* Variable namespacing using nested hash
|
13
|
+
* Follows 12-factor [rule 3](https://12factor.net/config) - store config in the environment
|
14
|
+
* Customizable due to loosely coupled PORO parts
|
6
15
|
|
7
|
-
* Fast as it is accessible without loading Rails
|
8
|
-
* Ease of management as nested hash is allowed
|
9
|
-
* 12-factor compatible by serializing as environment variable.
|
10
|
-
* Minimal meta-programming magics, so you can add your flavor of magic.
|
11
16
|
|
12
17
|
## Installation
|
13
18
|
|
@@ -21,56 +26,151 @@ And then execute:
|
|
21
26
|
|
22
27
|
$ bundle
|
23
28
|
|
24
|
-
|
29
|
+
For Rails, execute this rake task for out-of-the-box setup:
|
25
30
|
|
26
|
-
$
|
31
|
+
$ rake settei:install:rails
|
32
|
+
|
33
|
+
This task does the following things:
|
34
|
+
|
35
|
+
* create `config/setting.rb` for setting up `Setting`.
|
36
|
+
* require the above in `config/application.rb`
|
37
|
+
* create YAML files `config/environments/default.yml` and `config/environments/production.yml`
|
38
|
+
* make git ignore YAML files above
|
39
|
+
* append script to `deploy.rb` so config is passed via env var to production
|
27
40
|
|
28
41
|
## Usage
|
29
42
|
|
30
|
-
|
43
|
+
If `config/environments/default.yml` contains the following:
|
31
44
|
|
32
|
-
|
45
|
+
```yaml
|
46
|
+
the_answer_to_life_the_universe_and_everything: 42
|
47
|
+
google:
|
48
|
+
api: foo
|
49
|
+
```
|
50
|
+
|
51
|
+
Then you can access those like this:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
Setting.dig(:the_answer_to_life_the_universe_and_everything)
|
55
|
+
Setting.dig(:google, :api)
|
56
|
+
```
|
57
|
+
|
58
|
+
`#dig` is used to access its values. It's convenient because it does not err if nested hash is absent.
|
59
|
+
|
60
|
+
`#dig_and_wrap` will return a `Settei::Base` if it the return value is a hash.
|
61
|
+
|
62
|
+
For other available methods, [check here](http://www.rubydoc.info/github/lulalala/settei/master/Settei/Base).
|
63
|
+
|
64
|
+
If you have `development.yml` or `test.yml`, it will be loaded instead of `default.yml`.
|
65
|
+
|
66
|
+
### Deploy
|
67
|
+
|
68
|
+
If you use Capistrano or Mina, the `deploy.rb` is modified so deploy process will serialize `production.yml` into one long string, and pass it to remote server as **a single environment variable**. There it is de-serialized and loaded, and the rest works the same way.
|
69
|
+
|
70
|
+
If you use Heroku, use `rake settei:heroku:config:set app=[app_name]` to upload your config. You need heroku-cli and authenticate first.
|
71
|
+
|
72
|
+
## Why
|
73
|
+
|
74
|
+
Most config gems have not been updated for ages, and do not meet my needs:
|
75
|
+
|
76
|
+
I want to be 12-factor compliant, but I also hate using environment variables. See the following example: naming is hard and names tend to be very long. Passing more env vars also becomes more impractical.
|
77
|
+
|
78
|
+
```
|
79
|
+
BOARD_PAGINATION_PER_PAGE=5
|
80
|
+
BOARD_PAGINATION_MAX_PAGE=10
|
81
|
+
BOARD_REPLY_OMIT_CONDITION_N_RECENT_ONLY=5
|
82
|
+
BOARD_REPLY_OMIT_CONDITION_AVOID_ONLY_N_HIDDEN=2
|
83
|
+
```
|
33
84
|
|
34
|
-
|
35
|
-
|
36
|
-
YAML files are added under `config/environments` and is ignored by git.
|
85
|
+
In comparison YAML allows nested hash, so we can manage them using namespaces.
|
37
86
|
|
38
|
-
|
87
|
+
```yaml
|
88
|
+
board:
|
89
|
+
pagination:
|
90
|
+
per_page: 5
|
91
|
+
max_page: 10
|
92
|
+
reply_omit_condition:
|
93
|
+
n_recent_only: 5
|
94
|
+
avoid_only_n_hidden: 2
|
95
|
+
```
|
96
|
+
|
97
|
+
Can I have the benefit of env var (12-factor) and benefit of YAML (ease of variable mangement) at the same time?
|
98
|
+
|
99
|
+
Yes, if settings are stored in YAML files, but during deploy, transfer the whole YAML **file** as one env var.
|
100
|
+
|
101
|
+
I feel it is simpler and more effective.
|
102
|
+
|
103
|
+
## Tips
|
104
|
+
|
105
|
+
Rails `secrets.yml` and `credentials.yml.enc` are needlessly complex, and now we are able to ignore them:
|
106
|
+
|
107
|
+
Do away with Rails 4.1 secret.yml with something like this:
|
108
|
+
```ruby
|
109
|
+
# secret_token.rb
|
110
|
+
Foo::Application.config.secret_token = Setting.dig(:rails, :secret_token)
|
111
|
+
Foo::Application.config.secret_key_base = Setting.dig(:rails, :secret_key_base)
|
112
|
+
```
|
113
|
+
|
114
|
+
Similarly with Rails 5.2's credentials:
|
39
115
|
|
40
116
|
```ruby
|
41
|
-
|
117
|
+
# application.rb
|
118
|
+
config.secret_token = Setting.dig(:rails, :secret_token)
|
119
|
+
config.secret_key_base = Setting.dig(:rails, :secret_key_base)
|
42
120
|
```
|
43
121
|
|
44
|
-
|
122
|
+
Maybe we can get rid of `database.yml` one day too.
|
45
123
|
|
46
|
-
|
124
|
+
## Customization
|
47
125
|
|
48
|
-
|
126
|
+
The default setup is probably good enough for 90% of the users. However if you have advance requirements, you can easily customize.
|
49
127
|
|
50
|
-
|
128
|
+
One can start by editing the generated `setting.rb` file. The three parts are `Settei::Base`, loader and deploy script:
|
129
|
+
|
130
|
+
### Settei::Base
|
131
|
+
|
132
|
+
`Setting` is an instance of `Settei::Base`, the accessor of the configurations. It is initialized by a hash.
|
51
133
|
|
52
|
-
|
134
|
+
You can change `Setting` to other constants or a global variable.
|
53
135
|
|
54
|
-
|
136
|
+
You can also extend or replace `Settei::Base` with your own class, or you can just use the hash without any wrapper.
|
137
|
+
|
138
|
+
**Note** For Ruby < 2.3, `Hash#dig` is not available. What you can do is to replace `Settei::Base` with your own class, or even use `SettingsLogic.new(hash)`.
|
55
139
|
|
56
140
|
### Loader
|
57
141
|
|
58
|
-
|
142
|
+
Loaders are responsible for returning the configuration as hash, used to initialize `Settei::Base`.
|
143
|
+
|
144
|
+
`Settei::Loaders::SimpleLoader` is one type of loader. It loads from YAML or environment variable.
|
145
|
+
|
146
|
+
When initializing it, you can set:
|
147
|
+
|
148
|
+
* `dir`: the full path to directory containing YAML files
|
149
|
+
* `env_name`: the environment variable name; defaults to APP_CONFIG
|
59
150
|
|
60
151
|
```ruby
|
61
152
|
loader = Settei::Loaders::SimpleLoader.new(dir: 'path/to/dir')
|
153
|
+
```
|
154
|
+
|
155
|
+
To load data, call `load(Rails.env)`. In development environment, it tries to load `development.yml` if it exists, else it loads `default.yml`.
|
156
|
+
|
157
|
+
Once data is loaded, we can obtain it in hash form by calling `as_hash`
|
158
|
+
|
159
|
+
The deploy script also relies on loader's ability to serialize the whole hash into one string, suitable for deploying as environment variable. The methods `as_env_assignment` and `as_env_value` are provided for this purpose, e.g.:
|
160
|
+
|
161
|
+
```ruby
|
62
162
|
loader.load.as_hash # loads default.yml and returns a hash
|
63
163
|
loader.load(:production).as_env_value # loads production.yml and returns "XYZ"
|
64
164
|
loader.load(:test).as_env_assignment # loads test.yml and returns "APP_CONG=XYZ"
|
65
165
|
```
|
66
166
|
|
67
|
-
|
167
|
+
But no one is stopping you from writing your own loader. For example you might want the loader to encrypt/decrypt ENV value, or you may want to load from .env file.
|
68
168
|
|
69
|
-
For
|
169
|
+
For more detailed doc of `SimpleLoader`, [check here](http://www.rubydoc.info/github/lulalala/settei/master/Settei/Loaders/SimpleLoader).
|
70
170
|
|
71
|
-
###
|
171
|
+
### Deploy script
|
72
172
|
|
73
|
-
If
|
173
|
+
If you have more complex deploy requirements, just edit/revert the changes on `deploy.rb`.
|
74
174
|
|
75
175
|
### Frameworks other than Rails
|
76
176
|
|
@@ -79,23 +179,22 @@ Settei is designed to be simple so you can integrate it into any frameworks easi
|
|
79
179
|
1. Designate a folder for storing YAML files.
|
80
180
|
2. Create a `setting.rb` file, in which `Settei::Base` is initialized (see `templates/setting.rb`)
|
81
181
|
3. Require it when framework starts.
|
82
|
-
4. Load
|
83
|
-
|
84
|
-
We also welcome PRs for generators of other frameworks too.
|
85
|
-
|
86
|
-
## Ruby < 2.3
|
87
|
-
|
88
|
-
`Settei::Base` uses `dig` to access the configuration, available since Ruby 2.3. If your Ruby is not new enough, don't be afraid. Write your own hash accessor literally takes minutes. You can even use `SettingsLogic.new(hash)` .
|
182
|
+
4. Load production.yml, pass its serialized form as environment variable to production (see `templates/_capistrano.rb` or `templates/_mina.rb`).
|
89
183
|
|
90
184
|
## FAQ
|
91
185
|
|
92
186
|
**Q:** Would serialized configuration be too big for environment variable?
|
93
187
|
**A:** [The upper limit is pretty big.](https://stackoverflow.com/a/1078125/474597)
|
94
188
|
|
189
|
+
## Contribution
|
95
190
|
|
96
|
-
|
191
|
+
The slogan "YAML config yet still 12-factor compliant" is not entirely correct. Why not load from TOML or .env? If there is a need we can accommodate for that.
|
97
192
|
|
98
|
-
|
99
|
-
* Explore deep merge hash so development.yml can combine with default.yml.
|
100
|
-
* Make loader configurable so it is easy to add and mix functionality.
|
193
|
+
PRs are welcomed. Some ideas are:
|
101
194
|
|
195
|
+
* generators for other frameworks
|
196
|
+
* loader or its plugins
|
197
|
+
* plugin for `Settei::Base`
|
198
|
+
* explore deep merge hash so development.yml can combine with default.yml.
|
199
|
+
* make loader configurable so it is easy to add and mix functionality.
|
200
|
+
* rake task for heroku setup
|
data/lib/settei.rb
CHANGED
data/lib/settei/version.rb
CHANGED
data/lib/tasks/settei_tasks.rake
CHANGED
@@ -1,11 +1,27 @@
|
|
1
1
|
require 'rake'
|
2
|
-
require 'settei/generators/rails'
|
3
2
|
|
4
3
|
namespace :settei do
|
5
4
|
namespace :install do
|
6
5
|
desc "Setup settei for Rails project"
|
7
6
|
task :rails do
|
7
|
+
require 'settei/generators/rails'
|
8
8
|
Settei::Generators::Rails.new(app_path: Dir.pwd).run
|
9
9
|
end
|
10
10
|
end
|
11
|
+
|
12
|
+
namespace :heroku do
|
13
|
+
namespace :config do
|
14
|
+
desc "Update environment variable on Heroku"
|
15
|
+
task :set do
|
16
|
+
require 'settei/loaders/simple_loader'
|
17
|
+
dir = File.join(Dir.pwd, 'config', 'environments')
|
18
|
+
loader = Settei::Loaders::SimpleLoader.new(dir: dir)
|
19
|
+
loader.load(:production)
|
20
|
+
|
21
|
+
sh %{
|
22
|
+
heroku config:set #{loader.as_env_assignment} --app #{ENV['app']}
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
11
27
|
end
|
Binary file
|
data/settei.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ["lulalala"]
|
9
9
|
spec.email = ["mark@goodlife.tw"]
|
10
10
|
|
11
|
-
spec.summary = %q{
|
12
|
-
spec.description = %q{
|
11
|
+
spec.summary = %q{Config as YAML yet still 12-factor compliant}
|
12
|
+
spec.description = %q{Config as YAML yet still being 12-factor compliant, by serializing the file as one environment variable.}
|
13
13
|
spec.homepage = "https://github.com/lulalala/settei"
|
14
14
|
spec.licenses = ['MIT']
|
15
15
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: settei
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- lulalala
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-03-
|
11
|
+
date: 2018-03-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,9 +66,8 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
description:
|
70
|
-
|
71
|
-
variable, suitable for 12-factor app.
|
69
|
+
description: Config as YAML yet still being 12-factor compliant, by serializing the
|
70
|
+
file as one environment variable.
|
72
71
|
email:
|
73
72
|
- mark@goodlife.tw
|
74
73
|
executables: []
|
@@ -80,6 +79,7 @@ files:
|
|
80
79
|
- ".yardopts"
|
81
80
|
- Gemfile
|
82
81
|
- Gemfile.lock
|
82
|
+
- LICENSE.txt
|
83
83
|
- README.md
|
84
84
|
- Rakefile
|
85
85
|
- bin/console
|
@@ -92,6 +92,7 @@ files:
|
|
92
92
|
- lib/settei/railtie.rb
|
93
93
|
- lib/settei/version.rb
|
94
94
|
- lib/tasks/settei_tasks.rake
|
95
|
+
- misc/illustrated.png
|
95
96
|
- settei.gemspec
|
96
97
|
- templates/_capistrano.rb
|
97
98
|
- templates/_mina.rb
|
@@ -120,5 +121,5 @@ rubyforge_project:
|
|
120
121
|
rubygems_version: 2.6.13
|
121
122
|
signing_key:
|
122
123
|
specification_version: 4
|
123
|
-
summary:
|
124
|
+
summary: Config as YAML yet still 12-factor compliant
|
124
125
|
test_files: []
|