capistrano 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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