capistrano 2.2.0 → 2.3.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 (59) hide show
  1. data/CHANGELOG +29 -0
  2. data/README +4 -7
  3. data/bin/cap +0 -0
  4. data/bin/capify +0 -0
  5. data/lib/capistrano/command.rb +32 -38
  6. data/lib/capistrano/configuration/actions/file_transfer.rb +21 -13
  7. data/lib/capistrano/configuration/actions/invocation.rb +1 -1
  8. data/lib/capistrano/configuration/connections.rb +30 -20
  9. data/lib/capistrano/errors.rb +1 -1
  10. data/lib/capistrano/processable.rb +53 -0
  11. data/lib/capistrano/recipes/deploy/remote_dependency.rb +6 -0
  12. data/lib/capistrano/recipes/deploy/scm/git.rb +26 -11
  13. data/lib/capistrano/recipes/deploy/scm/none.rb +44 -0
  14. data/lib/capistrano/recipes/deploy/strategy/base.rb +6 -0
  15. data/lib/capistrano/recipes/deploy/strategy/copy.rb +74 -3
  16. data/lib/capistrano/recipes/deploy.rb +15 -13
  17. data/lib/capistrano/role.rb +0 -14
  18. data/lib/capistrano/server_definition.rb +5 -0
  19. data/lib/capistrano/shell.rb +21 -17
  20. data/lib/capistrano/ssh.rb +24 -58
  21. data/lib/capistrano/transfer.rb +216 -0
  22. data/lib/capistrano/version.rb +1 -1
  23. data/test/cli/execute_test.rb +1 -1
  24. data/test/cli/help_test.rb +1 -1
  25. data/test/cli/options_test.rb +1 -1
  26. data/test/cli/ui_test.rb +1 -1
  27. data/test/cli_test.rb +1 -1
  28. data/test/command_test.rb +31 -51
  29. data/test/configuration/actions/file_transfer_test.rb +21 -19
  30. data/test/configuration/actions/inspect_test.rb +1 -1
  31. data/test/configuration/actions/invocation_test.rb +6 -6
  32. data/test/configuration/callbacks_test.rb +1 -1
  33. data/test/configuration/connections_test.rb +11 -12
  34. data/test/configuration/execution_test.rb +1 -1
  35. data/test/configuration/loading_test.rb +1 -1
  36. data/test/configuration/namespace_dsl_test.rb +1 -1
  37. data/test/configuration/roles_test.rb +1 -1
  38. data/test/configuration/servers_test.rb +1 -1
  39. data/test/configuration/variables_test.rb +1 -1
  40. data/test/configuration_test.rb +1 -1
  41. data/test/deploy/scm/accurev_test.rb +1 -1
  42. data/test/deploy/scm/base_test.rb +1 -1
  43. data/test/deploy/scm/git_test.rb +10 -6
  44. data/test/deploy/scm/mercurial_test.rb +1 -1
  45. data/test/deploy/strategy/copy_test.rb +120 -27
  46. data/test/extensions_test.rb +1 -1
  47. data/test/logger_test.rb +1 -1
  48. data/test/server_definition_test.rb +1 -1
  49. data/test/shell_test.rb +27 -1
  50. data/test/ssh_test.rb +27 -21
  51. data/test/task_definition_test.rb +1 -1
  52. data/test/transfer_test.rb +160 -0
  53. data/test/utils.rb +30 -34
  54. data/test/version_test.rb +1 -1
  55. metadata +26 -14
  56. data/lib/capistrano/gateway.rb +0 -131
  57. data/lib/capistrano/upload.rb +0 -152
  58. data/test/gateway_test.rb +0 -167
  59. data/test/upload_test.rb +0 -131
@@ -1,4 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/utils"
1
+ require "utils"
2
2
  require 'capistrano'
3
3
 
4
4
  class ExtensionsTest < Test::Unit::TestCase
data/test/logger_test.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/utils"
1
+ require "utils"
2
2
  require 'capistrano/logger'
3
3
  require 'stringio'
4
4
 
@@ -1,4 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/utils"
1
+ require "utils"
2
2
  require 'capistrano/server_definition'
3
3
 
4
4
  class ServerDefinitionTest < Test::Unit::TestCase
data/test/shell_test.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/utils"
1
+ require "utils"
2
2
  require 'capistrano/configuration'
3
3
  require 'capistrano/shell'
4
4
 
@@ -61,4 +61,30 @@ class ShellTest < Test::Unit::TestCase
61
61
  @shell.expects(:process_command).with("on", "app,db", "hello world")
62
62
  assert @shell.read_and_execute
63
63
  end
64
+
65
+ def test_task_command_with_bang_gets_processed_by_exec_tasks
66
+ while_testing_post_exec_commands do
67
+ @shell.expects(:read_line).returns("!deploy")
68
+ @shell.expects(:exec_tasks).with(["deploy"])
69
+ assert @shell.read_and_execute
70
+ end
71
+ end
72
+
73
+ def test_normal_command_gets_processed_by_exec_command
74
+ while_testing_post_exec_commands do
75
+ @shell.expects(:read_line).returns("uptime")
76
+ @shell.expects(:exec_command).with("uptime",nil)
77
+ @shell.expects(:connect)
78
+ assert @shell.read_and_execute
79
+ end
80
+ end
81
+
82
+
83
+ private
84
+
85
+ def while_testing_post_exec_commands(&block)
86
+ @shell.instance_variable_set(:@mutex,Mutex.new)
87
+ yield
88
+ end
89
+
64
90
  end
data/test/ssh_test.rb CHANGED
@@ -1,89 +1,95 @@
1
- require "#{File.dirname(__FILE__)}/utils"
1
+ require "utils"
2
2
  require 'capistrano/ssh'
3
3
 
4
4
  class SSHTest < Test::Unit::TestCase
5
5
  def setup
6
- @options = { :username => nil,
7
- :password => nil,
6
+ Capistrano::ServerDefinition.stubs(:default_user).returns("default-user")
7
+ @options = { :password => nil,
8
8
  :port => 22,
9
9
  :auth_methods => %w(publickey hostbased) }
10
10
  @server = server("capistrano")
11
11
  end
12
12
 
13
13
  def test_connect_with_bare_server_without_options_or_config_with_public_key_succeeding_should_only_loop_once
14
- Net::SSH.expects(:start).with(@server.host, @options).returns(success = Object.new)
14
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options).returns(success = Object.new)
15
15
  assert_equal success, Capistrano::SSH.connect(@server)
16
16
  end
17
17
 
18
18
  def test_connect_with_bare_server_without_options_with_public_key_failing_should_try_password
19
- Net::SSH.expects(:start).with(@server.host, @options).raises(Net::SSH::AuthenticationFailed)
20
- Net::SSH.expects(:start).with(@server.host, @options.merge(:password => "f4b13n", :auth_methods => %w(password keyboard-interactive))).returns(success = Object.new)
19
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options).raises(Net::SSH::AuthenticationFailed)
20
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options.merge(:password => "f4b13n", :auth_methods => %w(password keyboard-interactive))).returns(success = Object.new)
21
21
  assert_equal success, Capistrano::SSH.connect(@server, :password => "f4b13n")
22
22
  end
23
23
 
24
24
  def test_connect_with_bare_server_without_options_public_key_and_password_failing_should_raise_error
25
- Net::SSH.expects(:start).with(@server.host, @options).raises(Net::SSH::AuthenticationFailed)
26
- Net::SSH.expects(:start).with(@server.host, @options.merge(:password => "f4b13n", :auth_methods => %w(password keyboard-interactive))).raises(Net::SSH::AuthenticationFailed)
25
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options).raises(Net::SSH::AuthenticationFailed)
26
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options.merge(:password => "f4b13n", :auth_methods => %w(password keyboard-interactive))).raises(Net::SSH::AuthenticationFailed)
27
27
  assert_raises(Net::SSH::AuthenticationFailed) do
28
28
  Capistrano::SSH.connect(@server, :password => "f4b13n")
29
29
  end
30
30
  end
31
31
 
32
32
  def test_connect_with_bare_server_and_user_via_public_key_should_pass_user_to_net_ssh
33
- Net::SSH.expects(:start).with(@server.host, @options.merge(:username => "jamis")).returns(success = Object.new)
33
+ Net::SSH.expects(:start).with(@server.host, "jamis", @options).returns(success = Object.new)
34
34
  assert_equal success, Capistrano::SSH.connect(@server, :user => "jamis")
35
35
  end
36
36
 
37
37
  def test_connect_with_bare_server_and_user_via_password_should_pass_user_to_net_ssh
38
- Net::SSH.expects(:start).with(@server.host, @options.merge(:username => "jamis")).raises(Net::SSH::AuthenticationFailed)
39
- Net::SSH.expects(:start).with(@server.host, @options.merge(:username => "jamis", :password => "f4b13n", :auth_methods => %w(password keyboard-interactive))).returns(success = Object.new)
38
+ Net::SSH.expects(:start).with(@server.host, "jamis", @options).raises(Net::SSH::AuthenticationFailed)
39
+ Net::SSH.expects(:start).with(@server.host, "jamis", @options.merge(:password => "f4b13n", :auth_methods => %w(password keyboard-interactive))).returns(success = Object.new)
40
40
  assert_equal success, Capistrano::SSH.connect(@server, :user => "jamis", :password => "f4b13n")
41
41
  end
42
42
 
43
43
  def test_connect_with_bare_server_with_explicit_port_should_pass_port_to_net_ssh
44
- Net::SSH.expects(:start).with(@server.host, @options.merge(:port => 1234)).returns(success = Object.new)
44
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options.merge(:port => 1234)).returns(success = Object.new)
45
45
  assert_equal success, Capistrano::SSH.connect(@server, :port => 1234)
46
46
  end
47
47
 
48
48
  def test_connect_with_server_with_user_should_pass_user_to_net_ssh
49
49
  server = server("jamis@capistrano")
50
- Net::SSH.expects(:start).with(server.host, @options.merge(:username => "jamis")).returns(success = Object.new)
50
+ Net::SSH.expects(:start).with(server.host, "jamis", @options).returns(success = Object.new)
51
51
  assert_equal success, Capistrano::SSH.connect(server)
52
52
  end
53
53
 
54
54
  def test_connect_with_server_with_port_should_pass_port_to_net_ssh
55
55
  server = server("capistrano:1235")
56
- Net::SSH.expects(:start).with(server.host, @options.merge(:port => 1235)).returns(success = Object.new)
56
+ Net::SSH.expects(:start).with(server.host, "default-user", @options.merge(:port => 1235)).returns(success = Object.new)
57
57
  assert_equal success, Capistrano::SSH.connect(server)
58
58
  end
59
59
 
60
60
  def test_connect_with_server_with_user_and_port_should_pass_user_and_port_to_net_ssh
61
61
  server = server("jamis@capistrano:1235")
62
- Net::SSH.expects(:start).with(server.host, @options.merge(:username => "jamis", :port => 1235)).returns(success = Object.new)
62
+ Net::SSH.expects(:start).with(server.host, "jamis", @options.merge(:port => 1235)).returns(success = Object.new)
63
+ assert_equal success, Capistrano::SSH.connect(server)
64
+ end
65
+
66
+ def test_connect_with_server_with_other_ssh_options_should_pass_ssh_options_to_net_ssh
67
+ server = server("jamis@capistrano:1235", :ssh_options => { :keys => %w(some_valid_key), :auth_methods => %w(a_method), :hmac => 'none' })
68
+ Net::SSH.expects(:start).with(server.host, "jamis", @options.merge(:port => 1235, :keys => %w(some_valid_key), :auth_methods => %w(a_method), :hmac => 'none' )).returns(success = Object.new)
63
69
  assert_equal success, Capistrano::SSH.connect(server)
64
70
  end
65
71
 
66
72
  def test_connect_with_ssh_options_should_use_ssh_options
67
73
  ssh_options = { :username => "JamisMan", :port => 8125 }
68
- Net::SSH.expects(:start).with(@server.host, @options.merge(:username => "JamisMan", :port => 8125)).returns(success = Object.new)
74
+ Net::SSH.expects(:start).with(@server.host, "JamisMan", @options.merge(:port => 8125)).returns(success = Object.new)
69
75
  assert_equal success, Capistrano::SSH.connect(@server, {:ssh_options => ssh_options})
70
76
  end
71
77
 
72
78
  def test_connect_with_options_and_ssh_options_should_see_options_override_ssh_options
73
79
  ssh_options = { :username => "JamisMan", :port => 8125, :forward_agent => true }
74
- Net::SSH.expects(:start).with(@server.host, @options.merge(:username => "jamis", :port => 1235, :forward_agent => true)).returns(success = Object.new)
75
- assert_equal success, Capistrano::SSH.connect(@server, {:ssh_options => ssh_options, :user => "jamis", :port => 1235})
80
+ Net::SSH.expects(:start).with(@server.host, "jamis", @options.merge(:port => 1235, :forward_agent => true)).returns(success = Object.new)
81
+ assert_equal success, Capistrano::SSH.connect(@server, :ssh_options => ssh_options, :user => "jamis", :port => 1235)
76
82
  end
77
83
 
78
84
  def test_connect_with_ssh_options_should_see_server_options_override_ssh_options
79
85
  ssh_options = { :username => "JamisMan", :port => 8125, :forward_agent => true }
80
86
  server = server("jamis@capistrano:1235")
81
- Net::SSH.expects(:start).with(server.host, @options.merge(:username => "jamis", :port => 1235, :forward_agent => true)).returns(success = Object.new)
87
+ Net::SSH.expects(:start).with(server.host, "jamis", @options.merge(:port => 1235, :forward_agent => true)).returns(success = Object.new)
82
88
  assert_equal success, Capistrano::SSH.connect(server, {:ssh_options => ssh_options})
83
89
  end
84
90
 
85
91
  def test_connect_should_add_xserver_accessor_to_connection
86
- Net::SSH.expects(:start).with(@server.host, @options).returns(success = Object.new)
92
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options).returns(success = Object.new)
87
93
  assert_equal success, Capistrano::SSH.connect(@server)
88
94
  assert success.respond_to?(:xserver)
89
95
  assert success.respond_to?(:xserver)
@@ -91,7 +97,7 @@ class SSHTest < Test::Unit::TestCase
91
97
  end
92
98
 
93
99
  def test_connect_should_not_retry_if_custom_auth_methods_are_given
94
- Net::SSH.expects(:start).with(@server.host, @options.merge(:auth_methods => %w(publickey))).raises(Net::SSH::AuthenticationFailed)
100
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options.merge(:auth_methods => %w(publickey))).raises(Net::SSH::AuthenticationFailed)
95
101
  assert_raises(Net::SSH::AuthenticationFailed) { Capistrano::SSH.connect(@server, :ssh_options => { :auth_methods => %w(publickey) }) }
96
102
  end
97
103
  end
@@ -1,4 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/utils"
1
+ require "utils"
2
2
  require 'capistrano/task_definition'
3
3
 
4
4
  class TaskDefinitionTest < Test::Unit::TestCase
@@ -0,0 +1,160 @@
1
+ require 'utils'
2
+ require 'capistrano/transfer'
3
+
4
+ class TransferTest < Test::Unit::TestCase
5
+ def test_class_process_should_delegate_to_instance_process
6
+ Capistrano::Transfer.expects(:new).with(:up, "from", "to", %w(a b c), {}).returns(mock('transfer', :process! => nil)).yields
7
+ yielded = false
8
+ Capistrano::Transfer.process(:up, "from", "to", %w(a b c), {}) { yielded = true }
9
+ assert yielded
10
+ end
11
+
12
+ def test_default_transport_is_sftp
13
+ transfer = Capistrano::Transfer.new(:up, "from", "to", [])
14
+ assert_equal :sftp, transfer.transport
15
+ end
16
+
17
+ def test_active_is_true_when_any_sftp_transfers_are_active
18
+ returns = [false, false, true]
19
+ sessions = [session('app1', :sftp), session('app2', :sftp), session('app3', :sftp)].each { |s| s.xsftp.expects(:upload).returns(stub('operation', :active? => returns.shift)) }
20
+ transfer = Capistrano::Transfer.new(:up, "from", "to", sessions, :via => :sftp)
21
+ assert_equal true, transfer.active?
22
+ end
23
+
24
+ def test_active_is_false_when_all_sftp_transfers_are_not_active
25
+ sessions = [session('app1', :sftp), session('app2', :sftp)].each { |s| s.xsftp.expects(:upload).returns(stub('operation', :active? => false)) }
26
+ transfer = Capistrano::Transfer.new(:up, "from", "to", sessions, :via => :sftp)
27
+ assert_equal false, transfer.active?
28
+ end
29
+
30
+ def test_active_is_true_when_any_scp_transfers_are_active
31
+ returns = [false, false, true]
32
+ sessions = [session('app1', :scp), session('app2', :scp), session('app3', :scp)].each do |s|
33
+ channel = stub('channel', :[]= => nil, :active? => returns.shift)
34
+ s.scp.expects(:upload).returns(channel)
35
+ end
36
+ transfer = Capistrano::Transfer.new(:up, "from", "to", sessions, :via => :scp)
37
+ assert_equal true, transfer.active?
38
+ end
39
+
40
+ def test_active_is_false_when_all_scp_transfers_are_not_active
41
+ sessions = [session('app1', :scp), session('app2', :scp), session('app3', :scp)].each do |s|
42
+ channel = stub('channel', :[]= => nil, :active? => false)
43
+ s.scp.expects(:upload).returns(channel)
44
+ end
45
+ transfer = Capistrano::Transfer.new(:up, "from", "to", sessions, :via => :scp)
46
+ assert_equal false, transfer.active?
47
+ end
48
+
49
+ [:up, :down].each do |direction|
50
+ define_method("test_sftp_#{direction}load_from_file_to_file_should_normalize_from_and_to") do
51
+ sessions = [session('app1', :sftp), session('app2', :sftp)]
52
+
53
+ sessions.each do |session|
54
+ session.xsftp.expects("#{direction}load".to_sym).with("from-#{session.xserver.host}", "to-#{session.xserver.host}",
55
+ :properties => { :server => session.xserver, :host => session.xserver.host })
56
+ end
57
+
58
+ transfer = Capistrano::Transfer.new(direction, "from-$CAPISTRANO:HOST$", "to-$CAPISTRANO:HOST$", sessions)
59
+ end
60
+
61
+ define_method("test_scp_#{direction}load_from_file_to_file_should_normalize_from_and_to") do
62
+ sessions = [session('app1', :scp), session('app2', :scp)]
63
+
64
+ sessions.each do |session|
65
+ session.scp.expects("#{direction}load".to_sym).returns({}).with("from-#{session.xserver.host}", "to-#{session.xserver.host}", :via => :scp)
66
+ end
67
+
68
+ transfer = Capistrano::Transfer.new(direction, "from-$CAPISTRANO:HOST$", "to-$CAPISTRANO:HOST$", sessions, :via => :scp)
69
+ end
70
+ end
71
+
72
+ def test_sftp_upload_from_IO_to_file_should_clone_the_IO_for_each_connection
73
+ sessions = [session('app1', :sftp), session('app2', :sftp)]
74
+ io = StringIO.new("from here")
75
+
76
+ sessions.each do |session|
77
+ session.xsftp.expects(:upload).with do |from, to, opts|
78
+ from != io && from.is_a?(StringIO) && from.string == io.string &&
79
+ to == "/to/here-#{session.xserver.host}" &&
80
+ opts[:properties][:server] == session.xserver &&
81
+ opts[:properties][:host] == session.xserver.host
82
+ end
83
+ end
84
+
85
+ transfer = Capistrano::Transfer.new(:up, StringIO.new("from here"), "/to/here-$CAPISTRANO:HOST$", sessions)
86
+ end
87
+
88
+ def test_scp_upload_from_IO_to_file_should_clone_the_IO_for_each_connection
89
+ sessions = [session('app1', :scp), session('app2', :scp)]
90
+ io = StringIO.new("from here")
91
+
92
+ sessions.each do |session|
93
+ channel = mock('channel')
94
+ channel.expects(:[]=).with(:server, session.xserver)
95
+ channel.expects(:[]=).with(:host, session.xserver.host)
96
+ session.scp.expects(:upload).returns(channel).with do |from, to, opts|
97
+ from != io && from.is_a?(StringIO) && from.string == io.string &&
98
+ to == "/to/here-#{session.xserver.host}"
99
+ end
100
+ end
101
+
102
+ transfer = Capistrano::Transfer.new(:up, StringIO.new("from here"), "/to/here-$CAPISTRANO:HOST$", sessions, :via => :scp)
103
+ end
104
+
105
+ def test_process_should_block_until_transfer_is_no_longer_active
106
+ transfer = Capistrano::Transfer.new(:up, "from", "to", [])
107
+ transfer.expects(:process_iteration).times(4).yields.returns(true,true,true,false)
108
+ transfer.expects(:active?).times(4)
109
+ transfer.process!
110
+ end
111
+
112
+ def test_errors_raised_for_a_sftp_session_should_abort_session_and_continue_with_remaining_sessions
113
+ s = session('app1')
114
+ error = ExceptionWithSession.new(s)
115
+ transfer = Capistrano::Transfer.new(:up, "from", "to", [])
116
+ transfer.expects(:process_iteration).raises(error).times(3).returns(true, false)
117
+ txfr = mock('transfer', :abort! => true)
118
+ txfr.expects(:[]=).with(:failed, true)
119
+ txfr.expects(:[]=).with(:error, error)
120
+ transfer.expects(:session_map).returns(s => txfr)
121
+ transfer.process!
122
+ end
123
+
124
+ def test_errors_raised_for_a_scp_session_should_abort_session_and_continue_with_remaining_sessions
125
+ s = session('app1')
126
+ error = ExceptionWithSession.new(s)
127
+ transfer = Capistrano::Transfer.new(:up, "from", "to", [], :via => :scp)
128
+ transfer.expects(:process_iteration).raises(error).times(3).returns(true, false)
129
+ txfr = mock('channel', :close => true)
130
+ txfr.expects(:[]=).with(:failed, true)
131
+ txfr.expects(:[]=).with(:error, error)
132
+ transfer.expects(:session_map).returns(s => txfr)
133
+ transfer.process!
134
+ end
135
+
136
+ private
137
+
138
+ class ExceptionWithSession < ::Exception
139
+ attr_reader :session
140
+
141
+ def initialize(session)
142
+ @session = session
143
+ super()
144
+ end
145
+ end
146
+
147
+ def session(host, mode=nil)
148
+ session = stub('session', :xserver => stub('server', :host => host))
149
+ case mode
150
+ when :sftp
151
+ sftp = stub('sftp')
152
+ session.expects(:sftp).with(false).returns(sftp)
153
+ sftp.expects(:connect).yields(sftp).returns(sftp)
154
+ session.stubs(:xsftp).returns(sftp)
155
+ when :scp
156
+ session.stubs(:scp).returns(stub('scp'))
157
+ end
158
+ session
159
+ end
160
+ end
data/test/utils.rb CHANGED
@@ -1,42 +1,38 @@
1
- unless defined?(TestExtensions)
2
- $:.unshift "#{File.dirname(__FILE__)}/../lib"
3
-
4
- begin
5
- require 'rubygems'
6
- gem 'mocha'
7
- rescue LoadError
8
- end
9
-
10
- require 'test/unit'
11
- require 'mocha'
12
- require 'capistrano/server_definition'
1
+ begin
2
+ require 'rubygems'
3
+ gem 'mocha'
4
+ rescue LoadError
5
+ end
13
6
 
14
- module TestExtensions
15
- def server(host, options={})
16
- Capistrano::ServerDefinition.new(host, options)
17
- end
7
+ require 'test/unit'
8
+ require 'mocha'
9
+ require 'capistrano/server_definition'
18
10
 
19
- def namespace(fqn=nil)
20
- space = stub(:roles => {}, :fully_qualified_name => fqn, :default_task => nil)
21
- yield(space) if block_given?
22
- space
23
- end
11
+ module TestExtensions
12
+ def server(host, options={})
13
+ Capistrano::ServerDefinition.new(host, options)
14
+ end
24
15
 
25
- def role(space, name, *args)
26
- opts = args.last.is_a?(Hash) ? args.pop : {}
27
- space.roles[name] ||= []
28
- space.roles[name].concat(args.map { |h| Capistrano::ServerDefinition.new(h, opts) })
29
- end
16
+ def namespace(fqn=nil)
17
+ space = stub(:roles => {}, :fully_qualified_name => fqn, :default_task => nil)
18
+ yield(space) if block_given?
19
+ space
20
+ end
30
21
 
31
- def new_task(name, namespace=@namespace, options={}, &block)
32
- block ||= Proc.new {}
33
- task = Capistrano::TaskDefinition.new(name, namespace, options, &block)
34
- assert_equal block, task.body
35
- return task
36
- end
22
+ def role(space, name, *args)
23
+ opts = args.last.is_a?(Hash) ? args.pop : {}
24
+ space.roles[name] ||= []
25
+ space.roles[name].concat(args.map { |h| Capistrano::ServerDefinition.new(h, opts) })
37
26
  end
38
27
 
39
- class Test::Unit::TestCase
40
- include TestExtensions
28
+ def new_task(name, namespace=@namespace, options={}, &block)
29
+ block ||= Proc.new {}
30
+ task = Capistrano::TaskDefinition.new(name, namespace, options, &block)
31
+ assert_equal block, task.body
32
+ return task
41
33
  end
42
34
  end
35
+
36
+ class Test::Unit::TestCase
37
+ include TestExtensions
38
+ end
data/test/version_test.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/utils"
1
+ require "utils"
2
2
  require 'capistrano/version'
3
3
 
4
4
  class VersionTest < Test::Unit::TestCase
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.2.0
4
+ version: 2.3.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-02-27 00:00:00 -07:00
12
+ date: 2008-05-02 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -19,10 +19,7 @@ dependencies:
19
19
  requirements:
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 1.0.10
23
- - - <
24
- - !ruby/object:Gem::Version
25
- version: 1.99.0
22
+ version: 2.0.0
26
23
  version:
27
24
  - !ruby/object:Gem::Dependency
28
25
  name: net-sftp
@@ -31,10 +28,25 @@ dependencies:
31
28
  requirements:
32
29
  - - ">="
33
30
  - !ruby/object:Gem::Version
34
- version: 1.1.0
35
- - - <
31
+ version: 2.0.0
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: net-scp
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.0
41
+ version:
42
+ - !ruby/object:Gem::Dependency
43
+ name: net-ssh-gateway
44
+ version_requirement:
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
36
48
  - !ruby/object:Gem::Version
37
- version: 1.99.0
49
+ version: 1.0.0
38
50
  version:
39
51
  - !ruby/object:Gem::Dependency
40
52
  name: highline
@@ -83,8 +95,8 @@ files:
83
95
  - lib/capistrano/configuration.rb
84
96
  - lib/capistrano/errors.rb
85
97
  - lib/capistrano/extensions.rb
86
- - lib/capistrano/gateway.rb
87
98
  - lib/capistrano/logger.rb
99
+ - lib/capistrano/processable.rb
88
100
  - lib/capistrano/recipes
89
101
  - lib/capistrano/recipes/compat.rb
90
102
  - lib/capistrano/recipes/deploy
@@ -99,6 +111,7 @@ files:
99
111
  - lib/capistrano/recipes/deploy/scm/darcs.rb
100
112
  - lib/capistrano/recipes/deploy/scm/git.rb
101
113
  - lib/capistrano/recipes/deploy/scm/mercurial.rb
114
+ - lib/capistrano/recipes/deploy/scm/none.rb
102
115
  - lib/capistrano/recipes/deploy/scm/perforce.rb
103
116
  - lib/capistrano/recipes/deploy/scm/subversion.rb
104
117
  - lib/capistrano/recipes/deploy/scm.rb
@@ -122,7 +135,7 @@ files:
122
135
  - lib/capistrano/shell.rb
123
136
  - lib/capistrano/ssh.rb
124
137
  - lib/capistrano/task_definition.rb
125
- - lib/capistrano/upload.rb
138
+ - lib/capistrano/transfer.rb
126
139
  - lib/capistrano/version.rb
127
140
  - lib/capistrano.rb
128
141
  - examples/sample.rb
@@ -160,13 +173,12 @@ files:
160
173
  - test/fixtures/cli_integration.rb
161
174
  - test/fixtures/config.rb
162
175
  - test/fixtures/custom.rb
163
- - test/gateway_test.rb
164
176
  - test/logger_test.rb
165
177
  - test/server_definition_test.rb
166
178
  - test/shell_test.rb
167
179
  - test/ssh_test.rb
168
180
  - test/task_definition_test.rb
169
- - test/upload_test.rb
181
+ - test/transfer_test.rb
170
182
  - test/utils.rb
171
183
  - test/version_test.rb
172
184
  - README
@@ -194,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
206
  requirements: []
195
207
 
196
208
  rubyforge_project: capistrano
197
- rubygems_version: 1.0.0
209
+ rubygems_version: 1.1.1
198
210
  signing_key:
199
211
  specification_version: 2
200
212
  summary: Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH.
@@ -1,131 +0,0 @@
1
- if RUBY_VERSION == "1.8.6"
2
- begin
3
- require 'fastthread'
4
- rescue LoadError
5
- warn "You are running Ruby 1.8.6, which has a bug in its threading implementation."
6
- warn "You are liable to encounter deadlocks running Capistrano, unless you install"
7
- warn "the fastthread library, which is available as a gem:"
8
- warn " gem install fastthread"
9
- end
10
- end
11
-
12
- require 'thread'
13
- require 'capistrano/errors'
14
- require 'capistrano/ssh'
15
- require 'capistrano/server_definition'
16
-
17
- Thread.abort_on_exception = true
18
-
19
- module Capistrano
20
-
21
- # Black magic. It uses threads and Net::SSH to set up a connection to a
22
- # gateway server, through which connections to other servers may be
23
- # tunnelled.
24
- #
25
- # It is used internally by Capistrano, but may be useful on its own, as well.
26
- #
27
- # Usage:
28
- #
29
- # gateway = Capistrano::Gateway.new(Capistrano::ServerDefinition.new('gateway.example.com'))
30
- #
31
- # sess1 = gateway.connect_to(Capistrano::ServerDefinition.new('hidden.example.com'))
32
- # sess2 = gateway.connect_to(Capistrano::ServerDefinition.new('other.example.com'))
33
- class Gateway
34
- # The Thread instance driving the gateway connection.
35
- attr_reader :thread
36
-
37
- # The Net::SSH session representing the gateway connection.
38
- attr_reader :session
39
-
40
- MAX_PORT = 65535
41
- MIN_PORT = 1024
42
-
43
- def initialize(server, options={}) #:nodoc:
44
- @options = options
45
- @next_port = MAX_PORT
46
- @terminate_thread = false
47
- @port_guard = Mutex.new
48
-
49
- mutex = Mutex.new
50
- waiter = ConditionVariable.new
51
-
52
- mutex.synchronize do
53
- @thread = Thread.new do
54
- logger.trace "starting connection to gateway `#{server}'" if logger
55
- SSH.connect(server, @options) do |@session|
56
- logger.trace "gateway connection established" if logger
57
- mutex.synchronize { waiter.signal }
58
- @session.loop do
59
- !@terminate_thread
60
- end
61
- end
62
- end
63
-
64
- waiter.wait(mutex)
65
- end
66
- end
67
-
68
- # Shuts down all forwarded connections and terminates the gateway.
69
- def shutdown!
70
- # cancel all active forward channels
71
- session.forward.active_locals.each do |lport, host, port|
72
- session.forward.cancel_local(lport)
73
- end
74
-
75
- # terminate the gateway thread
76
- @terminate_thread = true
77
-
78
- # wait for the gateway thread to stop
79
- thread.join
80
- end
81
-
82
- # Connects to the given server by opening a forwarded port from the local
83
- # host to the server, via the gateway, and then opens and returns a new
84
- # Net::SSH connection via that port.
85
- def connect_to(server)
86
- connection = nil
87
- logger.debug "establishing connection to `#{server}' via gateway" if logger
88
- local_port = next_port
89
-
90
- thread = Thread.new do
91
- begin
92
- local_host = ServerDefinition.new("127.0.0.1", :user => server.user, :port => local_port)
93
- session.forward.local(local_port, server.host, server.port || 22)
94
- connection = SSH.connect(local_host, @options)
95
- connection.xserver = server
96
- logger.trace "connected: `#{server}' (via gateway)" if logger
97
- rescue Errno::EADDRINUSE
98
- local_port = next_port
99
- retry
100
- rescue Exception => e
101
- warn "#{e.class}: #{e.message}"
102
- warn e.backtrace.join("\n")
103
- end
104
- end
105
-
106
- thread.join
107
- if connection.nil?
108
- error = ConnectionError.new("could not establish connection to `#{server}'")
109
- error.hosts = [server]
110
- raise error
111
- end
112
-
113
- connection
114
- end
115
-
116
- private
117
-
118
- def logger
119
- @options[:logger]
120
- end
121
-
122
- def next_port
123
- @port_guard.synchronize do
124
- port = @next_port
125
- @next_port -= 1
126
- @next_port = MAX_PORT if @next_port < MIN_PORT
127
- port
128
- end
129
- end
130
- end
131
- end