capistrano-shared_config 0.0.1

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: c572eaf23a01611ed2e3b3cdf70d1fd0da4e4e00
4
+ data.tar.gz: d727fa80d40d93c9baecee7fb52f5735cb51feb8
5
+ SHA512:
6
+ metadata.gz: f37094b90296b405e671b0022461c556f178a4e28d8697322bd4f377c35534be2604ce53255ac0f145bc035e5e03c2d2b09cdeac7610584954a3813b17deca2d
7
+ data.tar.gz: b717f1c764eca18541d609f519a81b0893dd3f0072207340cfb93009a2bcef4b1e7fab0ba04852bc395f17b5f226eb4ab207c7f9f155493ad63813563ebc965e
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in capistrano-sync_configs.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Alexander Stanko
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,80 @@
1
+ # Capistrano::SharedConfig
2
+
3
+ This gem provides some capistrano tasks for config files management during deploy.
4
+ With it you can:
5
+
6
+ * Create symlinks to config files in shared directory on each deploy
7
+ * Upload config files to shared directory from local machine on each deploy
8
+ * Use erb and capistrano tasks binding in your config files (it will compile before uploading to server)
9
+ * Make separate config files for each rails environment
10
+ * Automatically create shared_path/config directory on deploy:setup
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ ```ruby
17
+ gem 'capistrano-shared_config'
18
+ ```
19
+
20
+ And then execute:
21
+ ```
22
+ $ bundle install
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ Configure variables in config/deploy.rb, then require capistrano/shared_config:
28
+
29
+ ```ruby
30
+ set :shared_config_files, %w[settings.local nginx.conf]
31
+ set :shared_config_symlinks, %w[database, settings.local newrelic.yml] # default is same as shared_config_files
32
+
33
+ require 'capistrano/shared_config'
34
+ ```
35
+
36
+ Notice, you may skip `.yml` extension when configuring configs lists (Known extensions are: `.rb`, `.conf` and `.yml`).
37
+
38
+ Make sure, you require capistrano/shared\_config after desired `shared_config_files` set
39
+
40
+ You can also configure, when to run provided tasks:
41
+
42
+ ```ruby
43
+ # set :run_shared_config_symlinks, [:after, 'deploy:update_code']
44
+ # set :run_shared_config_sync, [:after, 'deploy:update_code']
45
+ # set :run_early_shared_config_check, [:before, 'deploy:update_code']
46
+
47
+ require 'capistrano/shared_config'
48
+ ```
49
+
50
+ ## Advanced Usage
51
+
52
+ You can call particular cap task with FILE env variable specified to upload or check only one file:
53
+ ```bash
54
+ $ cap shared_config:sync FILE=newrelic
55
+ ```
56
+
57
+ Or you can inspect content generated in config file with `show` task like this:
58
+ ```bash
59
+ $ cap shared_config:show FILE=settings.local
60
+ ```
61
+ It will output content of specified file surrounded by `=====` lines
62
+
63
+ ## Config Files Lookup
64
+
65
+ For uploading to server, provided task `sync` use files from `config` directory.
66
+ For every file_name in `shared_config_files` (after adding default `.yml` if needed)
67
+ it try to find the following files in order:
68
+
69
+ 1. `config/rails_env.file_name.erb`
70
+ 2. `config/rails_env.file_name`
71
+ 3. `config/file_name.erb`
72
+ 4. `config/file_name`
73
+
74
+ ## Contributing
75
+
76
+ 1. Fork it
77
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
78
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
79
+ 4. Push to the branch (`git push origin my-new-feature`)
80
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'capistrano/shared_config/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'capistrano-shared_config'
8
+ spec.version = Capistrano::SharedConfig::VERSION
9
+ spec.authors = ['Alexander Stanko']
10
+ spec.email = ['rakoth3d@gmail.com']
11
+ spec.description = %q{This gem provides several capistrano tasks for config files uploading and symlinking during deploy}
12
+ spec.summary = %q{Config files management during capistrano deploy}
13
+ spec.homepage = 'https://github.com/Rakoth/capistrano-shared_config'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
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.3'
22
+ spec.add_development_dependency 'rake'
23
+ spec.add_development_dependency 'capistrano'
24
+ spec.add_development_dependency 'capistrano-spec'
25
+ spec.add_development_dependency 'rspec'
26
+ end
@@ -0,0 +1,16 @@
1
+ set :application, 'app.example.com'
2
+
3
+ # Used in settings.local.yml. Usefull if you have many staging servers with same rails env.
4
+ set :redis_db, 5
5
+
6
+ # This files will be compiled from local template files and upload to shared folder on server on each deploy.
7
+ set :shared_config_files, %w[nginx.conf settings.local]
8
+
9
+ # For this files symlinks to shared folder will be created on each deploy.
10
+ set :shared_config_symlinks, %w[database settings.local]
11
+
12
+ # Change shared_config:symlinks tack position in deploy.
13
+ set :run_shared_config_symlinks, [:before, 'deploy:assets:precompile']
14
+
15
+ # Put require after configuring shared_config_* and run_shared_config_* variables.
16
+ require 'capistrano/shared_config'
@@ -0,0 +1,23 @@
1
+ upstream app-<%= stage %>-unicorn {
2
+ server unix:<%= deploy_to %>/current/tmp/sockets/unicorn.sock fail_timeout=30;
3
+ }
4
+
5
+ server {
6
+ listen 80;
7
+ server_name <%= application %>;
8
+
9
+ charset utf-8;
10
+ root <%= deploy_to %>/current/public;
11
+
12
+ location @unicorn {
13
+ proxy_set_header X-Real-IP $remote_addr;
14
+ proxy_set_header Host $host;
15
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
16
+ proxy_redirect off;
17
+ proxy_pass http://app-<%= stage %>-unicorn;
18
+ }
19
+
20
+ try_files $uri $uri/index.html $uri.html @unicorn;
21
+
22
+ error_page 500 502 503 504 /500.html;
23
+ }
@@ -0,0 +1,3 @@
1
+ redis:
2
+ host: redis1
3
+ db: <%= redis_db %>
@@ -0,0 +1,7 @@
1
+ require 'capistrano/shared_config/version'
2
+ require 'capistrano/shared_config/integration'
3
+
4
+ module Capistrano
5
+ module SharedConfig
6
+ end
7
+ end
@@ -0,0 +1,55 @@
1
+ require 'yaml'
2
+ require 'erb'
3
+
4
+ module Capistrano
5
+ module SharedConfig
6
+ class ConfigFile
7
+ def initialize name, capistrano_binding
8
+ @name = self.class.name(name)
9
+ @capistrano_binding = capistrano_binding
10
+ end
11
+
12
+ attr_reader :name, :capistrano_binding, :error
13
+
14
+ def env
15
+ @env ||= eval('rails_env', capistrano_binding)
16
+ end
17
+
18
+ def self.name name
19
+ name += '.yml' unless name =~ /\.(yml|conf|rb)$/
20
+ name
21
+ end
22
+
23
+ def location
24
+ @location ||= [
25
+ File.join('.', 'config', [env, name, 'erb'].join(?.)),
26
+ File.join('.', 'config', [env, name].join(?.)),
27
+ File.join('.', 'config', [name, 'erb'].join(?.)),
28
+ File.join('.', 'config', name)
29
+ ].detect(&File.method(:exists?))
30
+ end
31
+
32
+ def content
33
+ @content ||= ERB.new(File.read(location)).result(capistrano_binding)
34
+ end
35
+
36
+ def valid?
37
+ begin
38
+ case name
39
+ when /\.yml$/
40
+ YAML.load content
41
+ when /\.rb$/
42
+ eval("BEGIN {return true}\n#{content}", nil, name, 0)
43
+ else
44
+ # hope it is valid
45
+ end
46
+
47
+ true
48
+ rescue Exception => exception
49
+ @error = "Error in config file: #{exception.inspect}\n#{exception.message}"
50
+ false
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,74 @@
1
+ require 'capistrano'
2
+ require 'capistrano/version'
3
+ require 'capistrano/shared_config/config_file'
4
+
5
+ module Capistrano
6
+ module SharedConfig
7
+ class Integration
8
+ def self.load_into(capistrano_config)
9
+ capistrano_config.load do
10
+ set(:shared_config_files, fetch(:shared_config_files, []))
11
+ set(:shared_config_symlinks, fetch(:shared_config_symlinks, shared_config_files))
12
+
13
+ set(:run_shared_config_symlinks, fetch(:run_shared_config_symlinks, [:after, 'deploy:update_code']))
14
+ set(:run_shared_config_sync, fetch(:run_shared_config_sync, [:after, 'deploy:update_code']))
15
+ set(:run_early_shared_config_check, fetch(:run_early_shared_config_check, [:before, 'deploy:update_code']))
16
+
17
+ set(:_shared_config_files, (ENV['FILE'] ? [ENV['FILE']] : shared_config_files).
18
+ map{|name| ConfigFile.new(name, binding)}
19
+ )
20
+
21
+ namespace :shared_config do
22
+ desc 'Create shared config folder'
23
+ task :setup do
24
+ run "mkdir #{File.join(shared_path, 'config')}"
25
+ end
26
+ after 'deploy:setup', 'shared_config:setup'
27
+
28
+ desc 'Create symlinks for config files from shared_config_symlinks array'
29
+ task :symlinks do
30
+ next if shared_config_symlinks.empty?
31
+ commands = shared_config_symlinks.map do |name|
32
+ full_name = ConfigFile.name(name)
33
+ "ln -nfs #{File.join(shared_path, 'config', full_name)} #{File.join(latest_release, 'config', full_name)}"
34
+ end
35
+
36
+ run commands.join(' && ')
37
+ end
38
+ on run_shared_config_symlinks.first, 'shared_config:symlinks', only: run_shared_config_symlinks.last
39
+
40
+ desc 'Sync all config files'
41
+ task :sync do
42
+ _shared_config_files.each do |file|
43
+ put(file.content, File.join(shared_path, 'config', file.name))
44
+ end
45
+ end
46
+ on run_shared_config_sync.first, 'shared_config:sync', only: run_shared_config_sync.last
47
+
48
+ desc 'Check all config files'
49
+ task :check do
50
+ _shared_config_files.each do |file|
51
+ raise Capistrano::CommandError.new(file.error) unless file.valid?
52
+ end
53
+ end
54
+ on run_early_shared_config_check.first, 'shared_config:check', only: run_early_shared_config_check.last
55
+ before 'shared_config:sync', 'shared_config:check'
56
+
57
+ task :show do
58
+ _shared_config_files.each do |file|
59
+ puts '', file.name
60
+ puts ?= * 80
61
+ puts file.content
62
+ puts ?= * 80
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ if Capistrano::Configuration.instance
73
+ Capistrano::SharedConfig::Integration.load_into(Capistrano::Configuration.instance)
74
+ end
@@ -0,0 +1,5 @@
1
+ module Capistrano
2
+ module SharedConfig
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+ require 'capistrano/shared_config/config_file'
3
+
4
+ describe Capistrano::SharedConfig::ConfigFile do
5
+ describe '.name' do
6
+ it 'should use .yml extension by default' do
7
+ described_class.name('test').should == 'test.yml'
8
+ end
9
+
10
+ it 'should not override known extensions' do
11
+ described_class.name('test.yml').should == 'test.yml'
12
+ described_class.name('test.rb').should == 'test.rb'
13
+ described_class.name('test.conf').should == 'test.conf'
14
+ end
15
+ end
16
+
17
+ describe '#location' do
18
+ before do
19
+ File.stub(:exists?).and_return(false)
20
+ File.stub(:exists?).with('./config/production.config.yml').and_return(true)
21
+ File.stub(:exists?).with('./config/development.config.yml.erb').and_return(true)
22
+ File.stub(:exists?).with('./config/config.yml').and_return(true)
23
+ end
24
+
25
+ it 'should find local config with given environment' do
26
+ rails_env = 'staging'
27
+ described_class.new('config.yml', binding).location.should == './config/config.yml'
28
+
29
+ rails_env = 'production'
30
+ described_class.new('config.yml', binding).location.should == './config/production.config.yml'
31
+
32
+ rails_env = 'development'
33
+ described_class.new('config.yml', binding).location.should == './config/development.config.yml.erb'
34
+ end
35
+ end
36
+
37
+ describe '#content' do
38
+ let(:file_content) do
39
+ <<-YAML
40
+ staging:
41
+ test: 1
42
+ path: <%= deploy_to %>
43
+ YAML
44
+ end
45
+
46
+ before do
47
+ File.stub(:read).and_return(file_content)
48
+ end
49
+
50
+ it 'should eval erb template with given binding' do
51
+ deploy_to = 'test/path'
52
+ rails_env = 'staging'
53
+ described_class.new('test', binding).content.should == <<-YAML
54
+ staging:
55
+ test: 1
56
+ path: test/path
57
+ YAML
58
+ end
59
+ end
60
+
61
+ describe '#valid?' do
62
+ context 'yaml file' do
63
+ subject{described_class.new('test.yml', double(rails_env: 'staging'))}
64
+
65
+ it 'should return true for valid file' do
66
+ subject.stub(:content).and_return <<-YAML
67
+ test:
68
+ valid: yaml
69
+ YAML
70
+
71
+ subject.should be_valid
72
+ subject.error.should be_nil
73
+ end
74
+
75
+ it 'should return false for invalid file and set error' do
76
+ subject.stub(:content).and_return <<-YAML
77
+ test:
78
+ invalid: yaml
79
+ valid: yaml
80
+ YAML
81
+
82
+ subject.should_not be_valid
83
+ subject.error.should be
84
+ end
85
+ end
86
+
87
+ context 'rb file' do
88
+ subject{described_class.new('test.rb', double(rails_env: 'staging'))}
89
+
90
+ it 'should return true for valid file' do
91
+ subject.stub(:content).and_return <<-CODE
92
+ god.watch do
93
+ test
94
+ end
95
+ CODE
96
+
97
+ subject.should be_valid
98
+ subject.error.should be_nil
99
+ end
100
+
101
+ it 'should return false for invalid file and set error' do
102
+ subject.stub(:content).and_return <<-CODE
103
+ god.watch do
104
+ (test
105
+ end
106
+ CODE
107
+
108
+ subject.should_not be_valid
109
+ subject.error.should be
110
+ end
111
+ end
112
+
113
+ context 'other files' do
114
+ subject{described_class.new('test.conf', double(rails_env: 'staging'))}
115
+
116
+ it 'should return true' do
117
+ subject.stub(:content).and_return <<-CONFIG
118
+ test = 1
119
+ conf.test = 1
120
+ CONFIG
121
+
122
+ subject.should be_valid
123
+ subject.error.should be_nil
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,168 @@
1
+ require 'spec_helper'
2
+ require 'capistrano/shared_config/integration'
3
+
4
+ describe Capistrano::SharedConfig::Integration do
5
+ let(:cap) do
6
+ Capistrano::Configuration.new.tap do |config|
7
+ config.extend(Capistrano::Spec::ConfigurationExtension)
8
+ config.extend(ConfigurationExtension)
9
+ config.load do
10
+ namespace :deploy do
11
+ task(:default){}
12
+ task(:update_code){}
13
+ task(:assets_precompile){}
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ describe 'set config files variables' do
20
+ before do
21
+ cap.set(:rails_env, 'staging')
22
+ end
23
+
24
+ it 'should should set empty config files set for default' do
25
+ Capistrano::SharedConfig::Integration.load_into(cap)
26
+
27
+ cap.fetch(:shared_config_files).should == []
28
+ cap.fetch(:shared_config_symlinks).should == []
29
+ end
30
+
31
+ it 'should should use predefined shared_config_files' do
32
+ cap.set(:shared_config_files, ['test'])
33
+ Capistrano::SharedConfig::Integration.load_into(cap)
34
+
35
+ cap.fetch(:shared_config_files).should == ['test']
36
+ cap.fetch(:shared_config_symlinks).should == ['test']
37
+ end
38
+
39
+ it 'should should use predefined shared_config_symlinks' do
40
+ cap.set(:shared_config_files, ['test', 'test_1'])
41
+ cap.set(:shared_config_symlinks, ['test'])
42
+ Capistrano::SharedConfig::Integration.load_into(cap)
43
+
44
+ cap.fetch(:shared_config_files).should == ['test', 'test_1']
45
+ cap.fetch(:shared_config_symlinks).should == ['test']
46
+ end
47
+
48
+ it 'should set _shared_config_files for internal use' do
49
+ cap.set(:shared_config_files, ['test', 'test_1'])
50
+ Capistrano::SharedConfig::Integration.load_into(cap)
51
+
52
+ cap.fetch(:_shared_config_files).should have(2).items
53
+ cap.fetch(:_shared_config_files).first.name.should == 'test.yml'
54
+ cap.fetch(:_shared_config_files).last.name.should == 'test_1.yml'
55
+ end
56
+
57
+ it 'should set _shared_config_files for internal use when ENV[FILE] is present' do
58
+ begin
59
+ ENV['FILE'] = 'test_env'
60
+ cap.set(:shared_config_files, ['test', 'test_1'])
61
+ Capistrano::SharedConfig::Integration.load_into(cap)
62
+
63
+ cap.fetch(:_shared_config_files).should have(1).item
64
+ cap.fetch(:_shared_config_files).first.name.should == 'test_env.yml'
65
+ ensure
66
+ ENV.delete('FILE')
67
+ end
68
+ end
69
+ end
70
+
71
+ describe 'callbacks' do
72
+ context 'default' do
73
+ before do
74
+ Capistrano::SharedConfig::Integration.load_into(cap)
75
+ end
76
+
77
+ it 'should run shared_config:symlinks after deploy:update_code' do
78
+ cap.should callback('shared_config:symlinks').after('deploy:update_code')
79
+ end
80
+
81
+ it 'should run shared_config:sync after deploy:update_code' do
82
+ cap.should callback('shared_config:sync').after('deploy:update_code')
83
+ end
84
+
85
+ it 'should run early shared_config:check before deploy:update_code' do
86
+ cap.should callback('shared_config:check').before('deploy:update_code')
87
+ end
88
+
89
+ it 'should run shared_config:check before shared_config:sync' do
90
+ cap.should callback('shared_config:check').before('shared_config:sync')
91
+ end
92
+ end
93
+
94
+ context 'configured' do
95
+ it 'should run configured shared_config:symlinks' do
96
+ cap.set(:run_shared_config_symlinks, [:before, 'deploy:assets_precompile'])
97
+ Capistrano::SharedConfig::Integration.load_into(cap)
98
+
99
+ cap.should callback('shared_config:symlinks').before('deploy:assets_precompile')
100
+ end
101
+
102
+ it 'should run configured shared_config:sync' do
103
+ cap.set(:run_shared_config_sync, [:after, 'deploy:assets_precompile'])
104
+ Capistrano::SharedConfig::Integration.load_into(cap)
105
+
106
+ cap.should callback('shared_config:sync').after('deploy:assets_precompile')
107
+ end
108
+
109
+ it 'should run configured early shared_config:check' do
110
+ cap.set(:run_early_shared_config_check, [:before, 'deploy'])
111
+ Capistrano::SharedConfig::Integration.load_into(cap)
112
+ cap.should callback('shared_config:check').before('deploy')
113
+ end
114
+ end
115
+ end
116
+
117
+ describe 'tasks' do
118
+ before do
119
+ cap.set(:rails_env, 'production')
120
+ cap.set(:shared_path, '/shared')
121
+ cap.set(:shared_config_files, %w[database settings.local])
122
+ Capistrano::SharedConfig::Integration.load_into(cap)
123
+ end
124
+
125
+ describe 'shared_config:symlinks' do
126
+ before do
127
+ cap.set(:latest_release, '/release')
128
+ cap.find_and_execute_task('shared_config:symlinks')
129
+ end
130
+
131
+ it 'should create symlinks for all config files' do
132
+ cap.should have_run(
133
+ 'ln -nfs /shared/config/database.yml /release/config/database.yml && ' +
134
+ 'ln -nfs /shared/config/settings.local.yml /release/config/settings.local.yml'
135
+ )
136
+ end
137
+ end
138
+
139
+ describe 'shared_config:check' do
140
+ let(:files){cap.fetch(:_shared_config_files)}
141
+
142
+ it 'should pass silently if all configs are valid' do
143
+ files.each{|file| file.stub(:valid?).and_return(true)}
144
+ expect{cap.find_and_execute_task('shared_config:check')}.to_not raise_error
145
+ end
146
+
147
+ it 'should rollback deploy if config is invalid' do
148
+ files.first.stub(:valid?).and_return(true)
149
+ files.last.stub(valid?: false, error: 'test')
150
+ expect{cap.find_and_execute_task('shared_config:check')}.to raise_error(Capistrano::CommandError, 'test')
151
+ end
152
+ end
153
+
154
+ describe 'shared_config:sync' do
155
+ let(:files){cap.fetch(:_shared_config_files)}
156
+
157
+ it 'should upload all config files on server' do
158
+ files.first.stub(:content).and_return('test')
159
+ files.last.stub(:content).and_return('test_1')
160
+
161
+ cap.find_and_execute_task('shared_config:sync')
162
+
163
+ cap.should have_putted('/shared/config/database.yml').with('test')
164
+ cap.should have_putted('/shared/config/settings.local.yml').with('test_1')
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,12 @@
1
+ require 'capistrano-spec'
2
+
3
+ #TODO make pull-request into capistrano-spec gem
4
+ require 'support/matchers'
5
+ require 'support/configuration_extension'
6
+
7
+ RSpec.configure do |config|
8
+ config.include Capistrano::Spec::Matchers
9
+ config.include Capistrano::Spec::Helpers
10
+ config.include Matchers
11
+ config.order = :random
12
+ end
@@ -0,0 +1,9 @@
1
+ module ConfigurationExtension
2
+ def put(content, path, options={}, &block)
3
+ puttes[path] = {content: content, options: options, block: block}
4
+ end
5
+
6
+ def puttes
7
+ @puttes ||= {}
8
+ end
9
+ end
@@ -0,0 +1,75 @@
1
+ module Matchers
2
+ extend ::Spec::Matchers::DSL
3
+
4
+ define :callback do |task_name|
5
+ extend Capistrano::Spec::Helpers
6
+
7
+ match do |configuration|
8
+ @task = configuration.find_task(task_name)
9
+ callbacks = find_callback(configuration, @on, @task)
10
+
11
+ if callbacks
12
+ callbacks.any? do |callback|
13
+ if callback && @trigger_task_name
14
+ @trigger_task = configuration.find_task(@trigger_task_name)
15
+ @trigger_task && callback.applies_to?(@trigger_task)
16
+ else
17
+ callback
18
+ end
19
+ end
20
+ else
21
+ false
22
+ end
23
+ end
24
+
25
+ def on(on)
26
+ @on = on
27
+ self
28
+ end
29
+
30
+ def before(before_task_name)
31
+ @on = :before
32
+ @trigger_task_name = before_task_name
33
+ self
34
+ end
35
+
36
+ def after(after_task_name)
37
+ @on = :after
38
+ @trigger_task_name = after_task_name
39
+ self
40
+ end
41
+
42
+ failure_message_for_should do |actual|
43
+ if @trigger_task_name
44
+ "expected configuration to callback #{task_name.inspect} #{@on} #{@trigger_task_name.inspect}, but did not"
45
+ else
46
+ "expected configuration to callback #{task_name.inspect} on #{@on}, but did not"
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ define :have_putted do |path|
53
+ match do |configuration|
54
+ upload = configuration.puttes[path]
55
+ if @content
56
+ upload && upload[:content] == @content
57
+ else
58
+ upload
59
+ end
60
+ end
61
+
62
+ def with(content)
63
+ @content = content
64
+ self
65
+ end
66
+
67
+ failure_message_for_should do |actual|
68
+ if @content
69
+ "expected configuration to put #{path} with content '#{@content}', but did not"
70
+ else
71
+ "expected configuration to put #{path}, but did not"
72
+ end
73
+ end
74
+ end
75
+ end
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-shared_config
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Stanko
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-06-17 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.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: capistrano
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: capistrano-spec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: This gem provides several capistrano tasks for config files uploading
84
+ and symlinking during deploy
85
+ email:
86
+ - rakoth3d@gmail.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - .gitignore
92
+ - .rspec
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.md
96
+ - Rakefile
97
+ - capistrano-shared_config.gemspec
98
+ - examples/config/deploy.rb
99
+ - examples/config/nginx.conf.erb
100
+ - examples/config/staging.settings.local.yml
101
+ - lib/capistrano/shared_config.rb
102
+ - lib/capistrano/shared_config/config_file.rb
103
+ - lib/capistrano/shared_config/integration.rb
104
+ - lib/capistrano/shared_config/version.rb
105
+ - spec/capistrano/shared_config/config_file_spec.rb
106
+ - spec/capistrano/shared_config/integration_spec.rb
107
+ - spec/spec_helper.rb
108
+ - spec/support/configuration_extension.rb
109
+ - spec/support/matchers.rb
110
+ homepage: https://github.com/Rakoth/capistrano-shared_config
111
+ licenses:
112
+ - MIT
113
+ metadata: {}
114
+ post_install_message:
115
+ rdoc_options: []
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - '>='
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ requirements: []
129
+ rubyforge_project:
130
+ rubygems_version: 2.0.3
131
+ signing_key:
132
+ specification_version: 4
133
+ summary: Config files management during capistrano deploy
134
+ test_files:
135
+ - spec/capistrano/shared_config/config_file_spec.rb
136
+ - spec/capistrano/shared_config/integration_spec.rb
137
+ - spec/spec_helper.rb
138
+ - spec/support/configuration_extension.rb
139
+ - spec/support/matchers.rb