anyway_config 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +36 -0
- data/.travis.yml +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +84 -0
- data/Rakefile +6 -0
- data/anyway_config.gemspec +27 -0
- data/gemfiles/rails40.gemfile +7 -0
- data/gemfiles/rails41.gemfile +7 -0
- data/gemfiles/rails42.gemfile +7 -0
- data/lib/anyway.rb +10 -0
- data/lib/anyway/config.rb +64 -0
- data/lib/anyway/env.rb +59 -0
- data/lib/anyway/version.rb +3 -0
- data/spec/config_spec.rb +99 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +22 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/cool.yml +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +83 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +56 -0
- data/spec/dummy/config/secrets.yml +26 -0
- data/spec/dummy/db/migrate/20140730133818_add_testos.rb +11 -0
- data/spec/dummy/db/migrate/20140731162044_add_column_to_testos.rb +5 -0
- data/spec/dummy/db/schema.rb +22 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/env_spec.rb +21 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/support/cool_config.rb +4 -0
- data/spec/support/test_config.rb +5 -0
- metadata +204 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c681a4243d4852f2ef8383624c6d2a8f1578b3a0
|
4
|
+
data.tar.gz: 4719dd86c4d8f21e55712861be1fd9c7e2691b57
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 592cc0e754e5cd9568102b2bcd8e142c86c3b769bd262f0dfb3afc24ed853ca2ce70f854cf9e19fe7f7f980cb1bd761c68997b658f58cbb20c8f6794430b3777
|
7
|
+
data.tar.gz: 26524cbd6a105d6d59a5775e06b8324f665d2428df3a3129531a63b91894c97c93362997154c60cbdf9c119467600600f9fdd2b21b41ec243a0ef79470a8c5eb
|
data/.gitignore
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# Numerous always-ignore extensions
|
2
|
+
*.diff
|
3
|
+
*.err
|
4
|
+
*.orig
|
5
|
+
*.log
|
6
|
+
*.rej
|
7
|
+
*.swo
|
8
|
+
*.swp
|
9
|
+
*.vi
|
10
|
+
*~
|
11
|
+
*.sass-cache
|
12
|
+
*.iml
|
13
|
+
.idea/
|
14
|
+
|
15
|
+
# Sublime
|
16
|
+
*.sublime-project
|
17
|
+
*.sublime-workspace
|
18
|
+
|
19
|
+
# OS or Editor folders
|
20
|
+
.DS_Store
|
21
|
+
.cache
|
22
|
+
.project
|
23
|
+
.settings
|
24
|
+
.tmproj
|
25
|
+
Thumbs.db
|
26
|
+
|
27
|
+
.bundle/
|
28
|
+
log/*.log
|
29
|
+
pkg/
|
30
|
+
spec/dummy/db/*.sqlite3
|
31
|
+
spec/dummy/db/*.sqlite3-journal
|
32
|
+
spec/dummy/tmp/
|
33
|
+
|
34
|
+
Gemfile.lock
|
35
|
+
.rspec
|
36
|
+
*.gem
|
data/.travis.yml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
language: ruby
|
2
|
+
cache: bundler
|
3
|
+
rvm:
|
4
|
+
- 2.0.0
|
5
|
+
- 2.1
|
6
|
+
|
7
|
+
gemfile:
|
8
|
+
- Gemfile
|
9
|
+
|
10
|
+
matrix:
|
11
|
+
include:
|
12
|
+
- rvm: 2.0.0
|
13
|
+
gemfile: gemfiles/rails40.gemfile
|
14
|
+
|
15
|
+
- rvm: 2.1
|
16
|
+
gemfile: gemfiles/rails40.gemfile
|
17
|
+
|
18
|
+
- rvm: 2.1
|
19
|
+
gemfile: gemfiles/rails41.gemfile
|
20
|
+
|
21
|
+
- rvm: 2.1
|
22
|
+
gemfile: gemfiles/rails42.gemfile
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 palkan
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/palkan/anyway_config.svg?branch=master)](https://travis-ci.org/palkan/anyway_config)
|
2
|
+
|
3
|
+
# Anyway Config
|
4
|
+
|
5
|
+
Rails plugin configuration using any source: YAML, _secrets_, environment.
|
6
|
+
|
7
|
+
Requires Rails 4.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Configure your gemspec
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
Gem::Specification.new do |s|
|
15
|
+
...
|
16
|
+
s.add_dependancy 'anyway_config', "~>0.1"
|
17
|
+
...
|
18
|
+
end
|
19
|
+
```
|
20
|
+
|
21
|
+
And then execute:
|
22
|
+
|
23
|
+
$ bundle
|
24
|
+
|
25
|
+
Or install it yourself as:
|
26
|
+
|
27
|
+
$ gem install anyway_config
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
### Basic
|
32
|
+
|
33
|
+
Create configuration class:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
module MyCoolGem
|
37
|
+
class Config < Anyway::Config
|
38
|
+
attr_config user: 'root', password: 'root', host: 'localhost'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
`attr_config` creates accessors and default values. If you don't need default values just write:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
attr_config :user, :password, host: 'localhost'
|
47
|
+
```
|
48
|
+
|
49
|
+
Your config will be filled up with values from `RAILS_ROOT/config/my_cool_gem.yml`, `Rails.application.secrets.my_cool_gem` (if using Rails) and `ENV['MYCOOLGEM_*']`.
|
50
|
+
|
51
|
+
### Customize name
|
52
|
+
|
53
|
+
If you want to load config params from, for example, "cool.yml" (secrets, env), just add one line:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
module MyCoolGem
|
57
|
+
class Config < Anyway::Config
|
58
|
+
config_name :cool
|
59
|
+
attr_config user: 'root', password: 'root', host: 'localhost', options: {}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
### How to set env vars
|
65
|
+
|
66
|
+
Environmental variables for your config should start with your module name (or config name if any), uppercased and underscore-free.
|
67
|
+
|
68
|
+
For example, if your module is called "MyCoolGem" then your env var "MYCOOLGEM_PASSWORD" is used as `config.password`.
|
69
|
+
|
70
|
+
*Anyway Config* supports nested (_hashed_) environmental variables. Just separate keys with double-underscore.
|
71
|
+
For example, "MYCOOLGEM_OPTIONS__VERBOSE" is transformed to `config.options.verbose`.
|
72
|
+
|
73
|
+
|
74
|
+
### Config clear and reload
|
75
|
+
|
76
|
+
You can use `clear` and `reload` functions on your config (which do exactly what they state).
|
77
|
+
|
78
|
+
## Contributing
|
79
|
+
|
80
|
+
1. Fork it
|
81
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
82
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
83
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
84
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'anyway/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "anyway_config"
|
8
|
+
s.version = Anyway::VERSION
|
9
|
+
s.authors = ["Vlad Dem"]
|
10
|
+
s.email = ["dementiev.vm@gmail.com"]
|
11
|
+
s.homepage = "http://github.com/palkan/anyway_config"
|
12
|
+
s.summary = "Configuration for Rails plugins"
|
13
|
+
s.description = "Configuration for Rails plugins"
|
14
|
+
s.license = "MIT"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split($/)
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.add_dependency 'rails', "~>4"
|
20
|
+
|
21
|
+
s.add_development_dependency 'sqlite3'
|
22
|
+
s.add_development_dependency 'pry'
|
23
|
+
s.add_development_dependency 'pry-byebug'
|
24
|
+
s.add_development_dependency "simplecov", ">= 0.3.8"
|
25
|
+
s.add_development_dependency "rspec", "~> 3.0.0"
|
26
|
+
s.add_development_dependency "rspec-rails", "~> 3.0.0"
|
27
|
+
end
|
data/lib/anyway.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
module Anyway
|
2
|
+
class Config
|
3
|
+
class << self
|
4
|
+
attr_reader :defaults, :config_attributes
|
5
|
+
|
6
|
+
def attr_config(*args,**hargs)
|
7
|
+
@defaults = hargs.dup.with_indifferent_access
|
8
|
+
@config_attributes = args+hargs.keys
|
9
|
+
attr_accessor *@config_attributes
|
10
|
+
end
|
11
|
+
|
12
|
+
def config_name(val = nil)
|
13
|
+
return (@config_name = val.to_s) unless val.nil?
|
14
|
+
@config_name ||= extract_name
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def extract_name
|
19
|
+
self.name[/^(\w+)/].underscore
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
load
|
25
|
+
end
|
26
|
+
|
27
|
+
def reload
|
28
|
+
clear
|
29
|
+
load
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def clear
|
34
|
+
self.class.config_attributes.each do |attr|
|
35
|
+
self.send("#{attr}=", nil)
|
36
|
+
end
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def load
|
41
|
+
# first, copy defaults
|
42
|
+
config = self.class.defaults.deep_dup
|
43
|
+
config_name = self.class.config_name
|
44
|
+
|
45
|
+
# then load from YAML if any
|
46
|
+
config_path = Rails.root.join("config","#{config_name}.yml")
|
47
|
+
if File.file? config_path
|
48
|
+
config.deep_merge! (YAML.load_file(config_path)[Rails.env] || {})
|
49
|
+
end
|
50
|
+
|
51
|
+
# then load from Rails secrets
|
52
|
+
unless Rails.application.try(:secrets).nil?
|
53
|
+
config.deep_merge! (Rails.application.secrets.send(config_name)||{})
|
54
|
+
end
|
55
|
+
|
56
|
+
# and then load from env
|
57
|
+
config.deep_merge! (Anyway.env.send(config_name) || {})
|
58
|
+
|
59
|
+
config.each do |key, val|
|
60
|
+
self.send("#{key}=",val)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/anyway/env.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
module Anyway
|
2
|
+
class Env
|
3
|
+
def initialize
|
4
|
+
@data = {}
|
5
|
+
load
|
6
|
+
end
|
7
|
+
|
8
|
+
def reload
|
9
|
+
clear
|
10
|
+
load
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
def clear
|
15
|
+
@data.clear
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def method_missing(meth, *args, &block)
|
20
|
+
meth = meth.to_s.gsub(/\_/,'')
|
21
|
+
if args.empty? and @data.key?(meth)
|
22
|
+
@data[meth]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def load
|
28
|
+
ENV.each_pair do |key, val|
|
29
|
+
if config_key?(key)
|
30
|
+
mod, path = extract_module_path(key)
|
31
|
+
set_by_path(get_hash(@data, mod), path, val)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def config_key?(key)
|
37
|
+
key =~ /^[A-Z\d]+\_[A-Z\d\_]+/
|
38
|
+
end
|
39
|
+
|
40
|
+
def extract_module_path(key)
|
41
|
+
_, mod, path = key.split(/^([^\_]+)/)
|
42
|
+
path.sub!(/^[\_]+/,'')
|
43
|
+
[mod.downcase, path.downcase]
|
44
|
+
end
|
45
|
+
|
46
|
+
def set_by_path(to, path, val)
|
47
|
+
parts = path.split("__")
|
48
|
+
|
49
|
+
while parts.length > 1
|
50
|
+
to = get_hash(to, parts.shift)
|
51
|
+
end
|
52
|
+
to[parts.first] = val
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_hash(from, name)
|
56
|
+
(from[name] ||= {}.with_indifferent_access)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Anyway::Config do
|
4
|
+
let(:conf) { CoolConfig.new }
|
5
|
+
let(:test_conf) { Anyway::TestConfig.new }
|
6
|
+
|
7
|
+
describe "config with name" do
|
8
|
+
specify { expect(CoolConfig.config_name).to eq "cool" }
|
9
|
+
|
10
|
+
describe "defaults" do
|
11
|
+
specify { expect(CoolConfig.defaults[:port]).to eq 8080 }
|
12
|
+
specify { expect(CoolConfig.defaults[:host]).to eq 'localhost' }
|
13
|
+
end
|
14
|
+
|
15
|
+
specify do
|
16
|
+
expect(conf).to respond_to(:meta)
|
17
|
+
expect(conf).to respond_to(:data)
|
18
|
+
expect(conf).to respond_to(:port)
|
19
|
+
expect(conf).to respond_to(:host)
|
20
|
+
expect(conf).to respond_to(:user)
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "load from files" do
|
24
|
+
it "should set defauls" do
|
25
|
+
expect(conf.port).to eq 8080
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should load config from YAML" do
|
29
|
+
expect(conf.host).to eq "test.host"
|
30
|
+
end
|
31
|
+
|
32
|
+
unless Rails.application.try(:secrets).nil?
|
33
|
+
it "should load config from secrets" do
|
34
|
+
expect(conf.user[:name]).to eq "test"
|
35
|
+
expect(conf.user[:password]).to eq "test"
|
36
|
+
end
|
37
|
+
else
|
38
|
+
it "should load config from file if no secrets" do
|
39
|
+
expect(conf.user[:name]).to eq "root"
|
40
|
+
expect(conf.user[:password]).to eq "root"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "load from env" do
|
46
|
+
after(:each) { Anyway.env.clear }
|
47
|
+
it "should work" do
|
48
|
+
ENV['COOL_PORT'] = '80'
|
49
|
+
ENV['COOL_USER__NAME'] = 'john'
|
50
|
+
Anyway.env.reload
|
51
|
+
expect(conf.port).to eq '80'
|
52
|
+
expect(conf.user[:name]).to eq 'john'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "clear" do
|
57
|
+
let(:conf_cleared) { conf.clear }
|
58
|
+
|
59
|
+
specify do
|
60
|
+
expect(conf_cleared.meta).to be_nil
|
61
|
+
expect(conf_cleared.data).to be_nil
|
62
|
+
expect(conf_cleared.host).to be_nil
|
63
|
+
expect(conf_cleared.user).to be_nil
|
64
|
+
expect(conf_cleared.port).to be_nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "reload" do
|
69
|
+
after(:each) { Anyway.env.clear }
|
70
|
+
it do
|
71
|
+
expect(conf.port).to eq 8080
|
72
|
+
ENV['COOL_PORT'] = '80'
|
73
|
+
ENV['COOL_USER__NAME'] = 'john'
|
74
|
+
Anyway.env.reload
|
75
|
+
conf.reload
|
76
|
+
expect(conf.port).to eq '80'
|
77
|
+
expect(conf.user[:name]).to eq 'john'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "config with default name" do
|
83
|
+
after(:each) { Anyway.env.clear }
|
84
|
+
specify { expect(Anyway::TestConfig.config_name).to eq "anyway" }
|
85
|
+
|
86
|
+
specify do
|
87
|
+
expect(test_conf).to respond_to(:test)
|
88
|
+
expect(test_conf).to respond_to(:api)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should work" do
|
92
|
+
ENV['ANYWAY_API__KEY'] = 'test1'
|
93
|
+
ENV['ANYWAY_TEST'] = 'test'
|
94
|
+
Anyway.env.reload
|
95
|
+
expect(test_conf.api[:key]).to eq "test1"
|
96
|
+
expect(test_conf.test).to eq "test"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|