capistrano 2.6.1.pre → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -14,8 +14,8 @@ implemented simply as `self.gsub(/\s+/, ' ')`.
14
14
  Here's the run-down of changes, and their committers, as always - a huge thank
15
15
  you to the community that continues to drive Capistrano's development.
16
16
 
17
- * `deploy:setup` now respects `:group_writable` (Mathew Davies)
18
- * Fixes to `:scm_verbose` for the Git module (defaults to On.) (Daniel Duvall)
17
+ * `deploy:setup` now respects `:group_writable` (Daniel Duvall)
18
+ * Fixes to `:scm_verbose` for the Git module (defaults to On.) (Matthew Davies)
19
19
  * Will now copy hidden files in the project's root into the release
20
20
  directory (Mark Jaquith)
21
21
  * Now handles closing already-dead connections in a sane way (does not raise
data/Gemfile CHANGED
@@ -3,4 +3,12 @@ source "http://rubygems.org"
3
3
  # Specify your gem's dependencies in capistrano.gemspec
4
4
  gemspec
5
5
 
6
- gem "rake"
6
+ #
7
+ # Development Dependencies from the Gemfile
8
+ # are merged here.
9
+ #
10
+ group :development do
11
+ gem 'rake'
12
+ gem 'ruby-debug', :platform => :mri_18
13
+ gem 'ruby-debug19', :platform => :mri_19
14
+ end
@@ -1,8 +1,15 @@
1
1
  ## Capistrano
2
2
 
3
- Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH. It uses a simple DSL (borrowed in part from [Rake](http://rake.rubyforge.org/)) that allows you to define _tasks_, which may be applied to machines in certain roles. It also supports tunneling connections via some gateway machine to allow operations to be performed behind VPN's and firewalls.
3
+ Capistrano is a utility and framework for executing commands in parallel on
4
+ multiple remote machines, via SSH. It uses a simple DSL (borrowed in part from
5
+ [Rake](http://rake.rubyforge.org/)) that allows you to define _tasks_, which may
6
+ be applied to machines in certain roles. It also supports tunneling connections
7
+ via some gateway machine to allow operations to be performed behind VPN's and
8
+ firewalls.
4
9
 
5
- Capistrano was originally designed to simplify and automate deployment of web applications to distributed environments, and originally came bundled with a set of tasks designed for deploying Rails applications.
10
+ Capistrano was originally designed to simplify and automate deployment of web
11
+ applications to distributed environments, and originally came bundled with a set
12
+ of tasks designed for deploying Rails applications.
6
13
 
7
14
  ## Documentation
8
15
 
@@ -16,17 +23,18 @@ Capistrano was originally designed to simplify and automate deployment of web ap
16
23
  * [Net::SSH::Gateway](http://net-ssh.rubyforge.org)
17
24
  * [HighLine](http://highline.rubyforge.org)
18
25
 
19
- If you want to run the tests, you'll also need to have the following dependencies installed:
20
-
21
- * [Echoe](https://github.com/fauna/echoe)
22
- * [Mocha](http://mocha.rubyforge.org)
26
+ If you want to run the tests, you'll also need to install the dependencies with
27
+ Bundler, see the `Gemfile` within .
23
28
 
24
29
  ## ASSUMPTIONS
25
30
 
26
- Capistrano is "opinionated software", which means it has very firm ideas about how things ought to be done, and tries to force those ideas on you. Some of the assumptions behind these opinions are:
31
+ Capistrano is "opinionated software", which means it has very firm ideas about
32
+ how things ought to be done, and tries to force those ideas on you. Some of the
33
+ assumptions behind these opinions are:
27
34
 
28
35
  * You are using SSH to access the remote servers.
29
- * You either have the same password to all target machines, or you have public keys in place to allow passwordless access to them.
36
+ * You either have the same password to all target machines, or you have public
37
+ keys in place to allow passwordless access to them.
30
38
 
31
39
  Do not expect these assumptions to change.
32
40
 
@@ -39,9 +47,12 @@ In general, you'll use Capistrano as follows:
39
47
 
40
48
  Use the `cap` script as follows:
41
49
 
42
- cap sometask
50
+ cap sometask
43
51
 
44
- By default, the script will look for a file called one of `capfile` or `Capfile`. The `someaction` text indicates which task to execute. You can do "cap -h" to see all the available options and "cap -T" to see all the available tasks.
52
+ By default, the script will look for a file called one of `capfile` or
53
+ `Capfile`. The `someaction` text indicates which task to execute. You can do
54
+ "cap -h" to see all the available options and "cap -T" to see all the available
55
+ tasks.
45
56
 
46
57
  ## LICENSE:
47
58
 
@@ -33,7 +33,7 @@ The following options are understood:
33
33
 
34
34
  <%= color '-n, --dry-run', :bold %>
35
35
  Causes Capistrano to simply display each remote command, without executing it. In this sense it is similar to --debug, but without the prompt. Note that commands executed locally are still run--only remote commands are skipped.
36
-
36
+
37
37
  <%= color '-p, --password', :bold %>
38
38
  Normally, cap will prompt for the password on-demand, the first time it is needed. This can make it hard to walk away from Capistrano, since you might not know if it will prompt for a password down the road. In such cases, you can use the -p option to force cap to prompt for the password immediately.
39
39
 
@@ -54,9 +54,9 @@ module Capistrano
54
54
  exit
55
55
  end
56
56
 
57
- opts.on("-l", "--logger [STDERR|STDOUT|file]",
57
+ opts.on("-l", "--logger [STDERR|STDOUT|file]",
58
58
  "Choose logger method. STDERR used by default."
59
- ) do |value|
59
+ ) do |value|
60
60
  options[:output] = if value.nil? || value.upcase == 'STDERR'
61
61
  # Using default logger.
62
62
  nil
@@ -201,7 +201,7 @@ module Capistrano
201
201
  def default_sysconf #:nodoc:
202
202
  File.join(sysconf_directory, "capistrano.conf")
203
203
  end
204
-
204
+
205
205
  def default_dotfile #:nodoc:
206
206
  File.join(home_directory, ".caprc")
207
207
  end
@@ -211,7 +211,7 @@ module Capistrano
211
211
  # appropriate location for this file in Windows.
212
212
  ENV["SystemRoot"] || '/etc'
213
213
  end
214
-
214
+
215
215
  def home_directory #:nodoc:
216
216
  ENV["HOME"] ||
217
217
  (ENV["HOMEPATH"] && "#{ENV["HOMEDRIVE"]}#{ENV["HOMEPATH"]}") ||
@@ -22,7 +22,7 @@ module Capistrano
22
22
  def password_prompt(prompt="Password: ")
23
23
  ui.ask(prompt) { |q| q.echo = false }
24
24
  end
25
-
25
+
26
26
  # Debug mode prompt
27
27
  def debug_prompt(cmd)
28
28
  ui.say("Preparing to execute command: #{cmd}")
@@ -37,4 +37,4 @@ module Capistrano
37
37
  end
38
38
  end
39
39
  end
40
- end
40
+ end
@@ -111,6 +111,9 @@ module Capistrano
111
111
  # * :except - specifies a condition limiting which hosts will be selected to
112
112
  # run the command. This is the inverse of :only (hosts that do _not_ match
113
113
  # the condition will be selected).
114
+ # * :on_no_matching_servers - if :continue, will continue to execute tasks if
115
+ # no matching servers are found for the host criteria. The default is to raise
116
+ # a NoMatchingServersError exception.
114
117
  # * :once - if true, only the first matching server will be selected. The default
115
118
  # is false (all matching servers will be selected).
116
119
  # * :max_hosts - specifies the maximum number of hosts that should be selected
@@ -156,7 +156,7 @@ module Capistrano
156
156
  servers = find_servers_for_task(task, options)
157
157
 
158
158
  if servers.empty?
159
- if ENV['HOSTFILTER']
159
+ if ENV['HOSTFILTER'] || task.options.merge(options)[:on_no_matching_servers] == :continue
160
160
  logger.info "skipping `#{task.fully_qualified_name}' because no servers matched"
161
161
  return
162
162
  else
@@ -170,7 +170,10 @@ module Capistrano
170
170
  end
171
171
  else
172
172
  servers = find_servers(options)
173
- raise Capistrano::NoMatchingServersError, "no servers found to match #{options.inspect}" if servers.empty?
173
+ if servers.empty?
174
+ raise Capistrano::NoMatchingServersError, "no servers found to match #{options.inspect}" if options[:on_no_matching_servers] != :continue
175
+ return
176
+ end
174
177
  end
175
178
 
176
179
  servers = [servers.first] if options[:once]
@@ -56,7 +56,7 @@ _cset(:current_path) { File.join(deploy_to, current_dir) }
56
56
  _cset(:release_path) { File.join(releases_path, release_name) }
57
57
 
58
58
  _cset(:releases) { capture("ls -x #{releases_path}", :except => { :no_release => true }).split.sort }
59
- _cset(:current_release) { File.join(releases_path, releases.last) }
59
+ _cset(:current_release) { releases.length > 0 ? File.join(releases_path, releases.last) : nil }
60
60
  _cset(:previous_release) { releases.length > 1 ? File.join(releases_path, releases[-2]) : nil }
61
61
 
62
62
  _cset(:current_revision) { capture("cat #{current_path}/REVISION", :except => { :no_release => true }).chomp }
@@ -304,23 +304,11 @@ namespace :deploy do
304
304
  end
305
305
 
306
306
  desc <<-DESC
307
- Restarts your application. This works by calling the script/process/reaper \
308
- script under the current path.
309
-
310
- If you are deploying a Rails 2.3.x application, you will need to install
311
- these http://github.com/rails/irs_process_scripts (more info about why
312
- on that page.)
313
-
314
- By default, this will be invoked via sudo as the `app' user. If \
315
- you wish to run it as a different user, set the :runner variable to \
316
- that user. If you are in an environment where you can't use sudo, set \
317
- the :use_sudo variable to false:
318
-
319
- set :use_sudo, false
307
+ Blank task exists as a hook into which to install your own environment \
308
+ specific behaviour.
320
309
  DESC
321
310
  task :restart, :roles => :app, :except => { :no_release => true } do
322
- warn "[DEPRECATED] `deploy:restart` is going to be changed to Passenger mod_rails' method after 2.5.9 - see http://is.gd/2BPeA"
323
- try_runner "#{current_path}/script/process/reaper"
311
+ # Empty Task to overload with your platform specifics
324
312
  end
325
313
 
326
314
  namespace :rollback do
@@ -488,37 +476,19 @@ namespace :deploy do
488
476
  end
489
477
 
490
478
  desc <<-DESC
491
- Start the application servers. This will attempt to invoke a script \
492
- in your application called `script/spin', which must know how to start \
493
- your application listeners. For Rails applications, you might just have \
494
- that script invoke `script/process/spawner' with the appropriate \
495
- arguments.
496
-
497
- By default, the script will be executed via sudo as the `app' user. If \
498
- you wish to run it as a different user, set the :runner variable to \
499
- that user. If you are in an environment where you can't use sudo, set \
500
- the :use_sudo variable to false.
479
+ Blank task exists as a hook into which to install your own environment \
480
+ specific behaviour.
501
481
  DESC
502
482
  task :start, :roles => :app do
503
- warn "[DEPRECATED] `deploy:start` is going to be removed after 2.5.9 - see http://is.gd/2BPeA"
504
- run "cd #{current_path} && #{try_runner} nohup script/spin"
483
+ # Empty Task to overload with your platform specifics
505
484
  end
506
485
 
507
486
  desc <<-DESC
508
- Stop the application servers. This will call script/process/reaper for \
509
- both the spawner process, and all of the application processes it has \
510
- spawned. As such, it is fairly Rails specific and may need to be \
511
- overridden for other systems.
512
-
513
- By default, the script will be executed via sudo as the `app' user. If \
514
- you wish to run it as a different user, set the :runner variable to \
515
- that user. If you are in an environment where you can't use sudo, set \
516
- the :use_sudo variable to false.
487
+ Blank task exists as a hook into which to install your own environment \
488
+ specific behaviour.
517
489
  DESC
518
490
  task :stop, :roles => :app do
519
- warn "[DEPRECATED] `deploy:start` is going to be removed after 2.5.9 - see http://is.gd/2BPeA"
520
- run "if [ -f #{current_path}/tmp/pids/dispatch.spawner.pid ]; then #{try_runner} #{current_path}/script/process/reaper -a kill -r dispatch.spawner.pid; fi"
521
- try_runner "#{current_path}/script/process/reaper -a kill"
491
+ # Empty Task to overload with your platform specifics
522
492
  end
523
493
 
524
494
  namespace :pending do
@@ -148,7 +148,11 @@ module Capistrano
148
148
  if variable(:git_enable_submodules)
149
149
  execute << "#{git} submodule #{verbose} init"
150
150
  execute << "#{git} submodule #{verbose} sync"
151
- execute << "#{git} submodule #{verbose} update --init --recursive"
151
+ if false == variable(:git_submodules_recursive)
152
+ execute << "#{git} submodule #{verbose} update --init"
153
+ else
154
+ execute << "#{git} submodule #{verbose} update --init --recursive"
155
+ end
152
156
  end
153
157
 
154
158
  execute.join(" && ").compact
@@ -187,7 +191,11 @@ module Capistrano
187
191
  execute << "#{git} submodule #{verbose} init"
188
192
  execute << "for mod in `#{git} submodule status | awk '{ print $2 }'`; do #{git} config -f .git/config submodule.${mod}.url `#{git} config -f .gitmodules --get submodule.${mod}.url` && echo Synced $mod; done"
189
193
  execute << "#{git} submodule #{verbose} sync"
190
- execute << "#{git} submodule #{verbose} update --init --recursive"
194
+ if false == variable(:git_submodules_recursive)
195
+ execute << "#{git} submodule #{verbose} update --init"
196
+ else
197
+ execute << "#{git} submodule #{verbose} update --init --recursive"
198
+ end
191
199
  end
192
200
 
193
201
  # Make sure there's nothing else lying around in the repository (for
@@ -4,13 +4,13 @@ module Capistrano
4
4
  # Represents the definition of a single task.
5
5
  class TaskDefinition
6
6
  attr_reader :name, :namespace, :options, :body, :desc, :on_error, :max_hosts
7
-
7
+
8
8
  def initialize(name, namespace, options={}, &block)
9
-
9
+
10
10
  if name.to_s =~ /^(?:before_|after_)/
11
11
  Kernel.warn("[Deprecation Warning] Naming tasks with before_ and after_ is deprecated, please see the new before() and after() methods. (Offending task name was #{name})")
12
12
  end
13
-
13
+
14
14
  @name, @namespace, @options = name, namespace, options
15
15
  @desc = @options.delete(:desc)
16
16
  @on_error = options.delete(:on_error)
@@ -18,7 +18,7 @@ module Capistrano
18
18
  @body = block or raise ArgumentError, "a task requires a block"
19
19
  @servers = nil
20
20
  end
21
-
21
+
22
22
  # Returns the task's fully-qualified name, including the namespace
23
23
  def fully_qualified_name
24
24
  @fully_qualified_name ||= begin
@@ -29,7 +29,7 @@ module Capistrano
29
29
  end
30
30
  end
31
31
  end
32
-
32
+
33
33
  # Returns the description for this task, with newlines collapsed and
34
34
  # whitespace stripped. Returns the empty string if there is no
35
35
  # description for this task.
@@ -37,7 +37,7 @@ module Capistrano
37
37
  @description = nil if rebuild
38
38
  @description ||= begin
39
39
  description = @desc || ""
40
-
40
+
41
41
  indentation = description[/\A\s+/]
42
42
  if indentation
43
43
  reformatted_description = ""
@@ -4,11 +4,11 @@ module Capistrano
4
4
  class Version
5
5
 
6
6
  MAJOR = 2
7
- MINOR = 6
8
- PATCH = 1
7
+ MINOR = 7
8
+ PATCH = 0
9
9
 
10
10
  def self.to_s
11
- "#{MAJOR}.#{MINOR}.#{PATCH}.pre"
11
+ "#{MAJOR}.#{MINOR}.#{PATCH}"
12
12
  end
13
13
 
14
14
  end
@@ -198,7 +198,7 @@ class CLIOptionsTest < Test::Unit::TestCase
198
198
 
199
199
  def test_parse_options_with_V_should_show_version_and_exit
200
200
  @cli.args << "-V"
201
- @cli.expects(:puts).with { |s| s.include?(Capistrano::Version::STRING) }
201
+ @cli.expects(:puts).with { |s| s.include?(Capistrano::Version.to_s) }
202
202
  @cli.expects(:exit).raises(ExitException)
203
203
  assert_raises(ExitException) { @cli.parse_options! }
204
204
  end
@@ -214,7 +214,9 @@ class CommandTest < Test::Unit::TestCase
214
214
  mock_session(new_channel[10]),
215
215
  mock_session(new_channel[7])]
216
216
  cmd = Capistrano::Command.new("ls", sessions)
217
- assert_nothing_raised { cmd.process! }
217
+ assert_nothing_raised do
218
+ cmd.process!
219
+ end
218
220
  end
219
221
 
220
222
  def test_process_should_instantiate_command_and_process!
@@ -240,11 +242,12 @@ class CommandTest < Test::Unit::TestCase
240
242
  private
241
243
 
242
244
  def mock_session(channel=nil)
243
- stub('session', :open_channel => channel,
244
- :preprocess => true,
245
- :postprocess => true,
246
- :listeners => {},
247
- :xserver => server("capistrano"))
245
+ stub('session',
246
+ :open_channel => channel,
247
+ :preprocess => true,
248
+ :postprocess => true,
249
+ :listeners => {},
250
+ :xserver => server("capistrano"))
248
251
  end
249
252
 
250
253
  class MockChannel < Hash
@@ -71,7 +71,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
71
71
  Net::SSH::Gateway.expects(:new).with("gateway", "user", :debug => :verbose, :port => 8080, :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
72
72
  assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
73
73
  end
74
-
74
+
75
75
  def test_connection_factory_as_gateway_should_chain_gateways_if_gateway_variable_is_an_array
76
76
  @config.values[:gateway] = ["j@gateway1", "k@gateway2"]
77
77
  gateway1 = mock
@@ -80,7 +80,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
80
80
  Net::SSH::Gateway.expects(:new).with("127.0.0.1", "k", :port => 65535, :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
81
81
  assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
82
82
  end
83
-
83
+
84
84
  def test_connection_factory_as_gateway_should_chain_gateways_if_gateway_variable_is_a_hash
85
85
  @config.values[:gateway] = { ["j@gateway1", "k@gateway2"] => :default }
86
86
  gateway1 = mock
@@ -89,7 +89,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
89
89
  Net::SSH::Gateway.expects(:new).with("127.0.0.1", "k", :port => 65535, :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
90
90
  assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
91
91
  end
92
-
92
+
93
93
  def test_connection_factory_as_gateway_should_share_gateway_between_connections
94
94
  @config.values[:gateway] = "j@gateway"
95
95
  Net::SSH::Gateway.expects(:new).once.with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
@@ -98,7 +98,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
98
98
  @config.establish_connections_to(server("capistrano"))
99
99
  @config.establish_connections_to(server("another"))
100
100
  end
101
-
101
+
102
102
  def test_connection_factory_as_gateway_should_share_gateway_between_like_connections_if_gateway_variable_is_a_hash
103
103
  @config.values[:gateway] = { "j@gateway" => [ "capistrano", "another"] }
104
104
  Net::SSH::Gateway.expects(:new).once.with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
@@ -107,7 +107,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
107
107
  @config.establish_connections_to(server("capistrano"))
108
108
  @config.establish_connections_to(server("another"))
109
109
  end
110
-
110
+
111
111
  def test_connection_factory_as_gateways_should_not_share_gateway_between_unlike_connections_if_gateway_variable_is_a_hash
112
112
  @config.values[:gateway] = { "j@gateway" => [ "capistrano", "another"], "k@gateway2" => "yafhost" }
113
113
  Net::SSH::Gateway.expects(:new).once.with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
@@ -123,23 +123,23 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
123
123
  Capistrano::SSH.expects(:connect).with { |s,| s.host == "capistrano" }.returns(:success)
124
124
  assert @config.sessions.empty?
125
125
  @config.establish_connections_to(server("capistrano"))
126
- assert ["capistrano"], @config.sessions.keys
126
+ assert_equal ["capistrano"], @config.sessions.keys.map(&:host)
127
127
  end
128
128
 
129
129
  def test_establish_connections_to_should_accept_an_array
130
130
  Capistrano::SSH.expects(:connect).times(3).returns(:success)
131
131
  assert @config.sessions.empty?
132
132
  @config.establish_connections_to(%w(cap1 cap2 cap3).map { |s| server(s) })
133
- assert %w(cap1 cap2 cap3), @config.sessions.keys.sort
133
+ assert_equal %w(cap1 cap2 cap3), @config.sessions.keys.sort.map(&:host)
134
134
  end
135
135
 
136
136
  def test_establish_connections_to_should_not_attempt_to_reestablish_existing_connections
137
137
  Capistrano::SSH.expects(:connect).times(2).returns(:success)
138
138
  @config.sessions[server("cap1")] = :ok
139
139
  @config.establish_connections_to(%w(cap1 cap2 cap3).map { |s| server(s) })
140
- assert %w(cap1 cap2 cap3), @config.sessions.keys.sort.map { |s| s.host }
140
+ assert_equal %w(cap1 cap2 cap3), @config.sessions.keys.sort.map(&:host)
141
141
  end
142
-
142
+
143
143
  def test_establish_connections_to_should_raise_one_connection_error_on_failure
144
144
  Capistrano::SSH.expects(:connect).times(2).raises(Exception)
145
145
  assert_raises(Capistrano::ConnectionError) {
@@ -149,7 +149,6 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
149
149
 
150
150
  def test_connection_error_should_include_accessor_with_host_array
151
151
  Capistrano::SSH.expects(:connect).times(2).raises(Exception)
152
-
153
152
  begin
154
153
  @config.establish_connections_to(%w(cap1 cap2).map { |s| server(s) })
155
154
  flunk "expected an exception to be raised"
@@ -158,7 +157,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
158
157
  assert_equal %w(cap1 cap2), e.hosts.map { |h| h.to_s }.sort
159
158
  end
160
159
  end
161
-
160
+
162
161
  def test_connection_error_should_only_include_failed_hosts
163
162
  Capistrano::SSH.expects(:connect).with(server('cap1'), anything).raises(Exception)
164
163
  Capistrano::SSH.expects(:connect).with(server('cap2'), anything).returns(:success)
@@ -189,6 +188,11 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
189
188
  assert_raises(Capistrano::NoMatchingServersError) { @config.execute_on_servers(:a => :b, :c => :d) { |list| } }
190
189
  end
191
190
 
191
+ def test_execute_on_servers_without_current_task_should_not_raise_error_if_no_matching_servers_and_continue_on_no_matching_servers
192
+ @config.expects(:find_servers).with(:a => :b, :c => :d, :on_no_matching_servers => :continue).returns([])
193
+ assert_nothing_raised { @config.execute_on_servers(:a => :b, :c => :d, :on_no_matching_servers => :continue) { |list| } }
194
+ end
195
+
192
196
  def test_execute_on_servers_should_raise_an_error_if_the_current_task_has_no_matching_servers_by_default
193
197
  @config.current_task = mock_task
194
198
  @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([])
@@ -198,7 +202,27 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
198
202
  end
199
203
  end
200
204
  end
201
-
205
+
206
+ def test_execute_on_servers_should_not_raise_an_error_if_the_current_task_has_no_matching_servers_by_default_and_continue_on_no_matching_servers
207
+ @config.current_task = mock_task(:on_no_matching_servers => :continue)
208
+ @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([])
209
+ assert_nothing_raised do
210
+ @config.execute_on_servers do
211
+ flunk "should not get here"
212
+ end
213
+ end
214
+ end
215
+
216
+ def test_execute_on_servers_should_not_raise_an_error_if_the_current_task_has_no_matching_servers_by_default_and_command_continues_on_no_matching_servers
217
+ @config.current_task = mock_task
218
+ @config.expects(:find_servers_for_task).with(@config.current_task, :on_no_matching_servers => :continue).returns([])
219
+ assert_nothing_raised do
220
+ @config.execute_on_servers(:on_no_matching_servers => :continue) do
221
+ flunk "should not get here"
222
+ end
223
+ end
224
+ end
225
+
202
226
  def test_execute_on_servers_should_determine_server_list_from_active_task
203
227
  assert @config.sessions.empty?
204
228
  @config.current_task = mock_task
@@ -237,7 +261,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
237
261
  assert block_called
238
262
  assert_equal %w(cap1), @config.sessions.keys.sort.map { |s| s.host }
239
263
  end
240
-
264
+
241
265
  def test_execute_servers_should_raise_connection_error_on_failure_by_default
242
266
  @config.current_task = mock_task
243
267
  @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([server("cap1")])
@@ -248,7 +272,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
248
272
  end
249
273
  end
250
274
  end
251
-
275
+
252
276
  def test_execute_servers_should_not_raise_connection_error_on_failure_with_on_errors_continue
253
277
  @config.current_task = mock_task(:on_error => :continue)
254
278
  @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([server("cap1"), server("cap2")])
@@ -260,7 +284,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
260
284
  end
261
285
  }
262
286
  end
263
-
287
+
264
288
  def test_execute_on_servers_should_not_try_to_connect_to_hosts_with_connection_errors_with_on_errors_continue
265
289
  list = [server("cap1"), server("cap2")]
266
290
  @config.current_task = mock_task(:on_error => :continue)
@@ -275,7 +299,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
275
299
  assert_equal %w(cap2), servers.map { |s| s.host }
276
300
  end
277
301
  end
278
-
302
+
279
303
  def test_execute_on_servers_should_not_try_to_connect_to_hosts_with_command_errors_with_on_errors_continue
280
304
  cap1 = server("cap1")
281
305
  cap2 = server("cap2")
@@ -292,7 +316,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
292
316
  assert_equal %w(cap2), servers.map { |s| s.host }
293
317
  end
294
318
  end
295
-
319
+
296
320
  def test_execute_on_servers_should_not_try_to_connect_to_hosts_with_transfer_errors_with_on_errors_continue
297
321
  cap1 = server("cap1")
298
322
  cap2 = server("cap2")
@@ -309,7 +333,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
309
333
  assert_equal %w(cap2), servers.map { |s| s.host }
310
334
  end
311
335
  end
312
-
336
+
313
337
  def test_connect_should_establish_connections_to_all_servers_in_scope
314
338
  assert @config.sessions.empty?
315
339
  @config.current_task = mock_task
@@ -318,7 +342,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
318
342
  @config.connect!
319
343
  assert_equal %w(cap1 cap2 cap3), @config.sessions.keys.sort.map { |s| s.host }
320
344
  end
321
-
345
+
322
346
  def test_execute_on_servers_should_only_run_on_tasks_max_hosts_hosts_at_once
323
347
  cap1 = server("cap1")
324
348
  cap2 = server("cap2")
@@ -336,7 +360,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
336
360
  end
337
361
  assert_equal 2, block_called
338
362
  end
339
-
363
+
340
364
  def test_execute_on_servers_should_only_run_on_max_hosts_hosts_at_once
341
365
  cap1 = server("cap1")
342
366
  cap2 = server("cap2")
@@ -354,7 +378,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
354
378
  end
355
379
  assert_equal 2, block_called
356
380
  end
357
-
381
+
358
382
  def test_execute_on_servers_should_cope_with_already_dropped_connections_when_attempting_to_close_them
359
383
  cap1 = server("cap1")
360
384
  cap2 = server("cap2")
@@ -372,7 +396,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
372
396
  @config.execute_on_servers {}
373
397
  @config.execute_on_servers {}
374
398
  end
375
-
399
+
376
400
  def test_connect_should_honor_once_option
377
401
  assert @config.sessions.empty?
378
402
  @config.current_task = mock_task
@@ -1,4 +1,4 @@
1
- require "utils"
1
+ require 'utils'
2
2
  require 'capistrano/configuration/loading'
3
3
 
4
4
  class ConfigurationLoadingTest < Test::Unit::TestCase
@@ -106,7 +106,7 @@ class ConfigurationLoadingTest < Test::Unit::TestCase
106
106
 
107
107
  def test_require_from_config_should_load_file_in_config_scope
108
108
  assert_nothing_raised do
109
- @config.require "#{File.dirname(__FILE__)}/../fixtures/custom"
109
+ @config.require "#{File.expand_path(File.dirname(__FILE__))}/../fixtures/custom"
110
110
  end
111
111
  assert_equal :custom, @config.ping
112
112
  end
@@ -118,14 +118,14 @@ class ConfigurationLoadingTest < Test::Unit::TestCase
118
118
  end
119
119
 
120
120
  def test_require_from_config_should_return_false_when_called_a_second_time_with_same_args
121
- assert @config.require("#{File.dirname(__FILE__)}/../fixtures/custom")
122
- assert_equal false, @config.require("#{File.dirname(__FILE__)}/../fixtures/custom")
121
+ assert @config.require("#{File.expand_path(File.dirname(__FILE__))}/../fixtures/custom")
122
+ assert_equal false, @config.require("#{File.expand_path(File.dirname(__FILE__))}/../fixtures/custom")
123
123
  end
124
-
124
+
125
125
  def test_require_in_multiple_instances_should_load_recipes_in_each_instance
126
126
  config2 = MockConfig.new
127
- @config.require "#{File.dirname(__FILE__)}/../fixtures/custom"
128
- config2.require "#{File.dirname(__FILE__)}/../fixtures/custom"
127
+ @config.require "#{File.expand_path(File.dirname(__FILE__))}/../fixtures/custom"
128
+ config2.require "#{File.expand_path(File.dirname(__FILE__))}/../fixtures/custom"
129
129
  assert_equal :custom, @config.ping
130
130
  assert_equal :custom, config2.ping
131
131
  end
@@ -0,0 +1,25 @@
1
+ require 'utils'
2
+ require 'capistrano/configuration'
3
+
4
+ class RecipesTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @config = Capistrano::Configuration.new
8
+ @config.stubs(:logger).returns(stub_everything)
9
+ end
10
+
11
+ def test_current_releases_does_not_cause_error_on_dry_run
12
+ @config.dry_run = true
13
+ @config.load 'deploy'
14
+ @config.load do
15
+ set :application, "foo"
16
+ task :dry_run_test do
17
+ fetch :current_release
18
+ end
19
+ end
20
+
21
+ assert_nothing_raised do
22
+ @config.dry_run_test
23
+ end
24
+ end
25
+ end
@@ -1,12 +1,10 @@
1
- begin
2
- require 'rubygems'
3
- require 'redgreen' unless ENV['TM_FILENAME']
4
- gem 'mocha'
5
- rescue LoadError
6
- end
1
+ require 'rubygems'
2
+ require 'bundler/setup'
7
3
 
4
+ require 'ruby-debug'
8
5
  require 'test/unit'
9
6
  require 'mocha'
7
+
10
8
  require 'capistrano/server_definition'
11
9
 
12
10
  module TestExtensions
metadata CHANGED
@@ -1,136 +1,102 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: capistrano
3
- version: !ruby/object:Gem::Version
4
- hash: 961915984
5
- prerelease: 6
6
- segments:
7
- - 2
8
- - 6
9
- - 1
10
- - pre
11
- version: 2.6.1.pre
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.7.0
5
+ prerelease:
12
6
  platform: ruby
13
- authors:
7
+ authors:
14
8
  - Jamis Buck
15
9
  - Lee Hambley
16
10
  autorequire:
17
11
  bindir: bin
18
12
  cert_chain: []
19
-
20
- date: 2011-03-22 00:00:00 +01:00
13
+ date: 2011-03-22 00:00:00.000000000 +01:00
21
14
  default_executable:
22
- dependencies:
23
- - !ruby/object:Gem::Dependency
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
24
17
  name: highline
25
- prerelease: false
26
- requirement: &id001 !ruby/object:Gem::Requirement
18
+ requirement: &2157549420 !ruby/object:Gem::Requirement
27
19
  none: false
28
- requirements:
29
- - - ">="
30
- - !ruby/object:Gem::Version
31
- hash: 3
32
- segments:
33
- - 0
34
- version: "0"
20
+ requirements:
21
+ - - ! '>='
22
+ - !ruby/object:Gem::Version
23
+ version: '0'
35
24
  type: :runtime
36
- version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
38
- name: net-ssh
39
25
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
26
+ version_requirements: *2157549420
27
+ - !ruby/object:Gem::Dependency
28
+ name: net-ssh
29
+ requirement: &2157642760 !ruby/object:Gem::Requirement
41
30
  none: false
42
- requirements:
43
- - - ">="
44
- - !ruby/object:Gem::Version
45
- hash: 19
46
- segments:
47
- - 2
48
- - 0
49
- - 14
31
+ requirements:
32
+ - - ! '>='
33
+ - !ruby/object:Gem::Version
50
34
  version: 2.0.14
51
35
  type: :runtime
52
- version_requirements: *id002
53
- - !ruby/object:Gem::Dependency
54
- name: net-sftp
55
36
  prerelease: false
56
- requirement: &id003 !ruby/object:Gem::Requirement
37
+ version_requirements: *2157642760
38
+ - !ruby/object:Gem::Dependency
39
+ name: net-sftp
40
+ requirement: &2157664760 !ruby/object:Gem::Requirement
57
41
  none: false
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- hash: 15
62
- segments:
63
- - 2
64
- - 0
65
- - 0
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
66
45
  version: 2.0.0
67
46
  type: :runtime
68
- version_requirements: *id003
69
- - !ruby/object:Gem::Dependency
70
- name: net-scp
71
47
  prerelease: false
72
- requirement: &id004 !ruby/object:Gem::Requirement
48
+ version_requirements: *2157664760
49
+ - !ruby/object:Gem::Dependency
50
+ name: net-scp
51
+ requirement: &2157664160 !ruby/object:Gem::Requirement
73
52
  none: false
74
- requirements:
75
- - - ">="
76
- - !ruby/object:Gem::Version
77
- hash: 23
78
- segments:
79
- - 1
80
- - 0
81
- - 0
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
82
56
  version: 1.0.0
83
57
  type: :runtime
84
- version_requirements: *id004
85
- - !ruby/object:Gem::Dependency
86
- name: net-ssh-gateway
87
58
  prerelease: false
88
- requirement: &id005 !ruby/object:Gem::Requirement
59
+ version_requirements: *2157664160
60
+ - !ruby/object:Gem::Dependency
61
+ name: net-ssh-gateway
62
+ requirement: &2157663580 !ruby/object:Gem::Requirement
89
63
  none: false
90
- requirements:
91
- - - ">="
92
- - !ruby/object:Gem::Version
93
- hash: 19
94
- segments:
95
- - 1
96
- - 1
97
- - 0
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
98
67
  version: 1.1.0
99
68
  type: :runtime
100
- version_requirements: *id005
101
- - !ruby/object:Gem::Dependency
102
- name: mocha
103
69
  prerelease: false
104
- requirement: &id006 !ruby/object:Gem::Requirement
70
+ version_requirements: *2157663580
71
+ - !ruby/object:Gem::Dependency
72
+ name: mocha
73
+ requirement: &2157663000 !ruby/object:Gem::Requirement
105
74
  none: false
106
- requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- hash: 3
110
- segments:
111
- - 0
112
- version: "0"
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
113
79
  type: :development
114
- version_requirements: *id006
115
- description: Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH.
116
- email:
80
+ prerelease: false
81
+ version_requirements: *2157663000
82
+ description: Capistrano is a utility and framework for executing commands in parallel
83
+ on multiple remote machines, via SSH.
84
+ email:
117
85
  - jamis@jamisbuck.org
118
86
  - lee.hambley@gmail.com
119
- executables:
87
+ executables:
120
88
  - cap
121
89
  - capify
122
90
  extensions: []
123
-
124
- extra_rdoc_files:
91
+ extra_rdoc_files:
125
92
  - README.mdown
126
- files:
93
+ files:
127
94
  - .gitignore
128
95
  - .rvmrc
129
96
  - CHANGELOG
130
97
  - Gemfile
131
98
  - README.mdown
132
99
  - Rakefile
133
- - VERSION
134
100
  - bin/cap
135
101
  - bin/capify
136
102
  - capistrano.gemspec
@@ -228,6 +194,7 @@ files:
228
194
  - test/fixtures/config.rb
229
195
  - test/fixtures/custom.rb
230
196
  - test/logger_test.rb
197
+ - test/recipes_test.rb
231
198
  - test/role_test.rb
232
199
  - test/server_definition_test.rb
233
200
  - test/shell_test.rb
@@ -238,40 +205,29 @@ files:
238
205
  has_rdoc: true
239
206
  homepage: http://github.com/capistrano/capistrano
240
207
  licenses: []
241
-
242
208
  post_install_message:
243
209
  rdoc_options: []
244
-
245
- require_paths:
210
+ require_paths:
246
211
  - lib
247
- required_ruby_version: !ruby/object:Gem::Requirement
212
+ required_ruby_version: !ruby/object:Gem::Requirement
248
213
  none: false
249
- requirements:
250
- - - ">="
251
- - !ruby/object:Gem::Version
252
- hash: 3
253
- segments:
254
- - 0
255
- version: "0"
256
- required_rubygems_version: !ruby/object:Gem::Requirement
214
+ requirements:
215
+ - - ! '>='
216
+ - !ruby/object:Gem::Version
217
+ version: '0'
218
+ required_rubygems_version: !ruby/object:Gem::Requirement
257
219
  none: false
258
- requirements:
259
- - - ">"
260
- - !ruby/object:Gem::Version
261
- hash: 25
262
- segments:
263
- - 1
264
- - 3
265
- - 1
266
- version: 1.3.1
220
+ requirements:
221
+ - - ! '>='
222
+ - !ruby/object:Gem::Version
223
+ version: '0'
267
224
  requirements: []
268
-
269
225
  rubyforge_project:
270
226
  rubygems_version: 1.6.2
271
227
  signing_key:
272
228
  specification_version: 3
273
229
  summary: Capistrano - Welcome to easy deployment with Ruby over SSH
274
- test_files:
230
+ test_files:
275
231
  - test/cli/execute_test.rb
276
232
  - test/cli/help_test.rb
277
233
  - test/cli/options_test.rb
@@ -306,6 +262,7 @@ test_files:
306
262
  - test/fixtures/config.rb
307
263
  - test/fixtures/custom.rb
308
264
  - test/logger_test.rb
265
+ - test/recipes_test.rb
309
266
  - test/role_test.rb
310
267
  - test/server_definition_test.rb
311
268
  - test/shell_test.rb
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 2.6.0