capistrano 2.4.3 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +39 -0
- data/capistrano.gemspec +5 -5
- data/lib/capistrano/cli/execute.rb +1 -0
- data/lib/capistrano/cli/help.txt +6 -0
- data/lib/capistrano/cli/options.rb +26 -0
- data/lib/capistrano/cli/ui.rb +0 -1
- data/lib/capistrano/command.rb +175 -47
- data/lib/capistrano/configuration.rb +2 -1
- data/lib/capistrano/configuration/actions/invocation.rb +38 -7
- data/lib/capistrano/configuration/connections.rb +12 -6
- data/lib/capistrano/configuration/execution.rb +2 -1
- data/lib/capistrano/configuration/servers.rb +5 -4
- data/lib/capistrano/recipes/deploy.rb +45 -22
- data/lib/capistrano/recipes/deploy/local_dependency.rb +7 -3
- data/lib/capistrano/recipes/deploy/scm/cvs.rb +2 -1
- data/lib/capistrano/recipes/deploy/scm/none.rb +1 -1
- data/lib/capistrano/recipes/deploy/scm/subversion.rb +1 -1
- data/lib/capistrano/recipes/deploy/strategy/copy.rb +1 -1
- data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +10 -1
- data/lib/capistrano/role.rb +4 -0
- data/lib/capistrano/version.rb +2 -2
- data/test/cli/execute_test.rb +1 -1
- data/test/cli/options_test.rb +84 -0
- data/test/command_test.rb +38 -41
- data/test/configuration/actions/invocation_test.rb +12 -16
- data/test/configuration/connections_test.rb +30 -9
- data/test/configuration/execution_test.rb +16 -0
- data/test/configuration/servers_test.rb +15 -0
- data/test/configuration_test.rb +8 -1
- data/test/deploy/local_dependency_test.rb +15 -12
- data/test/deploy/scm/none_test.rb +35 -0
- data/test/deploy/strategy/copy_test.rb +13 -0
- metadata +3 -2
@@ -23,21 +23,27 @@ module Capistrano
|
|
23
23
|
|
24
24
|
class GatewayConnectionFactory #:nodoc:
|
25
25
|
def initialize(gateway, options)
|
26
|
-
Thread.abort_on_exception = true
|
27
|
-
server = ServerDefinition.new(gateway)
|
28
|
-
|
29
26
|
@options = options
|
30
|
-
@gateway
|
27
|
+
@options[:logger].debug "Creating gateway using #{[*gateway].join(', ')}" if @options[:logger]
|
28
|
+
Thread.abort_on_exception = true
|
29
|
+
@gateways = [*gateway].collect { |g| ServerDefinition.new(g) }
|
30
|
+
tunnel = SSH.connection_strategy(@gateways[0], @options) do |host, user, connect_options|
|
31
31
|
Net::SSH::Gateway.new(host, user, connect_options)
|
32
32
|
end
|
33
|
+
@gateway = (@gateways[1..-1]).inject(tunnel) do |tunnel, destination|
|
34
|
+
@options[:logger].debug "Creating tunnel to #{destination}" if @options[:logger]
|
35
|
+
local_host = ServerDefinition.new("127.0.0.1", :user => destination.user, :port => tunnel.open(destination.host, (destination.port || 22)))
|
36
|
+
SSH.connection_strategy(local_host, @options) do |host, user, connect_options|
|
37
|
+
Net::SSH::Gateway.new(host, user, connect_options)
|
38
|
+
end
|
39
|
+
end
|
33
40
|
end
|
34
|
-
|
41
|
+
|
35
42
|
def connect_to(server)
|
36
43
|
@options[:logger].debug "establishing connection to `#{server}' via gateway" if @options[:logger]
|
37
44
|
local_host = ServerDefinition.new("127.0.0.1", :user => server.user, :port => @gateway.open(server.host, server.port || 22))
|
38
45
|
session = SSH.connect(local_host, @options)
|
39
46
|
session.xserver = server
|
40
|
-
@options[:logger].trace "connected: `#{server}' (via gateway)" if @options[:logger]
|
41
47
|
session
|
42
48
|
end
|
43
49
|
end
|
@@ -60,8 +60,9 @@ module Capistrano
|
|
60
60
|
# hook will be executed.
|
61
61
|
def on_rollback(&block)
|
62
62
|
if transaction?
|
63
|
+
# don't note a new rollback request if one has already been set
|
64
|
+
rollback_requests << task_call_frames.last unless task_call_frames.last.rollback
|
63
65
|
task_call_frames.last.rollback = block
|
64
|
-
rollback_requests << task_call_frames.last
|
65
66
|
end
|
66
67
|
end
|
67
68
|
|
@@ -35,13 +35,14 @@ module Capistrano
|
|
35
35
|
# servers = find_servers :hosts => "jamis@example.host.com"
|
36
36
|
def find_servers(options={})
|
37
37
|
hosts = server_list_from(ENV['HOSTS'] || options[:hosts])
|
38
|
-
|
39
|
-
only = options[:only] || {}
|
40
|
-
except = options[:except] || {}
|
41
|
-
|
38
|
+
|
42
39
|
if hosts.any?
|
43
40
|
hosts.uniq
|
44
41
|
else
|
42
|
+
roles = role_list_from(ENV['ROLES'] || options[:roles] || self.roles.keys)
|
43
|
+
only = options[:only] || {}
|
44
|
+
except = options[:except] || {}
|
45
|
+
|
45
46
|
servers = roles.inject([]) { |list, role| list.concat(self.roles[role]) }
|
46
47
|
servers = servers.select { |server| only.all? { |key,value| server.options[key] == value } }
|
47
48
|
servers = servers.reject { |server| except.any? { |key,value| server.options[key] == value } }
|
@@ -42,6 +42,7 @@ _cset(:release_name) { set :deploy_timestamped, true; Time.now.utc.strftime
|
|
42
42
|
|
43
43
|
_cset :version_dir, "releases"
|
44
44
|
_cset :shared_dir, "shared"
|
45
|
+
_cset :shared_children, %w(system log pids)
|
45
46
|
_cset :current_dir, "current"
|
46
47
|
|
47
48
|
_cset(:releases_path) { File.join(deploy_to, version_dir) }
|
@@ -49,7 +50,7 @@ _cset(:shared_path) { File.join(deploy_to, shared_dir) }
|
|
49
50
|
_cset(:current_path) { File.join(deploy_to, current_dir) }
|
50
51
|
_cset(:release_path) { File.join(releases_path, release_name) }
|
51
52
|
|
52
|
-
_cset(:releases) { capture("ls -
|
53
|
+
_cset(:releases) { capture("ls -xt #{releases_path}").split.reverse }
|
53
54
|
_cset(:current_release) { File.join(releases_path, releases.last) }
|
54
55
|
_cset(:previous_release) { File.join(releases_path, releases[-2]) }
|
55
56
|
|
@@ -160,7 +161,7 @@ namespace :deploy do
|
|
160
161
|
DESC
|
161
162
|
task :setup, :except => { :no_release => true } do
|
162
163
|
dirs = [deploy_to, releases_path, shared_path]
|
163
|
-
dirs +=
|
164
|
+
dirs += shared_children.map { |d| File.join(shared_path, d) }
|
164
165
|
run "#{try_sudo} mkdir -p #{dirs.join(' ')} && #{try_sudo} chmod g+w #{dirs.join(' ')}"
|
165
166
|
end
|
166
167
|
|
@@ -287,28 +288,50 @@ namespace :deploy do
|
|
287
288
|
try_runner "#{current_path}/script/process/reaper"
|
288
289
|
end
|
289
290
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
291
|
+
namespace :rollback do
|
292
|
+
desc <<-DESC
|
293
|
+
[internal] Points the current symlink at the previous revision.
|
294
|
+
This is called by the rollback sequence, and should rarely (if
|
295
|
+
ever) need to be called directly.
|
296
|
+
DESC
|
297
|
+
task :revision, :except => { :no_release => true } do
|
298
|
+
if releases.length < 2
|
299
|
+
abort "could not rollback the code because there is no prior release"
|
300
|
+
else
|
301
|
+
run "rm #{current_path}; ln -s #{previous_release} #{current_path}"
|
302
|
+
end
|
301
303
|
end
|
302
|
-
end
|
303
304
|
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
305
|
+
desc <<-DESC
|
306
|
+
[internal] Removes the most recently deployed release.
|
307
|
+
This is called by the rollback sequence, and should rarely
|
308
|
+
(if ever) need to be called directly.
|
309
|
+
DESC
|
310
|
+
task :cleanup, :except => { :no_release => true } do
|
311
|
+
run "if [ `readlink #{current_path}` != #{current_release} ]; then rm -rf #{current_release}; fi"
|
312
|
+
end
|
313
|
+
|
314
|
+
desc <<-DESC
|
315
|
+
Rolls back to the previously deployed version. The `current' symlink will \
|
316
|
+
be updated to point at the previously deployed version, and then the \
|
317
|
+
current release will be removed from the servers. You'll generally want \
|
318
|
+
to call `rollback' instead, as it performs a `restart' as well.
|
319
|
+
DESC
|
320
|
+
task :code, :except => { :no_release => true } do
|
321
|
+
revision
|
322
|
+
cleanup
|
323
|
+
end
|
324
|
+
|
325
|
+
desc <<-DESC
|
326
|
+
Rolls back to a previous version and restarts. This is handy if you ever \
|
327
|
+
discover that you've deployed a lemon; `cap rollback' and you're right \
|
328
|
+
back where you were, on the previously deployed version.
|
329
|
+
DESC
|
330
|
+
task :default do
|
331
|
+
revision
|
332
|
+
restart
|
333
|
+
cleanup
|
334
|
+
end
|
312
335
|
end
|
313
336
|
|
314
337
|
desc <<-DESC
|
@@ -30,7 +30,7 @@ module Capistrano
|
|
30
30
|
# file is found that matches the parameter, this returns true.
|
31
31
|
def find_in_path(utility)
|
32
32
|
path = (ENV['PATH'] || "").split(File::PATH_SEPARATOR)
|
33
|
-
suffixes = self.class.on_windows? ?
|
33
|
+
suffixes = self.class.on_windows? ? self.class.windows_executable_extensions : [""]
|
34
34
|
|
35
35
|
path.each do |dir|
|
36
36
|
suffixes.each do |sfx|
|
@@ -41,9 +41,13 @@ module Capistrano
|
|
41
41
|
|
42
42
|
false
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
def self.on_windows?
|
46
|
-
RUBY_PLATFORM =~ /mswin/
|
46
|
+
RUBY_PLATFORM =~ /mswin|mingw/
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.windows_executable_extensions
|
50
|
+
%w(.exe .bat .com .cmd)
|
47
51
|
end
|
48
52
|
end
|
49
53
|
end
|
@@ -71,7 +71,7 @@ module Capistrano
|
|
71
71
|
revision = yield(scm(cvs_root, :log, "-r#{revision}")).
|
72
72
|
grep(/^date:/).
|
73
73
|
map { |line| line[/^date: (.*?);/, 1] }.
|
74
|
-
sort.last
|
74
|
+
sort.last + " UTC"
|
75
75
|
return revision
|
76
76
|
end
|
77
77
|
|
@@ -111,6 +111,7 @@ module Capistrano
|
|
111
111
|
|
112
112
|
# attempts to guess what type of revision we're working with
|
113
113
|
def revision_type(rev)
|
114
|
+
return :date if rev =~ /^\d{4}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2} UTC$/ # i.e 2007-05-15 08:13:25 UTC
|
114
115
|
return :date if rev =~ /^\d{4}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2}$/ # i.e 2007-05-15 08:13:25
|
115
116
|
return :revision if rev =~ /^\d/ # i.e. 1.2.1
|
116
117
|
return :tag # i.e. RELEASE_1_2
|
@@ -27,7 +27,7 @@ module Capistrano
|
|
27
27
|
# Simply does a copy from the :repository directory to the
|
28
28
|
# :destination directory.
|
29
29
|
def checkout(revision, destination)
|
30
|
-
"cp -R #{repository} #{destination}"
|
30
|
+
!Capistrano::Deploy::LocalDependency.on_windows? ? "cp -R #{repository} #{destination}" : "xcopy #{repository} \"#{destination}\" /S/I/Y/Q/E"
|
31
31
|
end
|
32
32
|
|
33
33
|
alias_method :export, :checkout
|
@@ -98,7 +98,7 @@ module Capistrano
|
|
98
98
|
username = variable(:scm_username)
|
99
99
|
return "" unless username
|
100
100
|
result = "--username #{variable(:scm_username)} "
|
101
|
-
result << "--password #{variable(:scm_password)} " unless variable(:scm_prefer_prompt)
|
101
|
+
result << "--password #{variable(:scm_password)} " unless variable(:scm_auth_cache) || variable(:scm_prefer_prompt)
|
102
102
|
result << "--no-auth-cache " unless variable(:scm_auth_cache)
|
103
103
|
result
|
104
104
|
end
|
@@ -80,7 +80,7 @@ module Capistrano
|
|
80
80
|
|
81
81
|
if copy_exclude.any?
|
82
82
|
logger.debug "processing exclusions..."
|
83
|
-
copy_exclude.each { |pattern| FileUtils.rm_rf(File.join(destination, pattern)) }
|
83
|
+
copy_exclude.each { |pattern| FileUtils.rm_rf(Dir.glob(File.join(destination, pattern), File::FNM_DOTMATCH)) }
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
@@ -38,7 +38,16 @@ module Capistrano
|
|
38
38
|
|
39
39
|
def copy_repository_cache
|
40
40
|
logger.trace "copying the cached version to #{configuration[:release_path]}"
|
41
|
-
|
41
|
+
if copy_exclude.empty?
|
42
|
+
run "cp -RPp #{repository_cache} #{configuration[:release_path]} && #{mark}"
|
43
|
+
else
|
44
|
+
exclusions = copy_exclude.map { |e| "--exclude=\"#{e}\"" }.join(' ')
|
45
|
+
run "rsync -rp #{exclusions} #{repository_cache}/* #{configuration[:release_path]} && #{mark}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def copy_exclude
|
50
|
+
@copy_exclude ||= Array(configuration.fetch(:copy_exclude, []))
|
42
51
|
end
|
43
52
|
end
|
44
53
|
|
data/lib/capistrano/role.rb
CHANGED
data/lib/capistrano/version.rb
CHANGED
data/test/cli/execute_test.rb
CHANGED
@@ -15,7 +15,7 @@ class CLIExecuteTest < Test::Unit::TestCase
|
|
15
15
|
def setup
|
16
16
|
@cli = MockCLI.new
|
17
17
|
@logger = stub_everything
|
18
|
-
@config = stub(:logger => @logger, :debug= => nil)
|
18
|
+
@config = stub(:logger => @logger, :debug= => nil, :dry_run= => nil)
|
19
19
|
@config.stubs(:set)
|
20
20
|
@config.stubs(:load)
|
21
21
|
@config.stubs(:trigger)
|
data/test/cli/options_test.rb
CHANGED
@@ -30,6 +30,18 @@ class CLIOptionsTest < Test::Unit::TestCase
|
|
30
30
|
assert @cli.options[:debug]
|
31
31
|
end
|
32
32
|
|
33
|
+
def test_parse_options_with_n_should_set_dry_run_option
|
34
|
+
@cli.args << "-n"
|
35
|
+
@cli.parse_options!
|
36
|
+
assert @cli.options[:dry_run]
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_parse_options_with_dry_run_should_set_dry_run_option
|
40
|
+
@cli.args << "--dry-run"
|
41
|
+
@cli.parse_options!
|
42
|
+
assert @cli.options[:dry_run]
|
43
|
+
end
|
44
|
+
|
33
45
|
def test_parse_options_with_e_should_set_explain_option
|
34
46
|
@cli.args << "-e" << "sample"
|
35
47
|
@cli.parse_options!
|
@@ -87,12 +99,84 @@ class CLIOptionsTest < Test::Unit::TestCase
|
|
87
99
|
assert_equal "bar", @cli.options[:pre_vars][:foo]
|
88
100
|
end
|
89
101
|
|
102
|
+
def test_S_should_coerce_digits_to_integers
|
103
|
+
@cli.args << "-S" << "foo=1234"
|
104
|
+
@cli.parse_options!
|
105
|
+
assert_equal 1234, @cli.options[:pre_vars][:foo]
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_S_should_treat_quoted_integers_as_string
|
109
|
+
@cli.args << "-S" << "foo=\"1234\""
|
110
|
+
@cli.parse_options!
|
111
|
+
assert_equal "1234", @cli.options[:pre_vars][:foo]
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_S_should_treat_digits_with_dot_as_floating_point
|
115
|
+
@cli.args << "-S" << "foo=3.1415"
|
116
|
+
@cli.parse_options!
|
117
|
+
assert_equal 3.1415, @cli.options[:pre_vars][:foo]
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_S_should_treat_true_as_boolean_true
|
121
|
+
@cli.args << "-S" << "foo=true"
|
122
|
+
@cli.parse_options!
|
123
|
+
assert_equal true, @cli.options[:pre_vars][:foo]
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_S_should_treat_false_as_boolean_false
|
127
|
+
@cli.args << "-S" << "foo=false"
|
128
|
+
@cli.parse_options!
|
129
|
+
assert_equal false, @cli.options[:pre_vars][:foo]
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_S_should_treat_nil_as_nil
|
133
|
+
@cli.args << "-S" << "foo=nil"
|
134
|
+
@cli.parse_options!
|
135
|
+
assert_equal nil, @cli.options[:pre_vars][:foo]
|
136
|
+
end
|
137
|
+
|
90
138
|
def test_parse_options_with_s_should_set_vars
|
91
139
|
@cli.args << "-s" << "foo=bar"
|
92
140
|
@cli.parse_options!
|
93
141
|
assert_equal "bar", @cli.options[:vars][:foo]
|
94
142
|
end
|
95
143
|
|
144
|
+
def test_s_should_coerce_digits_to_integers
|
145
|
+
@cli.args << "-s" << "foo=1234"
|
146
|
+
@cli.parse_options!
|
147
|
+
assert_equal 1234, @cli.options[:vars][:foo]
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_s_should_treat_quoted_integers_as_string
|
151
|
+
@cli.args << "-s" << "foo=\"1234\""
|
152
|
+
@cli.parse_options!
|
153
|
+
assert_equal "1234", @cli.options[:vars][:foo]
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_s_should_treat_digits_with_dot_as_floating_point
|
157
|
+
@cli.args << "-s" << "foo=3.1415"
|
158
|
+
@cli.parse_options!
|
159
|
+
assert_equal 3.1415, @cli.options[:vars][:foo]
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_s_should_treat_true_as_boolean_true
|
163
|
+
@cli.args << "-s" << "foo=true"
|
164
|
+
@cli.parse_options!
|
165
|
+
assert_equal true, @cli.options[:vars][:foo]
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_s_should_treat_false_as_boolean_false
|
169
|
+
@cli.args << "-s" << "foo=false"
|
170
|
+
@cli.parse_options!
|
171
|
+
assert_equal false, @cli.options[:vars][:foo]
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_s_should_treat_nil_as_nil
|
175
|
+
@cli.args << "-s" << "foo=nil"
|
176
|
+
@cli.parse_options!
|
177
|
+
assert_equal nil, @cli.options[:vars][:foo]
|
178
|
+
end
|
179
|
+
|
96
180
|
def test_parse_options_with_T_should_set_tasks_option_and_set_verbose_off
|
97
181
|
@cli.args << "-T"
|
98
182
|
@cli.parse_options!
|
data/test/command_test.rb
CHANGED
@@ -1,22 +1,21 @@
|
|
1
1
|
require "utils"
|
2
2
|
require 'capistrano/command'
|
3
|
+
require 'capistrano/configuration'
|
3
4
|
|
4
5
|
class CommandTest < Test::Unit::TestCase
|
5
6
|
def test_command_should_open_channels_on_all_sessions
|
6
|
-
s1 =
|
7
|
-
|
8
|
-
s3 = mock(:open_channel => nil)
|
9
|
-
assert_equal "ls", Capistrano::Command.new("ls", [s1, s2, s3]).command
|
7
|
+
s1, s2, s3 = mock_session, mock_session, mock_session
|
8
|
+
assert_equal "ls", Capistrano::Command.new("ls", [s1, s2, s3]).tree.fallback.command
|
10
9
|
end
|
11
10
|
|
12
11
|
def test_command_with_newlines_should_be_properly_escaped
|
13
|
-
cmd = Capistrano::Command.new("ls\necho", [
|
14
|
-
assert_equal "ls\\\necho", cmd.command
|
12
|
+
cmd = Capistrano::Command.new("ls\necho", [mock_session])
|
13
|
+
assert_equal "ls\\\necho", cmd.tree.fallback.command
|
15
14
|
end
|
16
15
|
|
17
16
|
def test_command_with_windows_newlines_should_be_properly_escaped
|
18
|
-
cmd = Capistrano::Command.new("ls\r\necho", [
|
19
|
-
assert_equal "ls\\\necho", cmd.command
|
17
|
+
cmd = Capistrano::Command.new("ls\r\necho", [mock_session])
|
18
|
+
assert_equal "ls\\\necho", cmd.tree.fallback.command
|
20
19
|
end
|
21
20
|
|
22
21
|
def test_command_with_pty_should_request_pty_and_register_success_callback
|
@@ -76,25 +75,17 @@ class CommandTest < Test::Unit::TestCase
|
|
76
75
|
end
|
77
76
|
|
78
77
|
def test_open_channel_should_set_host_key_on_channel
|
79
|
-
|
80
|
-
channel =
|
81
|
-
|
82
|
-
session.expects(:open_channel).yields(channel)
|
83
|
-
channel.expects(:[]=).with(:host, "capistrano")
|
84
|
-
channel.stubs(:[]).with(:host).returns("capistrano")
|
85
|
-
|
78
|
+
channel = nil
|
79
|
+
session = setup_for_extracting_channel_action { |ch| channel = ch }
|
86
80
|
Capistrano::Command.new("ls", [session])
|
81
|
+
assert_equal "capistrano", channel[:host]
|
87
82
|
end
|
88
83
|
|
89
84
|
def test_open_channel_should_set_options_key_on_channel
|
90
|
-
|
91
|
-
channel =
|
92
|
-
|
93
|
-
session.expects(:open_channel).yields(channel)
|
94
|
-
channel.expects(:[]=).with(:options, {:data => "here we go"})
|
95
|
-
channel.stubs(:[]).with(:host).returns("capistrano")
|
96
|
-
|
85
|
+
channel = nil
|
86
|
+
session = setup_for_extracting_channel_action { |ch| channel = ch }
|
97
87
|
Capistrano::Command.new("ls", [session], :data => "here we go")
|
88
|
+
assert_equal({ :data => 'here we go' }, channel[:options])
|
98
89
|
end
|
99
90
|
|
100
91
|
def test_successful_channel_should_send_command
|
@@ -157,17 +148,17 @@ class CommandTest < Test::Unit::TestCase
|
|
157
148
|
|
158
149
|
def test_on_request_should_record_exit_status
|
159
150
|
data = mock(:read_long => 5)
|
160
|
-
|
161
|
-
|
162
|
-
end
|
151
|
+
channel = nil
|
152
|
+
session = setup_for_extracting_channel_action([:on_request, "exit-status"], data) { |ch| channel = ch }
|
163
153
|
Capistrano::Command.new("ls", [session])
|
154
|
+
assert_equal 5, channel[:status]
|
164
155
|
end
|
165
156
|
|
166
157
|
def test_on_close_should_set_channel_closed
|
167
|
-
|
168
|
-
|
169
|
-
end
|
158
|
+
channel = nil
|
159
|
+
session = setup_for_extracting_channel_action(:on_close) { |ch| channel = ch }
|
170
160
|
Capistrano::Command.new("ls", [session])
|
161
|
+
assert channel[:closed]
|
171
162
|
end
|
172
163
|
|
173
164
|
def test_stop_should_close_all_open_channels
|
@@ -228,10 +219,8 @@ class CommandTest < Test::Unit::TestCase
|
|
228
219
|
|
229
220
|
def test_process_should_instantiate_command_and_process!
|
230
221
|
cmd = mock("command", :process! => nil)
|
231
|
-
Capistrano::Command.expects(:new).with("ls -l", %w(a b c), {:foo => "bar"}).
|
232
|
-
|
233
|
-
Capistrano::Command.process("ls -l", %w(a b c), :foo => "bar") { |cmd| parameter = cmd }
|
234
|
-
assert_equal :command, parameter
|
222
|
+
Capistrano::Command.expects(:new).with("ls -l", %w(a b c), {:foo => "bar"}).returns(cmd)
|
223
|
+
Capistrano::Command.process("ls -l", %w(a b c), :foo => "bar")
|
235
224
|
end
|
236
225
|
|
237
226
|
def test_process_with_host_placeholder_should_substitute_placeholder_with_each_host
|
@@ -254,16 +243,20 @@ class CommandTest < Test::Unit::TestCase
|
|
254
243
|
stub('session', :open_channel => channel,
|
255
244
|
:preprocess => true,
|
256
245
|
:postprocess => true,
|
257
|
-
:listeners => {}
|
246
|
+
:listeners => {},
|
247
|
+
:xserver => server("capistrano"))
|
248
|
+
end
|
249
|
+
|
250
|
+
class MockChannel < Hash
|
251
|
+
def close
|
252
|
+
end
|
258
253
|
end
|
259
254
|
|
260
255
|
def new_channel(closed, status=nil)
|
261
|
-
ch =
|
262
|
-
ch.
|
263
|
-
ch
|
256
|
+
ch = MockChannel.new
|
257
|
+
ch.update({ :closed => closed, :host => "capistrano", :server => server("capistrano") })
|
258
|
+
ch[:status] = status if status
|
264
259
|
ch.expects(:close) unless closed
|
265
|
-
ch.stubs(:[]).with(:host).returns("capistrano")
|
266
|
-
ch.stubs(:[]).with(:server).returns(server("capistrano"))
|
267
260
|
ch
|
268
261
|
end
|
269
262
|
|
@@ -271,11 +264,15 @@ class CommandTest < Test::Unit::TestCase
|
|
271
264
|
s = server("capistrano")
|
272
265
|
session = mock("session", :xserver => s)
|
273
266
|
|
274
|
-
channel =
|
267
|
+
channel = {}
|
275
268
|
session.expects(:open_channel).yields(channel)
|
276
269
|
|
277
|
-
channel.stubs(:
|
278
|
-
channel.stubs(:
|
270
|
+
channel.stubs(:on_data)
|
271
|
+
channel.stubs(:on_extended_data)
|
272
|
+
channel.stubs(:on_request)
|
273
|
+
channel.stubs(:on_close)
|
274
|
+
channel.stubs(:exec)
|
275
|
+
channel.stubs(:send_data)
|
279
276
|
|
280
277
|
if action
|
281
278
|
action = Array(action)
|