1
0
Fork 0
mirror of https://github.com/capistrano/capistrano synced 2023-03-27 23:21:18 -04:00

Invoke all commands via sh (customizable via :default_shell)

git-svn-id: http://svn.rubyonrails.org/rails/tools/capistrano@6947 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Jamis Buck 2007-06-05 16:10:01 +00:00
parent ef0c790bd5
commit 7b2458ec46
5 changed files with 49 additions and 19 deletions

View file

@ -1,5 +1,7 @@
*SVN*
* Invoke all commands via sh (customizable via :default_shell) [Jamis Buck]
* Make sure all directories exist on each deploy which are necessary for subsequent commands to succeed, since some SCM's won't save empty directories [Matthew Elder]
* Add :default_environment variable, which is applied to every command

View file

@ -87,7 +87,9 @@ module Capistrano
channel.on_success do |ch|
logger.trace "executing command", ch[:server] if logger
ch.exec(replace_placeholders(command, ch))
escaped = replace_placeholders(command, ch).gsub(/["\\]/) { |m| "\\#{m}" }
shell = options[:shell] || "sh"
ch.exec("#{shell} -c \"#{escaped}\"")
ch.send_data(options[:data]) if options[:data]
end

View file

@ -45,7 +45,7 @@ module Capistrano
block ||= self.class.default_io_proc
logger.debug "executing #{cmd.strip.inspect}"
options = add_default_environment(options)
options = add_default_command_options(options)
execute_on_servers(options) do |servers|
targets = servers.map { |s| sessions[s] }
@ -99,17 +99,26 @@ module Capistrano
end
end
# Merges the default environment into options as the :env key. If the
# :env key already exists, the :env key is merged into default_environment
# and then added back into options.
def add_default_environment(options)
return options if self[:default_environment].empty?
# Merges the various default command options into the options hash and
# returns the result. The default command options that are understand
# are:
#
# * :default_environment: If the :env key already exists, the :env
# key is merged into default_environment and then added back into
# options.
# * :default_shell: if the :shell key already exists, it will be used.
# Otherwise, if the :default_shell key exists in the configuration,
# it will be used. Otherwise, no :shell key is added.
def add_default_command_options(options)
options = options.dup
env = self[:default_environment]
env = env.merge(options[:env]) if options[:env]
options[:env] = env unless env.empty?
shell = options[:shell] || self[:default_shell]
options[:shell] = shell if shell
options[:env] = env
options
end
end

View file

@ -84,14 +84,21 @@ class CommandTest < Test::Unit::TestCase
def test_successful_channel_should_send_command
session = setup_for_extracting_channel_action(:on_success) do |ch|
ch.expects(:exec).with("ls")
ch.expects(:exec).with(%(sh -c "ls"))
end
Capistrano::Command.new("ls", [session])
end
def test_successful_channel_with_shell_option_should_send_command_via_specified_shell
session = setup_for_extracting_channel_action(:on_success) do |ch|
ch.expects(:exec).with(%(/bin/bash -c "ls"))
end
Capistrano::Command.new("ls", [session], :shell => "/bin/bash")
end
def test_successful_channel_should_send_data_if_data_key_is_present
session = setup_for_extracting_channel_action(:on_success) do |ch|
ch.expects(:exec).with("ls")
ch.expects(:exec).with(%(sh -c "ls"))
ch.expects(:send_data).with("here we go")
end
Capistrano::Command.new("ls", [session], :data => "here we go")
@ -231,14 +238,14 @@ class CommandTest < Test::Unit::TestCase
def test_process_with_host_placeholder_should_substitute_placeholder_with_each_host
session = setup_for_extracting_channel_action(:on_success) do |ch|
ch.expects(:exec).with("echo capistrano")
ch.expects(:exec).with(%(sh -c "echo capistrano"))
end
Capistrano::Command.new("echo $CAPISTRANO:HOST$", [session])
end
def test_process_with_unknown_placeholder_should_not_replace_placeholder
session = setup_for_extracting_channel_action(:on_success) do |ch|
ch.expects(:exec).with("echo $CAPISTRANO:OTHER$")
ch.expects(:exec).with(%(sh -c "echo $CAPISTRANO:OTHER$"))
end
Capistrano::Command.new("echo $CAPISTRANO:OTHER$", [session])
end

View file

@ -55,19 +55,29 @@ class ConfigurationActionsInvocationTest < Test::Unit::TestCase
@config.run("ls", &inspectable_proc)
end
def test_add_default_environment_should_simply_return_options_if_default_environment_is_blank
assert_equal({:foo => "bar"}, @config.add_default_environment(:foo => "bar"))
def test_add_default_command_options_should_return_bare_options_if_there_is_no_env_or_shell_specified
assert_equal({:foo => "bar"}, @config.add_default_command_options(:foo => "bar"))
end
def test_add_default_environment_should_merge_default_environment_as_env
def test_add_default_command_options_should_merge_default_environment_as_env
@config[:default_environment][:bang] = "baz"
assert_equal({:foo => "bar", :env => { :bang => "baz" }}, @config.add_default_environment(:foo => "bar"))
assert_equal({:foo => "bar", :env => { :bang => "baz" }}, @config.add_default_command_options(:foo => "bar"))
end
def test_add_default_environment_should_merge_env_with_default_environment
def test_add_default_command_options_should_merge_env_with_default_environment
@config[:default_environment][:bang] = "baz"
@config[:default_environment][:bacon] = "crunchy"
assert_equal({:foo => "bar", :env => { :bang => "baz", :bacon => "chunky", :flip => "flop" }}, @config.add_default_environment(:foo => "bar", :env => {:bacon => "chunky", :flip => "flop"}))
assert_equal({:foo => "bar", :env => { :bang => "baz", :bacon => "chunky", :flip => "flop" }}, @config.add_default_command_options(:foo => "bar", :env => {:bacon => "chunky", :flip => "flop"}))
end
def test_add_default_command_options_should_use_default_shell_if_present
@config.set :default_shell, "/bin/bash"
assert_equal({:foo => "bar", :shell => "/bin/bash"}, @config.add_default_command_options(:foo => "bar"))
end
def test_add_default_command_options_should_use_shell_in_preference_of_default_shell
@config.set :default_shell, "/bin/bash"
assert_equal({:foo => "bar", :shell => "/bin/sh"}, @config.add_default_command_options(:foo => "bar", :shell => "/bin/sh"))
end
def test_default_io_proc_should_log_stdout_arguments_as_info