capistrano-deploy 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -3,3 +3,4 @@ pkg/*
3
3
  .bundle
4
4
  .yardoc
5
5
  doc
6
+ vendor/bundle
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - 1.9.3
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- capistrano-deploy (0.2.2)
4
+ capistrano-deploy (0.3.0)
5
5
  capistrano (~> 2.9.0)
6
6
 
7
7
  GEM
@@ -14,23 +14,23 @@ GEM
14
14
  net-ssh (>= 2.0.14)
15
15
  net-ssh-gateway (>= 1.1.0)
16
16
  diff-lcs (1.1.3)
17
- highline (1.6.5)
17
+ highline (1.6.9)
18
18
  net-scp (1.0.4)
19
19
  net-ssh (>= 1.99.1)
20
20
  net-sftp (2.0.5)
21
21
  net-ssh (>= 2.0.9)
22
- net-ssh (2.2.1)
22
+ net-ssh (2.2.2)
23
23
  net-ssh-gateway (1.1.0)
24
24
  net-ssh (>= 1.99.1)
25
25
  rake (0.9.2.2)
26
- rspec (2.6.0)
27
- rspec-core (~> 2.6.0)
28
- rspec-expectations (~> 2.6.0)
29
- rspec-mocks (~> 2.6.0)
30
- rspec-core (2.6.4)
31
- rspec-expectations (2.6.0)
26
+ rspec (2.8.0)
27
+ rspec-core (~> 2.8.0)
28
+ rspec-expectations (~> 2.8.0)
29
+ rspec-mocks (~> 2.8.0)
30
+ rspec-core (2.8.0)
31
+ rspec-expectations (2.8.0)
32
32
  diff-lcs (~> 1.1.2)
33
- rspec-mocks (2.6.0)
33
+ rspec-mocks (2.8.0)
34
34
 
35
35
  PLATFORMS
36
36
  ruby
data/MIT-LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2012 Sergey Nartimov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.md CHANGED
@@ -1,18 +1,22 @@
1
- Capistrano deploy recipes
1
+ Capistrano deploy recipes [![TravisCI](https://secure.travis-ci.org/lest/capistrano-deploy.png?branch=master)](http://travis-ci.org/lest/capistrano-deploy)
2
2
  =========================
3
3
 
4
- Git & Rails
5
- -----------
4
+ Inspired by https://github.com/blog/470-deployment-script-spring-cleaning.
5
+
6
+ Quickstart with Git and Rails
7
+ -----------------------------
6
8
 
7
9
  Minimal Capfile for Rails deploy using Git:
8
10
 
9
- require 'capistrano-deploy'
10
- use_recipes :git, :rails
11
+ ```ruby
12
+ require 'capistrano-deploy'
13
+ use_recipes :git, :rails
11
14
 
12
- server 'server name or ip address', :web, :app, :db, :primary => true
13
- set :user, 'user for deploy'
14
- set :deploy_to, '/deploy/to/path'
15
- set :repository, 'your git repository'
15
+ server 'server name or ip address', :web, :app, :db, :primary => true
16
+ set :user, 'user for deploy'
17
+ set :deploy_to, '/deploy/to/path'
18
+ set :repository, 'your git repository'
19
+ ```
16
20
 
17
21
  To setup:
18
22
 
@@ -22,60 +26,98 @@ Then when you push some changes to git repository simply run:
22
26
 
23
27
  cap deploy
24
28
 
25
- If you have migrations instead of previous command run:
29
+ Or if you have migrations:
26
30
 
27
31
  cap deploy:migrations
28
32
 
29
- To look through changes to be deployed:
33
+ To look through the changes to be deployed:
30
34
 
31
35
  cap deploy:pending
32
36
 
33
37
  Multistage
34
38
  ----------
35
39
 
36
- use_recipe :multistage
40
+ Basic usage:
41
+
42
+ ```ruby
43
+ use_recipe :multistage
44
+
45
+ set :default_stage, :development
46
+
47
+ stage :development do
48
+ ...
49
+ end
50
+
51
+ stage :production do
52
+ ...
53
+ end
54
+ ```
37
55
 
38
- set :default_stage, :development
56
+ You can also pass options that allow setting variables and default stage:
39
57
 
40
- define_stage :development do
41
- ...
42
- end
58
+ ```ruby
59
+ stage :development, :branch => :develop, :default => true
60
+ stage :production, :branch => :master
61
+ ```
43
62
 
44
- define_stage :production do
45
- ...
46
- end
63
+ When branches are specified for stages and git recipe is used
64
+ it will automatically select stage based on current local branch.
47
65
 
48
66
  Bundle
49
67
  ------
50
68
 
51
- use_recipe :bundle
69
+ Use recipe:
52
70
 
53
- To automatically install missing gems:
71
+ ```ruby
72
+ use_recipe :bundle
73
+ ```
54
74
 
55
- after 'deploy:update', 'bundle:install'
75
+ And add callback to run `bundle install` on each deploy:
76
+
77
+ ```ruby
78
+ after 'deploy:update', 'bundle:install'
79
+ ```
56
80
 
57
81
  Passenger
58
82
  ---------
59
83
 
60
- use_recipe :passenger
84
+ Use recipe:
85
+
86
+ ```ruby
87
+ use_recipe :passenger
88
+ ```
89
+
90
+ It will automatically do `touch tmp/restart.txt` on each deploy.
61
91
 
62
92
  Unicorn
63
93
  -------
64
94
 
65
- use_recipe :unicorn
95
+ Use recipe:
66
96
 
67
- Now you can setup to reload unicorn on `deploy:restart`:
97
+ ```ruby
98
+ use_recipe :unicorn
99
+ ```
68
100
 
69
- after 'deploy:restart', 'unicorn:reload'
101
+ You can setup callback to reload unicorn after deploy is done:
102
+
103
+ ```ruby
104
+ after 'deploy:restart', 'unicorn:reload'
105
+ ```
70
106
 
71
107
  Whenever
72
108
  --------
73
109
 
74
- use_recipe :whenever
110
+ Use recipe:
111
+
112
+ ```ruby
113
+ use_recipe :whenever
114
+ ```
75
115
 
76
116
  To automatically update crontab file:
77
117
 
78
- after 'deploy:restart', 'whenever:update_crontab'
118
+ ```ruby
119
+ after 'deploy:restart', 'whenever:update_crontab'
120
+ ```
79
121
 
80
122
  You can also clear crontab file with command:
81
123
 
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  Gem::Specification.new do |s|
3
3
  s.name = 'capistrano-deploy'
4
- s.version = '0.2.2'
4
+ s.version = '0.3.0'
5
5
  s.platform = Gem::Platform::RUBY
6
6
  s.authors = ['Sergey Nartimov']
7
7
  s.email = ['just.lest@gmail.com']
@@ -1,17 +1,25 @@
1
+ require 'capistrano'
2
+
1
3
  module CapistranoDeploy
2
4
  def self.load_into(configuration)
3
5
  configuration.load do
4
6
  @used_recipes = []
5
7
 
6
- (class << self; self; end).class_eval do
8
+ class << self
7
9
  attr_reader :used_recipes
10
+ end
8
11
 
9
- define_method :use_recipe do |recipe_name|
10
- @used_recipes << recipe_name.to_sym
12
+ def use_recipe(recipe_name)
13
+ return if @used_recipes.include?(recipe_name.to_sym)
11
14
 
15
+ begin
12
16
  require "capistrano-deploy/#{recipe_name}"
17
+
13
18
  recipe = CapistranoDeploy.const_get(recipe_name.to_s.capitalize.gsub(/_(\w)/) { $1.upcase })
14
- recipe.load_into(configuration)
19
+ recipe.load_into(self)
20
+ @used_recipes << recipe.to_s.split('::').last.downcase.to_sym
21
+ rescue LoadError
22
+ abort "Are you misspelled `#{recipe_name}` recipe name?"
15
23
  end
16
24
  end
17
25
 
@@ -0,0 +1,2 @@
1
+ require 'capistrano-deploy/bundle'
2
+ CapistranoDeploy::Bundler = CapistranoDeploy::Bundle
@@ -11,6 +11,10 @@ module CapistranoDeploy
11
11
 
12
12
  set(:current_revision) { capture("cd #{deploy_to} && git rev-parse HEAD").chomp }
13
13
 
14
+ set :local_branch do
15
+ `git symbolic-ref HEAD 2> /dev/null`.strip.sub('refs/heads/', '')
16
+ end
17
+
14
18
  namespace :deploy do
15
19
  desc 'Setup'
16
20
  task :setup, :except => {:no_release => true} do
@@ -2,24 +2,37 @@ module CapistranoDeploy
2
2
  module Multistage
3
3
  def self.load_into(configuration)
4
4
  configuration.load do
5
- set :multistage_stages, []
5
+ set :multistage_config, Config.new(configuration)
6
6
 
7
- def define_stage(name, &block)
8
- multistage_stages << name
7
+ def define_stage(*args, &block)
8
+ warn "[DEPRECATION] `define_stage` is deprecated, use `stage` instead"
9
+ stage(*args, &block)
10
+ end
11
+
12
+ def stage(name, options={}, &block)
13
+ set :default_stage, name.to_sym if options.delete(:default)
14
+ multistage_config.stage(name, options)
9
15
  callbacks[:start].detect { |c| c.source == 'multistage:ensure' }.except << name.to_s
16
+
10
17
  task(name) do
11
- set :stage, name.to_s
12
- block.call
18
+ set :current_stage, name.to_s
19
+ options.each do |k, v|
20
+ set k, v if v
21
+ end
22
+ block.call if block
13
23
  end
14
24
  end
15
25
 
16
26
  namespace :multistage do
17
27
  task :ensure do
18
- unless exists?(:stage)
19
- if exists?(:default_stage)
28
+ unless exists?(:current_stage)
29
+ if stage = multistage_config.inferred_stage
30
+ find_and_execute_task(stage.name)
31
+ elsif exists?(:default_stage)
20
32
  find_and_execute_task(default_stage)
21
33
  else
22
- abort "No stage specified. Please specify one of: #{multistage_stages.join(', ')} (e.g. `cap #{multistage_stages.first} #{ARGV.last}')"
34
+ stage_names = multistage_config.stages.map(&:name)
35
+ abort "No stage specified. Please specify one of: #{stage_names.join(', ')} (e.g. `cap #{stage_names.first} #{ARGV.last}')"
23
36
  end
24
37
  end
25
38
  end
@@ -28,5 +41,37 @@ module CapistranoDeploy
28
41
  on :start, 'multistage:ensure'
29
42
  end
30
43
  end
44
+
45
+ # Handles multistage configuration
46
+ class Config
47
+ attr_reader :config
48
+ attr_reader :stages
49
+
50
+ def initialize(config)
51
+ @config = config
52
+ @stages = []
53
+ end
54
+
55
+ def stage(name, options={})
56
+ stages << Stage.new(name, options)
57
+ end
58
+
59
+ def inferred_stage
60
+ if config.using_recipe?(:git)
61
+ branch = config.local_branch
62
+ stages.find { |stage| stage.options[:branch].to_s == branch }
63
+ end
64
+ end
65
+ end
66
+
67
+ class Stage
68
+ attr_reader :name
69
+ attr_reader :options
70
+
71
+ def initialize(name, options={})
72
+ @name = name
73
+ @options = options
74
+ end
75
+ end
31
76
  end
32
77
  end
@@ -0,0 +1,25 @@
1
+ module CapistranoDeploy
2
+ module RailsAssets
3
+ def self.load_into(configuration)
4
+ configuration.load do
5
+ use_recipe :rails
6
+
7
+ namespace :deploy do
8
+ namespace :assets do
9
+ desc 'Precompile assets'
10
+ task :precompile do
11
+ run "cd #{deploy_to} && RAILS_ENV=#{rails_env} RAILS_GROUPS=assets #{rake} assets:precompile"
12
+ end
13
+
14
+ desc 'Clean assets'
15
+ task :clean do
16
+ run "cd #{deploy_to} && RAILS_ENV=#{rails_env} RAILS_GROUPS=assets #{rake} assets:clean"
17
+ end
18
+ end
19
+ end
20
+
21
+ after 'deploy:update', 'deploy:assets:precompile'
22
+ end
23
+ end
24
+ end
25
+ end
@@ -2,8 +2,18 @@ module CapistranoDeploy
2
2
  module Rvm
3
3
  def self.load_into(configuration)
4
4
  configuration.load do
5
- $:.unshift(File.expand_path('./lib', ENV['rvm_path']))
6
- require 'rvm/capistrano'
5
+ set :rvm_ruby_string, 'default'
6
+ set :rvm_path, '/usr/local/rvm'
7
+
8
+ set(:rvm_shell_path) { "#{rvm_path}/bin/rvm-shell" }
9
+
10
+ set :default_shell do
11
+ shell = rvm_shell_path
12
+ ruby = rvm_ruby_string.to_s.strip
13
+ shell = "rvm_path=#{rvm_path} #{shell} '#{ruby}'" unless ruby.empty?
14
+
15
+ shell
16
+ end
7
17
 
8
18
  if File.exists?('.rvmrc')
9
19
  matches = File.read('.rvmrc').scan(/^rvm\s+use\s+.*?([\w\-\.]+@[\w\-]+).*$/)
@@ -12,7 +12,7 @@ module CapistranoDeploy
12
12
 
13
13
  set :whenever_identifier do
14
14
  if using_recipe?(:multistage)
15
- "#{application}_#{stage}"
15
+ "#{application}_#{current_stage}"
16
16
  else
17
17
  application
18
18
  end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'bundler' do
4
+ before do
5
+ mock_config do
6
+ use_recipes :bundler
7
+ set :deploy_to, '/foo/bar'
8
+ end
9
+ end
10
+
11
+ it 'uses bundler alias for bundle recipe' do
12
+ config.used_recipes.should == [:bundle]
13
+ end
14
+ end
data/spec/deploy_spec.rb CHANGED
@@ -2,7 +2,10 @@ require 'spec_helper'
2
2
 
3
3
  describe 'deploy' do
4
4
  before do
5
- mock_config { use_recipes :git, :rails }
5
+ mock_config do
6
+ use_recipes :git, :rails
7
+ set :deploy_to, '/foo/bar'
8
+ end
6
9
  end
7
10
 
8
11
  it 'returns used recipes' do
@@ -14,11 +17,22 @@ describe 'deploy' do
14
17
  config.should_not be_using_recipe(:bundle)
15
18
  end
16
19
 
20
+ it 'uses recipe once' do
21
+ config.use_recipe :git
22
+ config.used_recipes.should == [:git, :rails]
23
+ end
24
+
25
+ it 'aborts when recipe name misspelled' do
26
+ with_stderr do |output|
27
+ expect { config.use_recipe(:rvn) }.to raise_error(SystemExit)
28
+ output.should include('Are you misspelled `rvn` recipe name?')
29
+ end
30
+ end
31
+
17
32
  describe 'deploy' do
18
33
  it 'runs update and restart' do
19
- config.namespaces[:deploy].should_receive(:update)
20
- config.namespaces[:deploy].should_receive(:restart)
21
34
  cli_execute 'deploy'
35
+ config.should have_executed('deploy:update', 'deploy:restart')
22
36
  end
23
37
  end
24
38
  end
data/spec/git_spec.rb CHANGED
@@ -2,7 +2,10 @@ require 'spec_helper'
2
2
 
3
3
  describe 'git' do
4
4
  before do
5
- mock_config { use_recipe :git; set :deploy_to, '/foo/bar' }
5
+ mock_config do
6
+ use_recipe :git
7
+ set :deploy_to, '/foo/bar'
8
+ end
6
9
  end
7
10
 
8
11
  it 'has branch' do
@@ -6,14 +6,9 @@ describe 'multistage' do
6
6
  use_recipes :multistage
7
7
 
8
8
  set :default_stage, :development
9
-
10
- define_stage :development do
11
- set :foo, 'bar'
12
- end
13
-
14
- define_stage :production do
15
- set :foo, 'baz'
16
- end
9
+ stage(:development, :branch => 'develop') { set :foo, 'bar' }
10
+ stage(:production, :branch => 'master') { set :foo, 'baz' }
11
+ stage :another_stage, :foo => 'bar'
17
12
 
18
13
  task(:example) {}
19
14
  end
@@ -21,13 +16,51 @@ describe 'multistage' do
21
16
 
22
17
  it 'uses default stage' do
23
18
  cli_execute 'example'
24
- config.stage.should == 'development'
19
+ config.current_stage.should == 'development'
25
20
  config.foo.should == 'bar'
26
21
  end
27
22
 
23
+ it 'aborts when no stage selected' do
24
+ with_stderr do |output|
25
+ config.unset :default_stage
26
+ expect { cli_execute 'example' }.to raise_error(SystemExit)
27
+ output.should include('No stage specified. Please specify one of: development, production')
28
+ end
29
+ end
30
+
28
31
  it 'uses specified stage' do
29
32
  cli_execute %w[production example]
30
- config.stage.should == 'production'
33
+ config.current_stage.should == 'production'
31
34
  config.foo.should == 'baz'
32
35
  end
36
+
37
+ it 'sets variables from options' do
38
+ cli_execute 'another_stage'
39
+ config.foo.should == 'bar'
40
+ end
41
+
42
+ it 'accepts default option' do
43
+ mock_config { stage :to_be_default, :default => true }
44
+ config.default_stage.should == :to_be_default
45
+ end
46
+
47
+ context 'with git' do
48
+ before do
49
+ mock_config { use_recipe :git }
50
+ end
51
+
52
+ it 'infers stage using local branch' do
53
+ config.stub(:local_branch) { 'master' }
54
+ cli_execute 'example'
55
+ config.current_stage.should == 'production'
56
+ config.branch.should == 'master'
57
+ end
58
+
59
+ it 'uses default state when local branch not matches' do
60
+ config.stub(:local_branch) { 'foo' }
61
+ cli_execute 'example'
62
+ config.current_stage.should == 'development'
63
+ config.branch.should == 'develop'
64
+ end
65
+ end
33
66
  end
@@ -13,12 +13,10 @@ describe 'passenger' do
13
13
  cli_execute 'passenger:restart'
14
14
  config.should have_run('touch /foo/bar/tmp/restart.txt')
15
15
  end
16
- end
17
16
 
18
- describe 'deploy:restart' do
19
- it 'touches tmp/restart.txt' do
17
+ it 'is executed after deploy:restart' do
20
18
  cli_execute 'deploy:restart'
21
- config.should have_run('touch /foo/bar/tmp/restart.txt')
19
+ config.should have_executed('deploy:restart', 'passenger:restart')
22
20
  end
23
21
  end
24
22
  end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'rails assets' do
4
+ before do
5
+ mock_config do
6
+ use_recipe :rails_assets
7
+ set :deploy_to, '/foo/bar'
8
+ end
9
+ end
10
+
11
+ it 'uses rails recipe' do
12
+ config.should be_using_recipe(:rails)
13
+ end
14
+
15
+ describe 'deploy:assets:precompile' do
16
+ it 'runs precompile' do
17
+ cli_execute 'deploy:assets:precompile'
18
+ config.should have_run('cd /foo/bar && RAILS_ENV=production RAILS_GROUPS=assets rake assets:precompile')
19
+ end
20
+
21
+ it 'uses bundle command' do
22
+ mock_config { use_recipe :bundle }
23
+ cli_execute 'deploy:assets:precompile'
24
+ config.should have_run('cd /foo/bar && RAILS_ENV=production RAILS_GROUPS=assets bundle exec rake assets:precompile')
25
+ end
26
+
27
+ it 'is invoked after deploy:update' do
28
+ cli_execute 'deploy:update'
29
+ config.should have_executed('deploy:update', 'deploy:assets:precompile')
30
+ end
31
+ end
32
+
33
+ describe 'deploy:assets:clean' do
34
+ it 'runs clean' do
35
+ cli_execute 'deploy:assets:clean'
36
+ config.should have_run('cd /foo/bar && RAILS_ENV=production RAILS_GROUPS=assets rake assets:clean')
37
+ end
38
+ end
39
+ end
data/spec/rails_spec.rb CHANGED
@@ -2,14 +2,13 @@ require 'spec_helper'
2
2
 
3
3
  describe 'rails' do
4
4
  before do
5
- mock_config { use_recipe :rails }
5
+ mock_config do
6
+ use_recipe :rails
7
+ set :deploy_to, '/foo/bar'
8
+ end
6
9
  end
7
10
 
8
11
  describe 'deploy:migrate' do
9
- before do
10
- mock_config { set :deploy_to, '/foo/bar' }
11
- end
12
-
13
12
  it 'runs rake db:migrate' do
14
13
  cli_execute 'deploy:migrate'
15
14
  config.should have_run('cd /foo/bar && RAILS_ENV=production rake db:migrate')
@@ -24,10 +23,8 @@ describe 'rails' do
24
23
 
25
24
  describe 'deploy:migrations' do
26
25
  it 'runs update, migrate and restart' do
27
- config.namespaces[:deploy].should_receive(:update)
28
- config.namespaces[:deploy].should_receive(:migrate)
29
- config.namespaces[:deploy].should_receive(:restart)
30
26
  cli_execute 'deploy:migrations'
27
+ config.should have_executed('deploy:update', 'deploy:migrate', 'deploy:restart')
31
28
  end
32
29
  end
33
30
  end
data/spec/spec_helper.rb CHANGED
@@ -1,16 +1,24 @@
1
- require 'capistrano'
2
- require 'capistrano/cli'
3
1
  require 'capistrano-deploy'
2
+ require 'capistrano/cli'
4
3
 
5
4
  module CapistranoDeploy
6
5
  module Spec
7
6
  module ConfigurationExtension
8
7
  def run(cmd, options={}, &block)
9
- runs[cmd] = {:options => options, :block => block}
8
+ runned_commands[cmd] = {:options => options, :block => block}
9
+ end
10
+
11
+ def execute_task(task)
12
+ executed_tasks << task.fully_qualified_name
13
+ super
14
+ end
15
+
16
+ def runned_commands
17
+ @runned_commands ||= {}
10
18
  end
11
19
 
12
- def runs
13
- @runs ||= {}
20
+ def executed_tasks
21
+ @executed_tasks ||= []
14
22
  end
15
23
  end
16
24
 
@@ -31,16 +39,30 @@ module CapistranoDeploy
31
39
 
32
40
  def cli_execute(*args)
33
41
  config = @config
34
- cli = Capistrano::CLI.parse(args.flatten).tap do |cli|
35
- cli.instance_eval do
36
- (class << self; self; end).send(:define_method, :instantiate_configuration) do |options|
37
- config
38
- end
42
+ cli = Capistrano::CLI.parse(args.flatten)
43
+ cli.instance_eval do
44
+ (class << self; self end).send(:define_method, :instantiate_configuration) do |options|
45
+ config
39
46
  end
40
47
  end
41
48
 
42
49
  cli.execute!
43
50
  end
51
+
52
+ def with_stderr
53
+ original, $stderr = $stderr, StringIO.new
54
+ output = Object.new
55
+ class << output
56
+ instance_methods.each { |m| undef_method m unless m =~ /^__|^object_id$|^instance_eval$/ }
57
+ end
58
+ def output.method_missing(*args, &block)
59
+ ($stderr.rewind && $stderr.read).__send__(*args, &block)
60
+ end
61
+
62
+ yield output
63
+ ensure
64
+ $stderr = original
65
+ end
44
66
  end
45
67
 
46
68
  module Matchers
@@ -48,11 +70,26 @@ module CapistranoDeploy
48
70
 
49
71
  define :have_run do |cmd|
50
72
  match do |configuration|
51
- configuration.runs[cmd]
73
+ configuration.runned_commands[cmd]
74
+ end
75
+
76
+ failure_message_for_should do |configuration|
77
+ "expected configuration to run #{cmd}, but it wasn't found in #{configuration.runned_commands.keys}"
78
+ end
79
+ end
80
+
81
+ define :have_executed do |*tasks|
82
+ match do |configuration|
83
+ expected = tasks.dup
84
+ configuration.executed_tasks.each do |actual|
85
+ expected.shift if actual == expected.first
86
+ end
87
+
88
+ expected.empty?
52
89
  end
53
90
 
54
91
  failure_message_for_should do |configuration|
55
- "expected configuration to run #{cmd}, but it wasn't found in #{configuration.runs.keys}"
92
+ "expected configuration to execute #{tasks}, but it executed #{configuration.executed_tasks.keys}"
56
93
  end
57
94
  end
58
95
  end
data/spec/unicorn_spec.rb CHANGED
@@ -15,17 +15,17 @@ describe 'unicorn' do
15
15
  mock_config { set :unicorn_pid, '/foo.pid' }
16
16
  end
17
17
 
18
- it 'reload' do
18
+ it 'sends HUP' do
19
19
  cli_execute 'unicorn:reload'
20
20
  config.should have_run('kill -HUP /foo.pid')
21
21
  end
22
22
 
23
- it 'stop' do
23
+ it 'sends QUIT' do
24
24
  cli_execute 'unicorn:stop'
25
25
  config.should have_run('kill -QUIT /foo.pid')
26
26
  end
27
27
 
28
- it 'reexec' do
28
+ it 'sends USR2' do
29
29
  cli_execute 'unicorn:reexec'
30
30
  config.should have_run('kill -USR2 /foo.pid')
31
31
  end
@@ -17,9 +17,32 @@ describe 'whenever' do
17
17
  it 'default to application with stage when using multistage' do
18
18
  mock_config do
19
19
  use_recipe :multistage
20
- set :stage, 'bar'
20
+ set :current_stage, 'bar'
21
21
  end
22
22
  config.whenever_identifier.should == 'foo_bar'
23
23
  end
24
24
  end
25
+
26
+ describe 'whenever_cmd' do
27
+ it 'has default value' do
28
+ config.whenever_cmd.should == 'whenever'
29
+ end
30
+
31
+ it 'respects bundle recipe' do
32
+ mock_config { use_recipe :bundle }
33
+ config.whenever_cmd.should == 'bundle exec whenever'
34
+ end
35
+ end
36
+
37
+ describe 'whenever:update_crontab' do
38
+ it 'runs command' do
39
+ mock_config do
40
+ set :deploy_to, '/foo/bar'
41
+ set :whenever_cmd, 'wc'
42
+ set :whenever_identifier, 'wi'
43
+ end
44
+ cli_execute 'whenever:update_crontab'
45
+ config.should have_run('cd /foo/bar && wc --update-crontab wi')
46
+ end
47
+ end
25
48
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano-deploy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-04 00:00:00.000000000 Z
12
+ date: 2012-01-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capistrano
16
- requirement: &2157534600 !ruby/object:Gem::Requirement
16
+ requirement: &15867460 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: 2.9.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2157534600
24
+ version_requirements: *15867460
25
25
  description:
26
26
  email:
27
27
  - just.lest@gmail.com
@@ -31,25 +31,30 @@ extra_rdoc_files: []
31
31
  files:
32
32
  - .gitignore
33
33
  - .rspec
34
+ - .travis.yml
34
35
  - Gemfile
35
36
  - Gemfile.lock
37
+ - MIT-LICENSE
36
38
  - README.md
37
39
  - Rakefile
38
40
  - capistrano-deploy.gemspec
39
41
  - lib/capistrano-deploy.rb
40
42
  - lib/capistrano-deploy/bundle.rb
41
- - lib/capistrano-deploy/deploy.rb
43
+ - lib/capistrano-deploy/bundler.rb
42
44
  - lib/capistrano-deploy/git.rb
43
45
  - lib/capistrano-deploy/multistage.rb
44
46
  - lib/capistrano-deploy/passenger.rb
45
47
  - lib/capistrano-deploy/rails.rb
48
+ - lib/capistrano-deploy/rails_assets.rb
46
49
  - lib/capistrano-deploy/rvm.rb
47
50
  - lib/capistrano-deploy/unicorn.rb
48
51
  - lib/capistrano-deploy/whenever.rb
52
+ - spec/bundle_spec.rb
49
53
  - spec/deploy_spec.rb
50
54
  - spec/git_spec.rb
51
55
  - spec/multistage_spec.rb
52
56
  - spec/passenger_spec.rb
57
+ - spec/rails_assets_spec.rb
53
58
  - spec/rails_spec.rb
54
59
  - spec/spec_helper.rb
55
60
  - spec/unicorn_spec.rb
@@ -68,7 +73,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
73
  version: '0'
69
74
  segments:
70
75
  - 0
71
- hash: 1789516116924546670
76
+ hash: -3624144912279790165
72
77
  required_rubygems_version: !ruby/object:Gem::Requirement
73
78
  none: false
74
79
  requirements:
@@ -77,18 +82,20 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
82
  version: '0'
78
83
  segments:
79
84
  - 0
80
- hash: 1789516116924546670
85
+ hash: -3624144912279790165
81
86
  requirements: []
82
87
  rubyforge_project:
83
- rubygems_version: 1.8.10
88
+ rubygems_version: 1.8.15
84
89
  signing_key:
85
90
  specification_version: 3
86
91
  summary: Capistrano deploy recipes
87
92
  test_files:
93
+ - spec/bundle_spec.rb
88
94
  - spec/deploy_spec.rb
89
95
  - spec/git_spec.rb
90
96
  - spec/multistage_spec.rb
91
97
  - spec/passenger_spec.rb
98
+ - spec/rails_assets_spec.rb
92
99
  - spec/rails_spec.rb
93
100
  - spec/spec_helper.rb
94
101
  - spec/unicorn_spec.rb
@@ -1,65 +0,0 @@
1
- warn "[DEPRECATION] require 'capistrano-deploy/deploy' is deprecated. Please use require 'capistrano-deploy' and use_recipes :git, :rails instead."
2
-
3
- Capistrano::Configuration.instance(:must_exist).load do
4
- ssh_options[:forward_agent] = true
5
-
6
- set(:application) { repository.slice(/[^\/:]+?(?=\.git$)/) }
7
- set(:repository) { abort "Please specify repository, set :repository, 'foo'" }
8
- set(:deploy_to) { abort "Please specify deploy directory, set :deploy_to, '/deploy/to/path'" }
9
-
10
- set :branch, 'master'
11
-
12
- set :enable_submodules, false
13
-
14
- set(:current_revision) { capture("cd #{deploy_to} && git rev-parse HEAD").chomp }
15
-
16
- namespace :deploy do
17
- desc 'Deploy'
18
- task :default do
19
- update
20
- restart
21
- end
22
-
23
- desc 'Deploy & migrate'
24
- task :migrations do
25
- update_code
26
- migrate
27
- restart
28
- end
29
-
30
- desc 'Setup'
31
- task :setup, :except => {:no_release => true} do
32
- run "mkdir -p `dirname #{deploy_to}` && git clone --no-checkout #{repository} #{deploy_to}"
33
- update_code
34
- end
35
-
36
- desc 'Update'
37
- task :update do
38
- update_code
39
- end
40
-
41
- desc 'Update the deployed code'
42
- task :update_code, :except => {:no_release => true} do
43
- command = ["cd #{deploy_to}", 'git fetch origin', "git reset --hard origin/#{branch}"]
44
- command += ['git submodule init', 'git submodule -q sync', 'git submodule -q update'] if enable_submodules
45
- run command.join(' && ')
46
- end
47
-
48
- desc 'Run migrations'
49
- task :migrate, :roles => :db, :only => {:primary => true} do
50
- rake = fetch(:rake, 'rake')
51
- rails_env = fetch(:rails_env, 'production')
52
- run "cd #{deploy_to} && RAILS_ENV=#{rails_env} #{rake} db:migrate"
53
- end
54
-
55
- desc 'Restart'
56
- task :restart do
57
- # nothing
58
- end
59
-
60
- desc 'Show pending commits'
61
- task :pending do
62
- system("git log --pretty=medium --stat #{current_revision}..origin/#{branch}")
63
- end
64
- end
65
- end