config_for 0.1.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: