capistrano 2.4.3 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. data/CHANGELOG.rdoc +39 -0
  2. data/capistrano.gemspec +5 -5
  3. data/lib/capistrano/cli/execute.rb +1 -0
  4. data/lib/capistrano/cli/help.txt +6 -0
  5. data/lib/capistrano/cli/options.rb +26 -0
  6. data/lib/capistrano/cli/ui.rb +0 -1
  7. data/lib/capistrano/command.rb +175 -47
  8. data/lib/capistrano/configuration.rb +2 -1
  9. data/lib/capistrano/configuration/actions/invocation.rb +38 -7
  10. data/lib/capistrano/configuration/connections.rb +12 -6
  11. data/lib/capistrano/configuration/execution.rb +2 -1
  12. data/lib/capistrano/configuration/servers.rb +5 -4
  13. data/lib/capistrano/recipes/deploy.rb +45 -22
  14. data/lib/capistrano/recipes/deploy/local_dependency.rb +7 -3
  15. data/lib/capistrano/recipes/deploy/scm/cvs.rb +2 -1
  16. data/lib/capistrano/recipes/deploy/scm/none.rb +1 -1
  17. data/lib/capistrano/recipes/deploy/scm/subversion.rb +1 -1
  18. data/lib/capistrano/recipes/deploy/strategy/copy.rb +1 -1
  19. data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +10 -1
  20. data/lib/capistrano/role.rb +4 -0
  21. data/lib/capistrano/version.rb +2 -2
  22. data/test/cli/execute_test.rb +1 -1
  23. data/test/cli/options_test.rb +84 -0
  24. data/test/command_test.rb +38 -41
  25. data/test/configuration/actions/invocation_test.rb +12 -16
  26. data/test/configuration/connections_test.rb +30 -9
  27. data/test/configuration/execution_test.rb +16 -0
  28. data/test/configuration/servers_test.rb +15 -0
  29. data/test/configuration_test.rb +8 -1
  30. data/test/deploy/local_dependency_test.rb +15 -12
  31. data/test/deploy/scm/none_test.rb +35 -0
  32. data/test/deploy/strategy/copy_test.rb +13 -0
  33. metadata +3 -2
@@ -5,6 +5,7 @@ class ConfigurationActionsInvocationTest < Test::Unit::TestCase
5
5
  class MockConfig
6
6
  attr_reader :options
7
7
  attr_accessor :debug
8
+ attr_accessor :dry_run
8
9
 
9
10
  def initialize
10
11
  @options = {}
@@ -40,20 +41,10 @@ class ConfigurationActionsInvocationTest < Test::Unit::TestCase
40
41
  @config.run "ls", :foo => "bar"
41
42
  end
42
43
 
43
- def test_run_without_block_should_use_default_io_proc
44
- @config.expects(:execute_on_servers).yields(%w(s1 s2 s3).map { |s| server(s) })
45
- @config.expects(:sessions).returns(Hash.new { |h,k| h[k] = k.host.to_sym }).times(3)
46
- prepare_command("ls", [:s1, :s2, :s3], {:logger => @config.logger})
47
- MockConfig.default_io_proc = inspectable_proc
48
- @config.run "ls"
49
- end
50
-
51
- def test_run_with_block_should_use_block
52
- @config.expects(:execute_on_servers).yields(%w(s1 s2 s3).map { |s| mock(:host => s) })
53
- @config.expects(:sessions).returns(Hash.new { |h,k| h[k] = k.host.to_sym }).times(3)
54
- prepare_command("ls", [:s1, :s2, :s3], {:logger => @config.logger})
55
- MockConfig.default_io_proc = Proc.new { |a,b,c| raise "shouldn't get here" }
56
- @config.run("ls", &inspectable_proc)
44
+ def test_run_will_return_if_dry_run
45
+ @config.expects(:dry_run).returns(true)
46
+ @config.expects(:execute_on_servers).never
47
+ @config.run "ls", :foo => "bar"
57
48
  end
58
49
 
59
50
  def test_add_default_command_options_should_return_bare_options_if_there_is_no_env_or_shell_specified
@@ -175,7 +166,7 @@ class ConfigurationActionsInvocationTest < Test::Unit::TestCase
175
166
  a = mock("channel", :called => true)
176
167
  b = mock("stream", :called => true)
177
168
  c = mock("data", :called => true)
178
-
169
+
179
170
  callback[a, b, c]
180
171
  end
181
172
 
@@ -203,6 +194,11 @@ class ConfigurationActionsInvocationTest < Test::Unit::TestCase
203
194
  a = mock("channel", :called => true)
204
195
  b = mock("stream", :called => true)
205
196
  c = mock("data", :called => true)
206
- Capistrano::Command.expects(:process).with(command, sessions, options).yields(a, b, c)
197
+
198
+ compare_args = Proc.new do |tree, sess, opts|
199
+ tree.fallback.command == command && sess == sessions && opts == options
200
+ end
201
+
202
+ Capistrano::Command.expects(:process).with(&compare_args)
207
203
  end
208
204
  end
@@ -58,18 +58,36 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
58
58
  assert_equal :session, @config.connection_factory.connect_to(server)
59
59
  end
60
60
 
61
- def test_connection_factory_should_return_gateway_instance_if_gateway_variable_is_set
62
- @config.values[:gateway] = "j@capistrano"
63
- Net::SSH::Gateway.expects(:new).with("capistrano", "j", :password => nil, :auth_methods => %w(publickey hostbased)).returns(stub_everything)
61
+ def test_should_connect_through_gateway_if_gateway_variable_is_set
62
+ @config.values[:gateway] = "j@gateway"
63
+ Net::SSH::Gateway.expects(:new).with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased)).returns(stub_everything)
64
64
  assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
65
65
  end
66
66
 
67
67
  def test_connection_factory_as_gateway_should_honor_config_options
68
- @config.values[:gateway] = "capistrano"
68
+ @config.values[:gateway] = "gateway"
69
69
  @config.values.update(@ssh_options)
70
- Net::SSH::Gateway.expects(:new).with("capistrano", "user", :debug => :verbose, :port => 8080, :password => nil, :auth_methods => %w(publickey hostbased)).returns(stub_everything)
70
+ Net::SSH::Gateway.expects(:new).with("gateway", "user", :debug => :verbose, :port => 8080, :password => nil, :auth_methods => %w(publickey hostbased)).returns(stub_everything)
71
71
  assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
72
72
  end
73
+
74
+ def test_connection_factory_as_gateway_should_chain_gateways_if_gateway_variable_is_an_array
75
+ @config.values[:gateway] = ["j@gateway1", "k@gateway2"]
76
+ gateway1 = mock
77
+ Net::SSH::Gateway.expects(:new).with("gateway1", "j", :password => nil, :auth_methods => %w(publickey hostbased)).returns(gateway1)
78
+ gateway1.expects(:open).returns(65535)
79
+ Net::SSH::Gateway.expects(:new).with("127.0.0.1", "k", :port => 65535, :password => nil, :auth_methods => %w(publickey hostbased)).returns(stub_everything)
80
+ assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
81
+ end
82
+
83
+ def test_connection_factory_as_gateway_should_share_gateway_between_connections
84
+ @config.values[:gateway] = "j@gateway"
85
+ Net::SSH::Gateway.expects(:new).once.with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased)).returns(stub_everything)
86
+ Capistrano::SSH.stubs(:connect).returns(stub_everything)
87
+ assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
88
+ @config.establish_connections_to(server("capistrano"))
89
+ @config.establish_connections_to(server("another"))
90
+ end
73
91
 
74
92
  def test_establish_connections_to_should_accept_a_single_nonarray_parameter
75
93
  Capistrano::SSH.expects(:connect).with { |s,| s.host == "capistrano" }.returns(:success)
@@ -107,12 +125,13 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
107
125
  flunk "expected an exception to be raised"
108
126
  rescue Capistrano::ConnectionError => e
109
127
  assert e.respond_to?(:hosts)
110
- assert_equal %w(cap1 cap2), e.hosts.map { |h| h.to_s }
128
+ assert_equal %w(cap1 cap2), e.hosts.map { |h| h.to_s }.sort
111
129
  end
112
130
  end
113
131
 
114
132
  def test_connection_error_should_only_include_failed_hosts
115
- Capistrano::SSH.expects(:connect).times(2).raises(Exception).then.returns(:success)
133
+ Capistrano::SSH.expects(:connect).with(server('cap1'), anything).raises(Exception)
134
+ Capistrano::SSH.expects(:connect).with(server('cap2'), anything).returns(:success)
116
135
 
117
136
  begin
118
137
  @config.establish_connections_to(%w(cap1 cap2).map { |s| server(s) })
@@ -203,7 +222,8 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
203
222
  def test_execute_servers_should_not_raise_connection_error_on_failure_with_on_errors_continue
204
223
  @config.current_task = mock_task(:on_error => :continue)
205
224
  @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([server("cap1"), server("cap2")])
206
- Capistrano::SSH.expects(:connect).times(2).raises(Exception).then.returns(:success)
225
+ Capistrano::SSH.expects(:connect).with(server('cap1'), anything).raises(Exception)
226
+ Capistrano::SSH.expects(:connect).with(server('cap2'), anything).returns(:success)
207
227
  assert_nothing_raised {
208
228
  @config.execute_on_servers do |servers|
209
229
  assert_equal %w(cap2), servers.map { |s| s.host }
@@ -215,7 +235,8 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
215
235
  list = [server("cap1"), server("cap2")]
216
236
  @config.current_task = mock_task(:on_error => :continue)
217
237
  @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns(list)
218
- Capistrano::SSH.expects(:connect).times(2).raises(Exception).then.returns(:success)
238
+ Capistrano::SSH.expects(:connect).with(server('cap1'), anything).raises(Exception)
239
+ Capistrano::SSH.expects(:connect).with(server('cap2'), anything).returns(:success)
219
240
  @config.execute_on_servers do |servers|
220
241
  assert_equal %w(cap2), servers.map { |s| s.host }
221
242
  end
@@ -116,6 +116,22 @@ class ConfigurationExecutionTest < Test::Unit::TestCase
116
116
  assert @config.state[:aaa]
117
117
  end
118
118
 
119
+ def test_on_rollback_called_twice_should_result_in_last_rollback_block_being_effective
120
+ aaa = new_task(@config, :aaa) do
121
+ transaction do
122
+ on_rollback { (state[:rollback] ||= []) << :first }
123
+ on_rollback { (state[:rollback] ||= []) << :second }
124
+ raise "boom"
125
+ end
126
+ end
127
+
128
+ assert_raises(RuntimeError) do
129
+ @config.execute_task(aaa)
130
+ end
131
+
132
+ assert_equal [:second], @config.state[:rollback]
133
+ end
134
+
119
135
  def test_find_and_execute_task_should_raise_error_when_task_cannot_be_found
120
136
  @config.expects(:find_task).with("path:to:task").returns(nil)
121
137
  assert_raises(Capistrano::NoSuchTaskError) { @config.find_and_execute_task("path:to:task") }
@@ -37,6 +37,13 @@ class ConfigurationServersTest < Test::Unit::TestCase
37
37
  assert_equal %w(web1 web2).sort, @config.find_servers_for_task(task).map { |s| s.host }.sort
38
38
  end
39
39
 
40
+ def test_task_with_unknown_role_should_raise_exception
41
+ task = new_task(:testing, @config, :roles => :bogus)
42
+ assert_raises(ArgumentError) do
43
+ @config.find_servers_for_task(task)
44
+ end
45
+ end
46
+
40
47
  def test_task_with_hosts_option_should_apply_only_to_those_hosts
41
48
  task = new_task(:testing, @config, :hosts => %w(foo bar))
42
49
  assert_equal %w(foo bar).sort, @config.find_servers_for_task(task).map { |s| s.host }.sort
@@ -63,6 +70,14 @@ class ConfigurationServersTest < Test::Unit::TestCase
63
70
  ENV['HOSTS'] = nil
64
71
  end
65
72
 
73
+ def test_task_with_hosts_as_environment_variable_should_not_inspect_roles_at_all
74
+ ENV['HOSTS'] = "foo,bar"
75
+ task = new_task(:testing, @config, :roles => :bogus)
76
+ assert_equal %w(foo bar).sort, @config.find_servers_for_task(task).map { |s| s.host }.sort
77
+ ensure
78
+ ENV['HOSTS'] = nil
79
+ end
80
+
66
81
  def test_task_with_only_should_apply_only_to_matching_tasks
67
82
  task = new_task(:testing, @config, :roles => :app, :only => { :primary => true })
68
83
  assert_equal %w(app1), @config.find_servers_for_task(task).map { |s| s.host }
@@ -12,7 +12,14 @@ class ConfigurationTest < Test::Unit::TestCase
12
12
 
13
13
  def test_connections_execution_loading_namespaces_roles_and_variables_modules_should_integrate_correctly
14
14
  Capistrano::SSH.expects(:connect).with { |s,c| s.host == "www.capistrano.test" && c == @config }.returns(:session)
15
- Capistrano::Command.expects(:process).with("echo 'hello world'", [:session], :logger => @config.logger)
15
+
16
+ process_args = Proc.new do |tree, session, opts|
17
+ tree.fallback.command == "echo 'hello world'" &&
18
+ session == [:session] &&
19
+ opts == { :logger => @config.logger }
20
+ end
21
+
22
+ Capistrano::Command.expects(:process).with(&process_args)
16
23
 
17
24
  @config.load do
18
25
  role :test, "www.capistrano.test"
@@ -6,68 +6,71 @@ class LocalDependencyTest < Test::Unit::TestCase
6
6
  @config = { }
7
7
  @dependency = Capistrano::Deploy::LocalDependency.new(@config)
8
8
  end
9
-
9
+
10
10
  def test_should_use_standard_error_message
11
11
  setup_for_one_path_entry(false)
12
12
  @dependency.command("cat")
13
13
  assert_equal "`cat' could not be found in the path on the local host", @dependency.message
14
14
  end
15
-
15
+
16
16
  def test_should_use_alternative_message_if_provided
17
17
  setup_for_one_path_entry(false)
18
18
  @dependency.command("cat").or("Sorry")
19
19
  assert_equal "Sorry", @dependency.message
20
20
  end
21
-
21
+
22
22
  def test_env_with_no_path_should_never_find_command
23
23
  ENV.expects(:[]).with("PATH").returns(nil)
24
24
  assert !@dependency.command("cat").pass?
25
25
  end
26
-
26
+
27
27
  def test_env_with_one_path_entry_should_fail_if_command_not_found
28
28
  setup_for_one_path_entry(false)
29
29
  assert !@dependency.command("cat").pass?
30
30
  end
31
-
31
+
32
32
  def test_env_with_one_path_entry_should_pass_if_command_found
33
33
  setup_for_one_path_entry(true)
34
34
  assert @dependency.command("cat").pass?
35
35
  end
36
-
36
+
37
37
  def test_env_with_three_path_entries_should_fail_if_command_not_found
38
38
  setup_for_three_path_entries(false)
39
39
  assert !@dependency.command("cat").pass?
40
40
  end
41
-
41
+
42
42
  def test_env_with_three_path_entries_should_pass_if_command_found
43
43
  setup_for_three_path_entries(true)
44
44
  assert @dependency.command("cat").pass?
45
45
  end
46
-
46
+
47
47
  def test_env_with_one_path_entry_on_windows_should_pass_if_command_found_with_extension
48
48
  setup_for_one_path_entry_on_windows(true)
49
49
  assert @dependency.command("cat").pass?
50
50
  end
51
-
51
+
52
52
  private
53
53
 
54
54
  def setup_for_one_path_entry(command_found)
55
+ Capistrano::Deploy::LocalDependency.expects(:on_windows?).returns(false)
55
56
  ENV.expects(:[]).with("PATH").returns("/bin")
56
57
  File.expects(:executable?).with("/bin/cat").returns(command_found)
57
58
  end
58
-
59
+
59
60
  def setup_for_three_path_entries(command_found)
61
+ Capistrano::Deploy::LocalDependency.expects(:on_windows?).returns(false)
60
62
  path = %w(/bin /usr/bin /usr/local/bin).join(File::PATH_SEPARATOR)
61
63
  ENV.expects(:[]).with("PATH").returns(path)
62
64
  File.expects(:executable?).with("/usr/bin/cat").returns(command_found)
63
65
  File.expects(:executable?).at_most(1).with("/bin/cat").returns(false)
64
66
  File.expects(:executable?).at_most(1).with("/usr/local/bin/cat").returns(false)
65
67
  end
66
-
68
+
67
69
  def setup_for_one_path_entry_on_windows(command_found)
68
70
  Capistrano::Deploy::LocalDependency.expects(:on_windows?).returns(true)
69
71
  ENV.expects(:[]).with("PATH").returns("/cygwin/bin")
70
72
  File.stubs(:executable?).returns(false)
71
- File.expects(:executable?).with("/cygwin/bin/cat.exe").returns(command_found)
73
+ first_executable_extension = Capistrano::Deploy::LocalDependency.windows_executable_extensions.first
74
+ File.expects(:executable?).with("/cygwin/bin/cat#{first_executable_extension}").returns(command_found)
72
75
  end
73
76
  end
@@ -0,0 +1,35 @@
1
+ require 'utils'
2
+ require 'capistrano/recipes/deploy/scm/none'
3
+
4
+ class DeploySCMNoneTest < Test::Unit::TestCase
5
+ class TestSCM < Capistrano::Deploy::SCM::None
6
+ default_command 'none'
7
+ end
8
+
9
+ def setup
10
+ @config = {}
11
+ def @config.exists?(name); key?(name); end
12
+ @source = TestSCM.new(@config)
13
+ end
14
+
15
+ def test_the_truth
16
+ assert true
17
+ end
18
+
19
+ def test_checkout_on_linux
20
+ Capistrano::Deploy::LocalDependency.stubs(:on_windows?).returns(false)
21
+ @config[:repository] = '.'
22
+ rev = ''
23
+ dest = '/var/www'
24
+ assert_equal "cp -R . /var/www", @source.checkout(rev, dest)
25
+ end
26
+
27
+ def test_checkout_on_windows
28
+ Capistrano::Deploy::LocalDependency.stubs(:on_windows?).returns(true)
29
+ @config[:repository] = '.'
30
+ rev = ''
31
+ dest = 'c:/Documents and settings/admin/tmp'
32
+ assert_equal "xcopy . \"c:/Documents and settings/admin/tmp\" /S/I/Y/Q/E", @source.checkout(rev, dest)
33
+ end
34
+
35
+ end
@@ -29,6 +29,19 @@ class DeployStrategyCopyTest < Test::Unit::TestCase
29
29
  Dir.expects(:tmpdir).returns("/temp/dir")
30
30
  @source.expects(:checkout).with("154", "/temp/dir/1234567890").returns(:local_checkout)
31
31
  @strategy.expects(:system).with(:local_checkout)
32
+ Dir.expects(:glob).with("/temp/dir/1234567890/.git", File::FNM_DOTMATCH).returns("/temp/dir/1234567890/.git")
33
+
34
+ FileUtils.expects(:rm_rf).with("/temp/dir/1234567890/.git")
35
+ prepare_standard_compress_and_copy!
36
+ @strategy.deploy!
37
+ end
38
+
39
+ def test_deploy_with_exclusions_should_remove_glob_patterns_from_destination
40
+ @config[:copy_exclude] = ".gi*"
41
+ Dir.expects(:tmpdir).returns("/temp/dir")
42
+ @source.expects(:checkout).with("154", "/temp/dir/1234567890").returns(:local_checkout)
43
+ @strategy.expects(:system).with(:local_checkout)
44
+ Dir.expects(:glob).with("/temp/dir/1234567890/.gi*", File::FNM_DOTMATCH).returns("/temp/dir/1234567890/.git")
32
45
 
33
46
  FileUtils.expects(:rm_rf).with("/temp/dir/1234567890/.git")
34
47
  prepare_standard_compress_and_copy!
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.3
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamis Buck
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-06-28 00:00:00 -06:00
12
+ date: 2008-08-28 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -293,6 +293,7 @@ test_files:
293
293
  - test/deploy/scm/base_test.rb
294
294
  - test/deploy/scm/git_test.rb
295
295
  - test/deploy/scm/mercurial_test.rb
296
+ - test/deploy/scm/none_test.rb
296
297
  - test/deploy/strategy/copy_test.rb
297
298
  - test/extensions_test.rb
298
299
  - test/logger_test.rb