config_for 0.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0fc8f929db5b50524c698fb943e5446e8f8d2ed9
4
+ data.tar.gz: e9a2a724817253874d80b587ff1a8c135e110002
5
+ SHA512:
6
+ metadata.gz: 1f712133ad38f13065e5d6ce340af6da380f09f5cc53c6171ff9c65ebd5068b760b6b3ed9b86530291dbfde3f11adb87f115bb9ac45e30c78a47dc1f00e428d2
7
+ data.tar.gz: 52acce1e49b443dbd0c3fd3a8c4da3109f16ac7d26de80291c05b9a80989544d3f9f509d1838449dbc82c48a995482df28330dcd3ced498796c0c76c79595d9a
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /gemfiles/*.gemfile.lock
11
+ *.bundle
12
+ *.so
13
+ *.o
14
+ *.a
15
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ gemfile:
3
+ - gemfiles/rails_3.gemfile
4
+ - gemfiles/rails_4.gemfile
5
+ - gemfiles/rails_4_1.gemfile
6
+ rvm:
7
+ - 2.1.3
8
+ - 2.1.2
9
+ - 2.0.0
10
+ - 1.9.3
data/Appraisals ADDED
@@ -0,0 +1,11 @@
1
+ appraise 'rails-3' do
2
+ gem 'rails', '~> 3.2.14'
3
+ end
4
+
5
+ appraise 'rails-4' do
6
+ gem 'rails', '~> 4.0.0'
7
+ end
8
+
9
+ appraise 'rails-4-1' do
10
+ gem 'rails', '~> 4.1.0'
11
+ end
data/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ ## master - unreleased
5
+ <!-- ## 0.1.0 - 2014-10-02 -->
6
+
7
+ ### Added
8
+ - Rails integration
9
+ - Sinatra Integration
10
+ - Capistrano Integration
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in config_for.gemspec
4
+ gemspec
5
+
6
+ gem 'appraisal'
7
+
8
+ platforms :mri_20, :mri_21 do
9
+ gem 'pry-byebug'
10
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Michal Cichra
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,117 @@
1
+ # ConfigFor [![Build Status](https://travis-ci.org/3scale/config_for.svg?branch=master)](https://travis-ci.org/3scale/config_for)
2
+
3
+ Framework for generating, uploading and loading config files in Ruby apps.
4
+
5
+ It offers integrations with Rails and Sinatra.
6
+
7
+ For generating and uploading configs it uses Capistrano task.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'config_for'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install config_for
24
+
25
+ ## Compatibility
26
+
27
+ Tested against Ruby 1.9.3, 2.0.0, 2.1.2, 2.1.3.
28
+ Also against 3 versions of rails: 3.2, 4.0 and 4.1.
29
+
30
+ Capistrano `>= 3.0` is required as well as Sinatra `>= 1.4`.
31
+
32
+ ## Usage
33
+
34
+ ConfigFor will automatically load correct integrations for Rails/Sinatra/Capistrano
35
+ when required. If it does not happen automatically, you can include them by hand:
36
+
37
+ ```ruby
38
+ require 'config_for/rails'
39
+ require 'config_for/sinatra'
40
+ require 'config_for/capistrano'
41
+ ```
42
+
43
+ ### Rails
44
+
45
+ Rails 4.2 and up provide `config_for` method on `Rails.application`.
46
+ ConfigFor backports this for Rails `> 3.0` and `< 4.2`.
47
+
48
+ So you can use:
49
+
50
+ ```ruby
51
+ # config/production.rb
52
+ Rails.application.configure do
53
+ config.redis = config_for(:redis) # will load config/redis.yml and get key 'production'
54
+ end
55
+ ```
56
+
57
+ ### Sinatra
58
+
59
+ Sinatra has no default way of loading configs, so ConfigFor follows the same as Rails.
60
+ After loading the integration, Sinatra Classic apps will have the plugin loaded automatically,
61
+ but Sinatra Modular apps have to register it by hand.
62
+
63
+ ```ruby
64
+ class MyApp < Sinatra::Base
65
+ register ConfigFor::Sinatra
66
+
67
+ # loads root + 'config/redis.yml' and gets key of correct 'environment'
68
+ set :redis, Redis.new(config_for(:redis))
69
+ end
70
+ ```
71
+
72
+ ### Capistrano
73
+
74
+ Capistrano is used to deploy the config to servers. ConfigFor provides task generator
75
+ for various configs. First you have to load it:
76
+
77
+ ```ruby
78
+ # Capfile
79
+ require 'config_for/capistrano'
80
+ ```
81
+
82
+ Then you can use it like:
83
+
84
+ ```ruby
85
+ set :database_yml, {
86
+ production: {
87
+ host: 'localhost',
88
+ port: 3306
89
+ }
90
+ }
91
+ ConfigFor::Capistrano::Task.new(:database)
92
+ ```
93
+
94
+ Which will generate following tasks:
95
+
96
+ ```shell
97
+ cap database # Generate config/database.yml
98
+ cap database:remove # Remove config/database.yml from current and shared path
99
+ cap database:reset # Reset database config
100
+ cap database:upload # Upload config/database.yml to remote servers
101
+ ```
102
+
103
+ Also it add hook to run `database` task before `deploy:check:linked_files`.
104
+ So the last think you have to do is add `config/database.yml` to `linked_files` variable like:
105
+
106
+ ```ruby
107
+ set :linked_files, %w[ config/database.yml ]
108
+ ```
109
+
110
+ ## Contributing
111
+
112
+ 1. Fork it ( https://github.com/3scale/config_for/fork )
113
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
114
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
115
+ 3. Run tests (`bundle exec rake`)
116
+ 4. Push to the branch (`git push origin my-new-feature`)
117
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ task default: :spec
7
+ rescue LoadError
8
+ end
9
+
10
+ begin
11
+ require 'appraisal'
12
+ rescue LoadError
13
+ end
14
+
15
+ begin
16
+ require 'config_for'
17
+ require 'pry'
18
+
19
+ task :console do
20
+ Pry.toplevel_binding.pry
21
+ end
22
+ rescue LoadError
23
+ end
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'config_for/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'config_for'
8
+ spec.version = ConfigFor::VERSION
9
+ spec.authors = ['Michal Cichra']
10
+ spec.email = ['michal@3scale.net']
11
+ spec.summary = %q{Provides YAML tools for app configuration.}
12
+ spec.description = %q{Simplifies YAML parsing in Sinatra and Rails applications. Provides tools to generate configs by capistrano.}
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z 2> /dev/null`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '>= 1.6'
22
+ spec.add_development_dependency 'rake', '~> 10.0'
23
+
24
+ spec.add_development_dependency 'rails', '>= 3.0', '< 4.2'
25
+ spec.add_development_dependency 'sinatra', '>= 1.4.0'
26
+ spec.add_development_dependency 'capistrano', '>= 3.0'
27
+
28
+ spec.add_development_dependency 'rspec', '~> 3.1'
29
+ spec.add_development_dependency 'memfs'
30
+ spec.add_development_dependency 'yard'
31
+
32
+ # Sorry, but it has HashWithIndifferentAccess and symbolize_keys
33
+ spec.add_dependency 'activesupport', '>= 3.0'
34
+ end
@@ -0,0 +1,12 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "rails", "~> 3.2.14"
7
+
8
+ platforms :mri_20, :mri_21 do
9
+ gem "pry-byebug"
10
+ end
11
+
12
+ gemspec :path => "../"
@@ -0,0 +1,12 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "rails", "~> 4.0.0"
7
+
8
+ platforms :mri_20, :mri_21 do
9
+ gem "pry-byebug"
10
+ end
11
+
12
+ gemspec :path => "../"
@@ -0,0 +1,12 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "rails", "~> 4.1.0"
7
+
8
+ platforms :mri_20, :mri_21 do
9
+ gem "pry-byebug"
10
+ end
11
+
12
+ gemspec :path => "../"
data/lib/config_for.rb ADDED
@@ -0,0 +1,55 @@
1
+ require 'config_for/version'
2
+ require 'pathname'
3
+
4
+ require 'yaml'
5
+ require 'erb'
6
+ require 'active_support/hash_with_indifferent_access'
7
+
8
+ module ConfigFor
9
+ if defined?(::Rails)
10
+ require 'config_for/rails'
11
+ end
12
+
13
+ if defined?(::Sinatra)
14
+ require 'config_for/sinatra'
15
+ end
16
+
17
+ if defined?(::Capistrano)
18
+ require 'config_for/capistrano'
19
+ end
20
+
21
+ # inspired by https://github.com/rails/rails/commit/9629dea4fb15a948ab4394590fdd946bd9dd4f91
22
+
23
+ # Loads yaml file "#{{name}}.yml" from path and gets
24
+ #
25
+ # @param [Pathname, String] path partial of full path to folder with configs
26
+ # @param [String] name without extension
27
+ # @param [Symbol,String] env key to get from the config
28
+ # @return [ActiveSupport::HashWithIndifferentAccess] config file for given env
29
+ # @raise [RuntimeError] when file does not exist or can't be parsed
30
+ # @example Load config in rails
31
+ # ConfigFor.load_config(Rails.root.join('config'), 'redis', Rails.env)
32
+ def self.load_config(path, name, env)
33
+ yaml = File.join(path, "#{name}.yml")
34
+
35
+ if File.exist?(yaml)
36
+ config = parse_yaml(yaml)[env]
37
+ ActiveSupport::HashWithIndifferentAccess.new(config)
38
+ else
39
+ raise "Could not load configuration. No such file - #{yaml}"
40
+ end
41
+ end
42
+
43
+ # Parse and process a yaml file through ERB
44
+
45
+ # @param [Pathname, String] full path to yaml file
46
+ # @return [Hash]
47
+ # @raise [RuntimeError] when file can't be parsed
48
+ def self.parse_yaml(file)
49
+ ::YAML.load(::ERB.new(File.read(file)).result) || {}
50
+ rescue ::Psych::SyntaxError => e
51
+ raise "YAML syntax error occurred while parsing #{file}. " \
52
+ "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
53
+ "Error: #{e.message}"
54
+ end
55
+ end
@@ -0,0 +1,161 @@
1
+ require 'rake/tasklib'
2
+ require 'pathname'
3
+ require 'tempfile'
4
+ require 'capistrano/dsl'
5
+ require 'active_support/core_ext/hash/keys'
6
+ require 'yaml'
7
+
8
+ module ConfigFor
9
+ module Capistrano
10
+
11
+ # inspired by https://github.com/rspec/rspec-core/blob/6b7f55e4fb36226cf830983aab8da8308f641708/lib/rspec/core/rake_task.rb
12
+
13
+ # Rake Task generator for generating and uploading config files through Capistrano.
14
+ # @example generating task for database.yml
15
+ # ConfigFor::Capistrano::Task.new(:database)
16
+ # @example changing the folder
17
+ # ConfigFor::Capistrano::Task.new(:database) { |task| task.folder = 'configuration' }
18
+ class Task < ::Rake::TaskLib
19
+ include ::Capistrano::DSL
20
+
21
+
22
+ # @!attribute name
23
+ # @return [String] the name of the task and subtasks namespace
24
+ attr_accessor :name
25
+
26
+ # @!attribute folder
27
+ # @return [String] folder to upload the generated config
28
+ attr_accessor :folder
29
+
30
+ # @!attribute tempfile
31
+ # @return [Tempfile] temporary file for generating the config before upload
32
+ attr_accessor :tempfile
33
+
34
+ # Generates new tasks with for uploading #name
35
+ # @param [String, Symbol] name name of this tasks and subtasks
36
+ # @param &block gets evaluated before defining the tasks
37
+ # @yieldparam [Task] task the task itself so you can modify it before it gets defined
38
+ def initialize(name, &block)
39
+ @name = name
40
+ @folder = 'config'
41
+ @file = "#{name}.yml"
42
+ @roles = :all
43
+ @tempfile = ::Tempfile.new(@file)
44
+ @variable = "#{name}_yml".to_sym
45
+
46
+ yield(self) if block_given?
47
+
48
+ desc "Generate #{name} uploader" unless ::Rake.application.last_comment
49
+ define
50
+ end
51
+
52
+
53
+ # Path where will be the file uploaded
54
+ # Is a join of #folder and #file
55
+ def path
56
+ ::File.join(@folder, @file)
57
+ end
58
+
59
+ # Invokes the task to do the upload
60
+ def run_task
61
+ invoke("#{name}:upload")
62
+ end
63
+
64
+ # Generated YAML content
65
+ # Gets the configuration from #variable, deep stringifies keys and returns YAML
66
+ # @return [String] serialized YAML
67
+ def yaml
68
+ config = fetch(@variable, {})
69
+ stringified = if config.respond_to?(:deep_stringify_keys)
70
+ config.deep_stringify_keys
71
+ else
72
+ # TODO: remove when dropping rails 3 support
73
+ # two level stringify for rails 3 compatability
74
+ config.stringify_keys.each_value(&:stringify_keys!)
75
+ end
76
+ stringified.to_yaml
77
+ end
78
+
79
+ private
80
+
81
+ def define
82
+ namespace name do
83
+ desc "Upload #{path} to remote servers"
84
+ task upload: path
85
+
86
+ desc "Remove #{path} from current and shared path"
87
+ task :remove do
88
+ files = []
89
+ files << shared_path.join(path)
90
+ files << current_path.join(path)
91
+
92
+ files.each do |file|
93
+ escaped = file.to_s.shellescape
94
+
95
+ on roles(@roles) do
96
+ if test "[ -e #{escaped} ]"
97
+ execute :rm, escaped
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ desc "Reset #{name} config"
104
+ task reset: [:remove, :upload]
105
+
106
+ task :generate do
107
+ @tempfile.write(yaml)
108
+ @tempfile.close(false)
109
+ end
110
+ end
111
+
112
+ remote_file path => @tempfile.path, roles: @roles
113
+ file @tempfile.path => "#{name}:generate"
114
+
115
+ desc "Generate #{path}"
116
+ task(name, &method(:run_task))
117
+
118
+ before 'deploy:check:linked_files', @name
119
+ end
120
+
121
+
122
+ private
123
+
124
+ # This reimplements Capistrano::DSL::TaskEnhancements#remote_file
125
+ # but uses UploadTask instead of Rake::Task
126
+
127
+ # TODO: can be removed when https://github.com/capistrano/capistrano/pull/1144
128
+ # is merged and released
129
+
130
+ def remote_file(task)
131
+ target_roles = task.delete(:roles)
132
+
133
+ UploadTask.define_task(task) do |t|
134
+ prerequisite_file = t.prerequisites.first
135
+ file = shared_path.join(t.name)
136
+
137
+ on roles(target_roles) do
138
+ unless test "[ -f #{file} ]"
139
+ info "Uploading #{prerequisite_file} to #{file}"
140
+ upload! File.open(prerequisite_file), file
141
+ end
142
+ end
143
+
144
+ end
145
+ end
146
+ end
147
+
148
+
149
+ private
150
+
151
+ # Inheriting from Rake::FileCreationTask because it does not scope
152
+ # task by namespace. Capistrano uses default Rake::Task which inside namespace produces:
153
+ # namespace:path/file.ext instead of just path/file.ext
154
+
155
+ class UploadTask < Rake::FileCreationTask
156
+ def needed?
157
+ true
158
+ end
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,19 @@
1
+ module ConfigFor
2
+ module Rails
3
+ # Convenience loading of config files
4
+ #
5
+ # @param [String, Symbol] name the config file to load
6
+ # @return [ActiveSupport::HashWithIndifferentAccess] loaded config file
7
+ # @example in config/production.rb
8
+ # Rails.application.configure do
9
+ # config.redis = config_for(:redis)
10
+ # end
11
+ def config_for(name)
12
+ ConfigFor.load_config(paths['config'].existent.first, name, ::Rails.env)
13
+ end
14
+ end
15
+ end
16
+
17
+ ::Rails::Application.class_eval do
18
+ include ConfigFor::Rails
19
+ end
@@ -0,0 +1,21 @@
1
+ module ConfigFor
2
+ module Sinatra
3
+
4
+ # Convenience loading of config files
5
+ #
6
+ # @param [String, Symbol] name the config file to load
7
+ # @return [ActiveSupport::HashWithIndifferentAccess] loaded config file for current environment
8
+ # @example
9
+ # class MyApp < Sinatra::Base
10
+ # register ConfigFor::Sinatra
11
+ #
12
+ # set :redis, Redis.new(config_for(:redis))
13
+ # end
14
+ def config_for(name)
15
+ config = File.join(settings.root, 'config')
16
+ ConfigFor.load_config(config, name, settings.environment)
17
+ end
18
+ end
19
+ end
20
+
21
+ Sinatra.register(ConfigFor::Sinatra)
@@ -0,0 +1,3 @@
1
+ module ConfigFor
2
+ VERSION = '0.1.0.pre1'
3
+ end
@@ -0,0 +1,102 @@
1
+ require 'config_for/capistrano'
2
+
3
+ RSpec.describe ConfigFor::Capistrano do
4
+
5
+ end
6
+
7
+ RSpec.describe ConfigFor::Capistrano::Task do
8
+ def invoke(task, *args)
9
+ rake_task(task).invoke(*args)
10
+ end
11
+
12
+ def rake_task(task)
13
+ Rake::Task[task]
14
+ end
15
+
16
+ before do
17
+ Rake.application = Rake::Application.new
18
+ Rake::Task.define_task('deploy:check:linked_files')
19
+ end
20
+
21
+ context 'database task' do
22
+ let!(:database_task) { described_class.new(:database) }
23
+ subject(:task) { database_task }
24
+
25
+ it { expect(task.path).to eq('config/database.yml') }
26
+
27
+ context 'with configuration' do
28
+ before{ stub_const('Capistrano::Configuration', configuration) }
29
+ let(:configuration) { double('configuration', env: env) }
30
+ let(:env) { { database_yml: database_configuration } }
31
+ let(:database_configuration) { { production: { host: 'localhost' } } }
32
+
33
+ it { expect(task.yaml).to eq("---\nproduction:\n host: localhost\n") }
34
+ end
35
+
36
+ let(:prerequisites) { subject.prerequisites }
37
+
38
+ context 'tempfile' do
39
+ subject { rake_task(task.tempfile.path) }
40
+ it { expect(prerequisites).to eq(['database:generate']) }
41
+ end
42
+
43
+ context 'remote_file' do
44
+ subject { rake_task('config/database.yml') }
45
+ it { expect(prerequisites).to eq([task.tempfile.path]) }
46
+ end
47
+
48
+ context 'upload' do
49
+ subject { rake_task('database:upload') }
50
+ it { expect(prerequisites).to eq(['config/database.yml']) }
51
+ end
52
+
53
+ context 'remove' do
54
+ subject { rake_task('database:remove') }
55
+ it { expect(prerequisites).to eq([]) }
56
+ end
57
+
58
+ context 'reset' do
59
+ subject { rake_task('database:reset') }
60
+ it { expect(prerequisites).to eq(%w[remove upload]) }
61
+ end
62
+ end
63
+
64
+ context 'task' do
65
+ it 'accepts block to change folder' do
66
+ task = described_class.new(:test) { |task| task.folder = 'other' }
67
+ expect(task.folder).to eq('other')
68
+ expect(rake_task('other/test.yml')).to be
69
+ end
70
+
71
+ it 'accepts block to change name' do
72
+ task = described_class.new(:test) { |task| task.name = 'other' }
73
+ expect(task.name).to eq('other')
74
+ expect(rake_task('other')).to be
75
+ end
76
+ end
77
+
78
+ context 'task in namespace' do
79
+ let!(:database_task) do
80
+ Rake.application.in_namespace('namespace') do
81
+ described_class.new(:database)
82
+ end
83
+ end
84
+
85
+ let(:prerequisites) { subject.prerequisites }
86
+ subject { rake_task(self.class.description) }
87
+
88
+ context 'namespace:database:upload' do
89
+ it { is_expected.to be }
90
+ it { expect(prerequisites).to eq(['config/database.yml'])}
91
+ end
92
+
93
+ context 'namespace:database' do
94
+ it { is_expected.to be }
95
+ end
96
+
97
+ context 'config/database.yml' do
98
+ it { is_expected.to be_a(ConfigFor::Capistrano::UploadTask) }
99
+ end
100
+
101
+ end
102
+ end
@@ -0,0 +1,23 @@
1
+ require 'config_for'
2
+
3
+ RSpec.describe ConfigFor do
4
+ let(:env) { 'production' }
5
+ subject(:config) { config_for(self.class.description) }
6
+
7
+ def config_for(name)
8
+ described_class.load_config(fixtures_path, name, env)
9
+ end
10
+
11
+ context 'database' do
12
+ it { is_expected.to eq('host' => 'localhost', 'port' => 3306) }
13
+ it { is_expected.to include(port: 3306, host: 'localhost') }
14
+ end
15
+
16
+ context 'unknown' do
17
+ it do
18
+ expect{ subject }
19
+ .to raise_error(RuntimeError,
20
+ 'Could not load configuration. No such file - spec/fixtures/unknown.yml')
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,6 @@
1
+ production:
2
+ host: localhost
3
+ port: 3306
4
+
5
+ development:
6
+ host: localhost
@@ -0,0 +1,24 @@
1
+ require 'rails'
2
+ require 'rails/application'
3
+ require 'config_for'
4
+ require 'config_for/rails'
5
+
6
+ RSpec.describe ConfigFor::Rails do
7
+ # TODO: remove when dropping rails 3 compatibility
8
+ after { Rails.application = nil }
9
+
10
+ subject(:railtie) { Class.new(Rails::Application) }
11
+ it { expect(subject.ancestors).to include(described_class) }
12
+
13
+ context 'application' do
14
+ let(:config) { Rails.root.join('config') }
15
+
16
+ subject(:application) { railtie.instance }
17
+
18
+ before { allow(Rails).to receive(:env).and_return('production') }
19
+
20
+ around(:each) { |ex| railtie.configure(&ex) }
21
+
22
+ it_behaves_like 'framework integration'
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ require 'sinatra/base'
2
+ require 'config_for/sinatra'
3
+
4
+ RSpec.describe ConfigFor::Sinatra do
5
+ it { expect(Sinatra::Application.extensions).to include(described_class) }
6
+ end
7
+
8
+ RSpec.describe Sinatra::Application do
9
+ subject(:application) { Sinatra::Application }
10
+ let(:settings) { application.settings }
11
+ let(:root) { Dir.pwd }
12
+
13
+ before { allow(settings).to receive(:environment).and_return('production') }
14
+ before { allow(settings).to receive(:root).and_return(root) }
15
+
16
+ let(:config) { Pathname(root).join('config') }
17
+
18
+ it_behaves_like 'framework integration'
19
+ end
@@ -0,0 +1,117 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
4
+ # file to always be loaded, without a need to explicitly require it in any files.
5
+ #
6
+ # Given that it is always loaded, you are encouraged to keep this file as
7
+ # light-weight as possible. Requiring heavyweight dependencies from this file
8
+ # will add to the boot time of your test suite on EVERY test run, even for an
9
+ # individual file that may not need all of that loaded. Instead, consider making
10
+ # a separate helper file that requires the additional dependencies and performs
11
+ # the additional setup, and require it from the spec files that actually need it.
12
+ #
13
+ # The `.rspec` file also contains a few flags that are not defaults but that
14
+ # users commonly want.
15
+ #
16
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
17
+
18
+ require 'memfs'
19
+
20
+ begin
21
+ require 'pry'
22
+ rescue LoadError
23
+ end
24
+
25
+ module Fixtures
26
+ def fixtures_path
27
+ Pathname('spec/fixtures'.freeze)
28
+ end
29
+ end
30
+
31
+ RSpec.configure do |config|
32
+ # rspec-expectations config goes here. You can use an alternate
33
+ # assertion/expectation library such as wrong or the stdlib/minitest
34
+ # assertions if you prefer.
35
+ config.expect_with :rspec do |expectations|
36
+ # This option will default to `true` in RSpec 4. It makes the `description`
37
+ # and `failure_message` of custom matchers include text for helper methods
38
+ # defined using `chain`, e.g.:
39
+ # be_bigger_than(2).and_smaller_than(4).description
40
+ # # => "be bigger than 2 and smaller than 4"
41
+ # ...rather than:
42
+ # # => "be bigger than 2"
43
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
44
+ end
45
+
46
+ # rspec-mocks config goes here. You can use an alternate test double
47
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
48
+ config.mock_with :rspec do |mocks|
49
+ # Prevents you from mocking or stubbing a method that does not exist on
50
+ # a real object. This is generally recommended, and will default to
51
+ # `true` in RSpec 4.
52
+ mocks.verify_partial_doubles = true
53
+ end
54
+
55
+ config.include(Fixtures)
56
+
57
+ # The settings below are suggested to provide a good initial experience
58
+ # with RSpec, but feel free to customize to your heart's content.
59
+
60
+ # These two settings work together to allow you to limit a spec run
61
+ # to individual examples or groups you care about by tagging them with
62
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
63
+ # get run.
64
+ config.filter_run :focus
65
+ config.run_all_when_everything_filtered = true
66
+
67
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
68
+ # For more details, see:
69
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
70
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
71
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
72
+ config.disable_monkey_patching!
73
+
74
+ # This setting enables warnings. It's recommended, but in some cases may
75
+ # be too noisy due to issues in dependencies.
76
+ config.warnings = true
77
+
78
+ # Many RSpec users commonly either run the entire suite or an individual
79
+ # file, and it's useful to allow more verbose output when running an
80
+ # individual spec file.
81
+ if config.files_to_run.one?
82
+ # Use the documentation formatter for detailed output,
83
+ # unless a formatter has already been configured
84
+ # (e.g. via a command-line flag).
85
+ config.default_formatter = 'doc'
86
+ end
87
+
88
+ # Print the 10 slowest examples and example groups at the
89
+ # end of the spec run, to help surface which specs are running
90
+ # particularly slow.
91
+ config.profile_examples = 10
92
+
93
+ # Run specs in random order to surface order dependencies. If you find an
94
+ # order dependency and want to debug it, you can fix the order by providing
95
+ # the seed, which is printed after each run.
96
+ # --seed 1234
97
+ config.order = :random
98
+
99
+ # Seed global randomization in this process using the `--seed` CLI option.
100
+ # Setting this allows you to use `--seed` to deterministically reproduce
101
+ # test failures related to randomization by passing the same `--seed` value
102
+ # as the one that triggered the failure.
103
+ Kernel.srand config.seed
104
+ end
105
+
106
+
107
+ RSpec.shared_examples 'framework integration' do
108
+ around(:each) { |ex| MemFs.activate(&ex) }
109
+
110
+ context 'with database config' do
111
+ subject { application.config_for(:database) }
112
+ before { MemFs.touch(config.join('database.yml')) }
113
+
114
+ after { subject }
115
+ it { expect(ConfigFor).to receive(:load_config).with(config.to_s,:database,'production') }
116
+ end
117
+ end
metadata ADDED
@@ -0,0 +1,208 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: config_for
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.pre1
5
+ platform: ruby
6
+ authors:
7
+ - Michal Cichra
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ - - <
49
+ - !ruby/object:Gem::Version
50
+ version: '4.2'
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '3.0'
58
+ - - <
59
+ - !ruby/object:Gem::Version
60
+ version: '4.2'
61
+ - !ruby/object:Gem::Dependency
62
+ name: sinatra
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - '>='
66
+ - !ruby/object:Gem::Version
67
+ version: 1.4.0
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - '>='
73
+ - !ruby/object:Gem::Version
74
+ version: 1.4.0
75
+ - !ruby/object:Gem::Dependency
76
+ name: capistrano
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '3.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '3.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rspec
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ~>
94
+ - !ruby/object:Gem::Version
95
+ version: '3.1'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ~>
101
+ - !ruby/object:Gem::Version
102
+ version: '3.1'
103
+ - !ruby/object:Gem::Dependency
104
+ name: memfs
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: yard
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - '>='
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: activesupport
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - '>='
136
+ - !ruby/object:Gem::Version
137
+ version: '3.0'
138
+ type: :runtime
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - '>='
143
+ - !ruby/object:Gem::Version
144
+ version: '3.0'
145
+ description: Simplifies YAML parsing in Sinatra and Rails applications. Provides tools
146
+ to generate configs by capistrano.
147
+ email:
148
+ - michal@3scale.net
149
+ executables: []
150
+ extensions: []
151
+ extra_rdoc_files: []
152
+ files:
153
+ - .gitignore
154
+ - .rspec
155
+ - .travis.yml
156
+ - Appraisals
157
+ - CHANGELOG.md
158
+ - Gemfile
159
+ - LICENSE.txt
160
+ - README.md
161
+ - Rakefile
162
+ - config_for.gemspec
163
+ - gemfiles/rails_3.gemfile
164
+ - gemfiles/rails_4.gemfile
165
+ - gemfiles/rails_4_1.gemfile
166
+ - lib/config_for.rb
167
+ - lib/config_for/capistrano.rb
168
+ - lib/config_for/rails.rb
169
+ - lib/config_for/sinatra.rb
170
+ - lib/config_for/version.rb
171
+ - spec/capistrano_spec.rb
172
+ - spec/config_for_spec.rb
173
+ - spec/fixtures/database.yml
174
+ - spec/rails_spec.rb
175
+ - spec/sinatra_spec.rb
176
+ - spec/spec_helper.rb
177
+ homepage: ''
178
+ licenses:
179
+ - MIT
180
+ metadata: {}
181
+ post_install_message:
182
+ rdoc_options: []
183
+ require_paths:
184
+ - lib
185
+ required_ruby_version: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - '>='
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ required_rubygems_version: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - '>'
193
+ - !ruby/object:Gem::Version
194
+ version: 1.3.1
195
+ requirements: []
196
+ rubyforge_project:
197
+ rubygems_version: 2.2.2
198
+ signing_key:
199
+ specification_version: 4
200
+ summary: Provides YAML tools for app configuration.
201
+ test_files:
202
+ - spec/capistrano_spec.rb
203
+ - spec/config_for_spec.rb
204
+ - spec/fixtures/database.yml
205
+ - spec/rails_spec.rb
206
+ - spec/sinatra_spec.rb
207
+ - spec/spec_helper.rb
208
+ has_rdoc: