capistrano 2.3.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +50 -2
- data/lib/capistrano/cli/execute.rb +1 -0
- data/lib/capistrano/cli/options.rb +4 -0
- data/lib/capistrano/cli/ui.rb +13 -0
- data/lib/capistrano/command.rb +2 -2
- data/lib/capistrano/configuration.rb +2 -1
- data/lib/capistrano/configuration/actions/file_transfer.rb +5 -1
- data/lib/capistrano/configuration/actions/invocation.rb +45 -18
- data/lib/capistrano/configuration/callbacks.rb +3 -3
- data/lib/capistrano/configuration/execution.rb +8 -3
- data/lib/capistrano/configuration/loading.rb +20 -21
- data/lib/capistrano/recipes/deploy.rb +56 -27
- data/lib/capistrano/recipes/deploy/local_dependency.rb +6 -2
- data/lib/capistrano/recipes/deploy/remote_dependency.rb +2 -0
- data/lib/capistrano/recipes/deploy/scm/git.rb +21 -12
- data/lib/capistrano/recipes/deploy/scm/mercurial.rb +2 -1
- data/lib/capistrano/recipes/deploy/scm/subversion.rb +2 -1
- data/lib/capistrano/recipes/deploy/strategy/copy.rb +22 -34
- data/lib/capistrano/recipes/deploy/strategy/remote.rb +1 -1
- data/lib/capistrano/version.rb +1 -14
- data/test/cli/execute_test.rb +1 -1
- data/test/cli/options_test.rb +7 -1
- data/test/configuration/actions/file_transfer_test.rb +20 -1
- data/test/configuration/actions/invocation_test.rb +16 -10
- data/test/configuration/callbacks_test.rb +16 -2
- data/test/configuration/loading_test.rb +6 -1
- data/test/deploy/local_dependency_test.rb +73 -0
- data/test/deploy/remote_dependency_test.rb +114 -0
- data/test/deploy/scm/git_test.rb +22 -8
- data/test/deploy/scm/mercurial_test.rb +10 -4
- data/test/deploy/strategy/copy_test.rb +16 -11
- data/test/role_test.rb +11 -0
- data/test/server_definition_test.rb +14 -1
- metadata +5 -3
- data/test/version_test.rb +0 -24
data/CHANGELOG
CHANGED
@@ -1,6 +1,54 @@
|
|
1
|
-
*2.
|
1
|
+
*2.4.0* June 13, 2008
|
2
|
+
|
3
|
+
* Added :normalize_asset_timestamps option to deployment, defaulting to true, which allows asset timestamping to be disabled [John Trupiano]
|
4
|
+
|
5
|
+
|
6
|
+
*2.4.0 Preview Release #1* (2.3.101) June 5, 2008
|
7
|
+
|
8
|
+
* Only make deploy:start, deploy:stop, and deploy:restart try sudo as :runner. The other sudo-enabled tasks (deploy:setup, deploy:cleanup, etc.) will now use the :admin_runner user (which by default is unset). [Jamis Buck]
|
9
|
+
|
10
|
+
* Make sure triggers defined as a block inherit the scope of the task they are attached to, instead of the task they were called from [Jamis Buck]
|
11
|
+
|
12
|
+
* Make deploy:upload use the upload() helper for more efficient directory processing [Jamis Buck]
|
13
|
+
|
14
|
+
* Make deploy:upload accept globs [Mark Imbriaco]
|
15
|
+
|
16
|
+
* Make sure the host is reported with the output from scm_run [Jamis Buck]
|
17
|
+
|
18
|
+
* Make git SCM honor the :scm_verbose option [Jamis Buck]
|
19
|
+
|
20
|
+
* Don't follow symlinks when using :copy_cache [Jamis Buck]
|
21
|
+
|
22
|
+
* If :mode is given to upload() helper, do a chmod after to set the mode [Jamis Buck]
|
23
|
+
|
24
|
+
* Fix load_from_file method for windows users [Neil Wilson]
|
25
|
+
|
26
|
+
* Display a deprecation error if a remote git branch is specified [Tim Harper]
|
2
27
|
|
3
|
-
*
|
28
|
+
* Fix deployment recipes to use the updated sudo helper [Jamis Buck]
|
29
|
+
|
30
|
+
* Enhance the sudo helper so it can be used to return the command, instead of executing it [Jamis Buck]
|
31
|
+
|
32
|
+
* Revert "make sudo helper play nicely with complex command chains", since it broke stuff [Jamis Buck]
|
33
|
+
|
34
|
+
* Make set(:default_shell, false) work for not using a shell on a per-command basis [Ryan McGeary]
|
35
|
+
|
36
|
+
* Improved test coverage [Ryan McGeary]
|
37
|
+
|
38
|
+
* Fixed "coverage" take task [Ryan McGeary]
|
39
|
+
|
40
|
+
* Use upload() instead of put() with the copy strategy [Jamis Buck]
|
41
|
+
|
42
|
+
* Revert the "git fetch --tags" change, since it didn't work as expected [Jamis Buck]
|
43
|
+
|
44
|
+
* Fix deploy:pending when using git SCM [Ryan McGeary]
|
45
|
+
|
46
|
+
* Make sure deploy:check works with :none scm (which has no default command) [Jamis Buck]
|
47
|
+
|
48
|
+
* Add debug switch for enabling conditional execution of commands [Mark Imbriaco]
|
49
|
+
|
50
|
+
|
51
|
+
*2.3.0* May 2, 2008
|
4
52
|
|
5
53
|
* Make deploy:setup obey the :use_sudo and :runner directives, and generalize the :use_sudo and :runner options into a try_sudo() helper method [Jamis Buck]
|
6
54
|
|
@@ -27,6 +27,10 @@ module Capistrano
|
|
27
27
|
@option_parser ||= OptionParser.new do |opts|
|
28
28
|
opts.banner = "Usage: #{File.basename($0)} [options] action ..."
|
29
29
|
|
30
|
+
opts.on("-d", "--debug",
|
31
|
+
"Prompts before each remote command execution."
|
32
|
+
) { |value| options[:debug] = true }
|
33
|
+
|
30
34
|
opts.on("-e", "--explain TASK",
|
31
35
|
"Displays help (if available) for the task."
|
32
36
|
) { |value| options[:explain] = value }
|
data/lib/capistrano/cli/ui.rb
CHANGED
@@ -22,6 +22,19 @@ module Capistrano
|
|
22
22
|
def password_prompt(prompt="Password: ")
|
23
23
|
ui.ask(prompt) { |q| q.echo = false }
|
24
24
|
end
|
25
|
+
|
26
|
+
# Debug mode prompt
|
27
|
+
def debug_prompt(cmd)
|
28
|
+
ui.say("Preparing to execute command: #{cmd}")
|
29
|
+
prompt = "Execute ([Yes], No, Abort) "
|
30
|
+
ui.ask("#{prompt}? ") do |q|
|
31
|
+
q.overwrite = false
|
32
|
+
q.character = true
|
33
|
+
q.default = 'y'
|
34
|
+
q.validate = /(y(es)?)|(no?)|(a(bort)?|\n)/i
|
35
|
+
q.responses[:not_valid] = prompt
|
36
|
+
end
|
37
|
+
end
|
25
38
|
end
|
26
39
|
end
|
27
40
|
end
|
data/lib/capistrano/command.rb
CHANGED
@@ -82,12 +82,12 @@ module Capistrano
|
|
82
82
|
if options[:shell] == false
|
83
83
|
shell = nil
|
84
84
|
else
|
85
|
-
shell = [
|
85
|
+
shell = "#{options[:shell] || "sh"} -c"
|
86
86
|
cmd = cmd.gsub(/[$\\`"]/) { |m| "\\#{m}" }
|
87
87
|
cmd = "\"#{cmd}\""
|
88
88
|
end
|
89
89
|
|
90
|
-
command_line = [environment,
|
90
|
+
command_line = [environment, shell, cmd].compact.join(" ")
|
91
91
|
|
92
92
|
ch.exec(command_line)
|
93
93
|
ch.send_data(options[:data]) if options[:data]
|
@@ -19,9 +19,10 @@ module Capistrano
|
|
19
19
|
# define roles, and set configuration variables.
|
20
20
|
class Configuration
|
21
21
|
# The logger instance defined for this configuration.
|
22
|
-
attr_accessor :logger
|
22
|
+
attr_accessor :debug, :logger
|
23
23
|
|
24
24
|
def initialize #:nodoc:
|
25
|
+
@debug = false
|
25
26
|
@logger = Logger.new
|
26
27
|
end
|
27
28
|
|
@@ -10,7 +10,6 @@ module Capistrano
|
|
10
10
|
# set the mode on the file.
|
11
11
|
def put(data, path, options={})
|
12
12
|
opts = options.dup
|
13
|
-
opts[:permissions] = opts.delete(:mode)
|
14
13
|
upload(StringIO.new(data), path, opts)
|
15
14
|
end
|
16
15
|
|
@@ -23,7 +22,12 @@ module Capistrano
|
|
23
22
|
end
|
24
23
|
|
25
24
|
def upload(from, to, options={}, &block)
|
25
|
+
mode = options.delete(:mode)
|
26
26
|
transfer(:up, from, to, options, &block)
|
27
|
+
if mode
|
28
|
+
mode = mode.is_a?(Numeric) ? mode.to_s(8) : mode.to_s
|
29
|
+
run "chmod #{mode} #{to}"
|
30
|
+
end
|
27
31
|
end
|
28
32
|
|
29
33
|
def download(from, to, options={}, &block)
|
@@ -46,33 +46,49 @@ module Capistrano
|
|
46
46
|
block ||= self.class.default_io_proc
|
47
47
|
logger.debug "executing #{cmd.strip.inspect}"
|
48
48
|
|
49
|
+
return if debug && continue_execution(cmd) == false
|
50
|
+
|
49
51
|
options = add_default_command_options(options)
|
50
52
|
|
53
|
+
if cmd.include?(sudo)
|
54
|
+
block = sudo_behavior_callback(block)
|
55
|
+
end
|
56
|
+
|
51
57
|
execute_on_servers(options) do |servers|
|
52
58
|
targets = servers.map { |s| sessions[s] }
|
53
59
|
Command.process(cmd, targets, options.merge(:logger => logger), &block)
|
54
60
|
end
|
55
61
|
end
|
56
62
|
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
63
|
+
# Returns the command string used by capistrano to invoke a comamnd via
|
64
|
+
# sudo.
|
65
|
+
#
|
66
|
+
# run "#{sudo :as => 'bob'} mkdir /path/to/dir"
|
60
67
|
#
|
61
|
-
#
|
68
|
+
# It can also be invoked like #run, but executing the command via sudo.
|
69
|
+
# This assumes that the sudo password (if required) is the same as the
|
70
|
+
# password for logging in to the server.
|
71
|
+
#
|
72
|
+
# sudo "mkdir /path/to/dir"
|
73
|
+
#
|
74
|
+
# Also, this method understands a <tt>:sudo</tt> configuration variable,
|
62
75
|
# which (if specified) will be used as the full path to the sudo
|
63
76
|
# executable on the remote machine:
|
64
77
|
#
|
65
78
|
# set :sudo, "/opt/local/bin/sudo"
|
66
|
-
def sudo(
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
79
|
+
def sudo(*parameters, &block)
|
80
|
+
options = parameters.last.is_a?(Hash) ? parameters.pop.dup : {}
|
81
|
+
command = parameters.first
|
82
|
+
user = options[:as] && "-u #{options.delete(:as)}"
|
83
|
+
|
84
|
+
sudo_command = [fetch(:sudo, "sudo"), "-p '#{sudo_prompt}'", user].compact.join(" ")
|
85
|
+
|
86
|
+
if command
|
87
|
+
command = sudo_command + " " + command
|
88
|
+
run(command, options, &block)
|
89
|
+
else
|
90
|
+
return sudo_command
|
91
|
+
end
|
76
92
|
end
|
77
93
|
|
78
94
|
# Returns a Proc object that defines the behavior of the sudo
|
@@ -88,13 +104,13 @@ module Capistrano
|
|
88
104
|
Proc.new do |ch, stream, out|
|
89
105
|
if out =~ /^#{Regexp.escape(sudo_prompt)}/
|
90
106
|
ch.send_data "#{self[:password]}\n"
|
91
|
-
elsif out =~
|
107
|
+
elsif out =~ /^Sorry, try again/
|
92
108
|
if prompt_host.nil? || prompt_host == ch[:server]
|
93
109
|
prompt_host = ch[:server]
|
94
110
|
logger.important out, "#{stream} :: #{ch[:server]}"
|
95
111
|
reset! :password
|
96
112
|
end
|
97
|
-
|
113
|
+
elsif fallback
|
98
114
|
fallback.call(ch, stream, out)
|
99
115
|
end
|
100
116
|
end
|
@@ -119,7 +135,7 @@ module Capistrano
|
|
119
135
|
options[:env] = env unless env.empty?
|
120
136
|
|
121
137
|
shell = options[:shell] || self[:default_shell]
|
122
|
-
options[:shell] = shell
|
138
|
+
options[:shell] = shell unless shell.nil?
|
123
139
|
|
124
140
|
options
|
125
141
|
end
|
@@ -128,7 +144,18 @@ module Capistrano
|
|
128
144
|
def sudo_prompt
|
129
145
|
fetch(:sudo_prompt, "sudo password: ")
|
130
146
|
end
|
147
|
+
|
148
|
+
def continue_execution(cmd)
|
149
|
+
case Capistrano::CLI.debug_prompt(cmd)
|
150
|
+
when "y"
|
151
|
+
true
|
152
|
+
when "n"
|
153
|
+
false
|
154
|
+
when "a"
|
155
|
+
exit(-1)
|
156
|
+
end
|
157
|
+
end
|
131
158
|
end
|
132
159
|
end
|
133
160
|
end
|
134
|
-
end
|
161
|
+
end
|
@@ -4,7 +4,7 @@ module Capistrano
|
|
4
4
|
class Configuration
|
5
5
|
module Callbacks
|
6
6
|
def self.included(base) #:nodoc:
|
7
|
-
%w(initialize
|
7
|
+
%w(initialize invoke_task_directly).each do |method|
|
8
8
|
base.send :alias_method, "#{method}_without_callbacks", method
|
9
9
|
base.send :alias_method, method, "#{method}_with_callbacks"
|
10
10
|
end
|
@@ -18,13 +18,13 @@ module Capistrano
|
|
18
18
|
@callbacks = {}
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
21
|
+
def invoke_task_directly_with_callbacks(task) #:nodoc:
|
22
22
|
before = find_hook(task, :before)
|
23
23
|
execute_task(before) if before
|
24
24
|
|
25
25
|
trigger :before, task
|
26
26
|
|
27
|
-
result =
|
27
|
+
result = invoke_task_directly_without_callbacks(task)
|
28
28
|
|
29
29
|
trigger :after, task
|
30
30
|
|
@@ -72,12 +72,12 @@ module Capistrano
|
|
72
72
|
task_call_frames.last.task
|
73
73
|
end
|
74
74
|
|
75
|
-
# Executes the task with the given name,
|
76
|
-
#
|
75
|
+
# Executes the task with the given name, without invoking any associated
|
76
|
+
# callbacks.
|
77
77
|
def execute_task(task)
|
78
78
|
logger.debug "executing `#{task.fully_qualified_name}'"
|
79
79
|
push_task_call_frame(task)
|
80
|
-
|
80
|
+
invoke_task_directly(task)
|
81
81
|
ensure
|
82
82
|
pop_task_call_frame
|
83
83
|
end
|
@@ -121,6 +121,11 @@ module Capistrano
|
|
121
121
|
def pop_task_call_frame
|
122
122
|
task_call_frames.pop
|
123
123
|
end
|
124
|
+
|
125
|
+
# Invokes the task's body directly, without setting up the call frame.
|
126
|
+
def invoke_task_directly(task)
|
127
|
+
task.namespace.instance_eval(&task.body)
|
128
|
+
end
|
124
129
|
end
|
125
130
|
end
|
126
131
|
end
|
@@ -140,27 +140,26 @@ module Capistrano
|
|
140
140
|
def require(*args) #:nodoc:
|
141
141
|
# look to see if this specific configuration instance has ever seen
|
142
142
|
# these arguments to require before
|
143
|
-
if
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
return result
|
157
|
-
ensure
|
158
|
-
# restore the original, so that require's can be nested
|
159
|
-
self.class.instance = original_instance
|
160
|
-
self.class.current_feature = original_feature
|
143
|
+
if @loaded_features.include?(args)
|
144
|
+
return false
|
145
|
+
end
|
146
|
+
|
147
|
+
@loaded_features << args
|
148
|
+
begin
|
149
|
+
original_instance, self.class.instance = self.class.instance, self
|
150
|
+
original_feature, self.class.current_feature = self.class.current_feature, args
|
151
|
+
|
152
|
+
result = super
|
153
|
+
if !result # file has been required previously, load up the remembered recipes
|
154
|
+
list = self.class.recipes_per_feature[args] || []
|
155
|
+
list.each { |options| load(options.merge(:reloading => true)) }
|
161
156
|
end
|
162
|
-
|
163
|
-
return
|
157
|
+
|
158
|
+
return result
|
159
|
+
ensure
|
160
|
+
# restore the original, so that require's can be nested
|
161
|
+
self.class.instance = original_instance
|
162
|
+
self.class.current_feature = original_feature
|
164
163
|
end
|
165
164
|
end
|
166
165
|
|
@@ -169,7 +168,7 @@ module Capistrano
|
|
169
168
|
# Load a recipe from the named file. If +name+ is given, the file will
|
170
169
|
# be reported using that name.
|
171
170
|
def load_from_file(file, name=nil)
|
172
|
-
file = find_file_in_load_path(file) unless file
|
171
|
+
file = find_file_in_load_path(file) unless File.file?(file)
|
173
172
|
load :string => File.read(file), :name => name || file
|
174
173
|
end
|
175
174
|
|
@@ -89,13 +89,43 @@ ensure
|
|
89
89
|
ENV[name] = saved
|
90
90
|
end
|
91
91
|
|
92
|
+
# If a command is given, this will try to execute the given command, as
|
93
|
+
# described below. Otherwise, it will return a string for use in embedding in
|
94
|
+
# another command, for executing that command as described below.
|
95
|
+
#
|
92
96
|
# If :run_method is :sudo (or :use_sudo is true), this executes the given command
|
93
|
-
# via +sudo+. Otherwise is uses +run+.
|
94
|
-
#
|
95
|
-
|
96
|
-
|
97
|
+
# via +sudo+. Otherwise is uses +run+. If :as is given as a key, it will be
|
98
|
+
# passed as the user to sudo as, if using sudo. If the :as key is not given,
|
99
|
+
# it will default to whatever the value of the :admin_runner variable is,
|
100
|
+
# which (by default) is unset.
|
101
|
+
#
|
102
|
+
# THUS, if you want to try to run something via sudo, and what to use the
|
103
|
+
# root user, you'd just to try_sudo('something'). If you wanted to try_sudo as
|
104
|
+
# someone else, you'd just do try_sudo('something', :as => "bob"). If you
|
105
|
+
# always wanted sudo to run as a particular user, you could do
|
106
|
+
# set(:admin_runner, "bob").
|
107
|
+
def try_sudo(*args)
|
108
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
109
|
+
command = args.shift
|
110
|
+
raise ArgumentError, "too many arguments" if args.any?
|
111
|
+
|
112
|
+
as = options.fetch(:as, fetch(:admin_runner, nil))
|
97
113
|
via = fetch(:run_method, :sudo)
|
98
|
-
|
114
|
+
if command
|
115
|
+
invoke_command(command, :via => via, :as => as)
|
116
|
+
elsif via == :sudo
|
117
|
+
sudo(:as => as)
|
118
|
+
else
|
119
|
+
""
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Same as sudo, but tries sudo with :as set to the value of the :runner
|
124
|
+
# variable (which defaults to "app").
|
125
|
+
def try_runner(*args)
|
126
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
127
|
+
args << options.merge(:as => fetch(:runner, "app"))
|
128
|
+
try_sudo(*args)
|
99
129
|
end
|
100
130
|
|
101
131
|
# =========================================================================
|
@@ -131,7 +161,7 @@ namespace :deploy do
|
|
131
161
|
task :setup, :except => { :no_release => true } do
|
132
162
|
dirs = [deploy_to, releases_path, shared_path]
|
133
163
|
dirs += %w(system log pids).map { |d| File.join(shared_path, d) }
|
134
|
-
|
164
|
+
run "#{try_sudo} mkdir -p #{dirs.join(' ')} && #{try_sudo} chmod g+w #{dirs.join(' ')}"
|
135
165
|
end
|
136
166
|
|
137
167
|
desc <<-DESC
|
@@ -178,7 +208,9 @@ namespace :deploy do
|
|
178
208
|
symlinks to the shared directory for the log, system, and tmp/pids \
|
179
209
|
directories, and will lastly touch all assets in public/images, \
|
180
210
|
public/stylesheets, and public/javascripts so that the times are \
|
181
|
-
consistent (so that asset timestamping works).
|
211
|
+
consistent (so that asset timestamping works). This touch process \
|
212
|
+
is only carried out if the :normalize_asset_timestamps variable is \
|
213
|
+
set to true, which is the default.
|
182
214
|
DESC
|
183
215
|
task :finalize_update, :except => { :no_release => true } do
|
184
216
|
run "chmod -R g+w #{latest_release}" if fetch(:group_writable, true)
|
@@ -194,9 +226,11 @@ namespace :deploy do
|
|
194
226
|
ln -s #{shared_path}/pids #{latest_release}/tmp/pids
|
195
227
|
CMD
|
196
228
|
|
197
|
-
|
198
|
-
|
199
|
-
|
229
|
+
if fetch(:normalize_asset_timestamps, true)
|
230
|
+
stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S")
|
231
|
+
asset_paths = %w(images stylesheets javascripts).map { |p| "#{latest_release}/public/#{p}" }.join(" ")
|
232
|
+
run "find #{asset_paths} -exec touch -t #{stamp} {} ';'; true", :env => { "TZ" => "UTC" }
|
233
|
+
end
|
200
234
|
end
|
201
235
|
|
202
236
|
desc <<-DESC
|
@@ -223,24 +257,19 @@ namespace :deploy do
|
|
223
257
|
To use this task, specify the files and directories you want to copy as a \
|
224
258
|
comma-delimited list in the FILES environment variable. All directories \
|
225
259
|
will be processed recursively, with all files being pushed to the \
|
226
|
-
deployment servers.
|
227
|
-
will be ignored.
|
260
|
+
deployment servers.
|
228
261
|
|
229
262
|
$ cap deploy:upload FILES=templates,controller.rb
|
263
|
+
|
264
|
+
Dir globs are also supported:
|
265
|
+
|
266
|
+
$ cap deploy:upload FILES='config/apache/*.conf'
|
230
267
|
DESC
|
231
268
|
task :upload, :except => { :no_release => true } do
|
232
|
-
files = (ENV["FILES"] || "").
|
233
|
-
|
234
|
-
map { |f| f.strip!; File.directory?(f) ? Dir["#{f}/**/*"] : f }.
|
235
|
-
flatten.
|
236
|
-
reject { |f| File.directory?(f) || File.basename(f)[0] == ?. }
|
269
|
+
files = (ENV["FILES"] || "").split(",").map { |f| Dir[f.strip] }.flatten
|
270
|
+
abort "Please specify at least one file or directory to update (via the FILES environment variable)" if files.empty?
|
237
271
|
|
238
|
-
|
239
|
-
|
240
|
-
files.each do |file|
|
241
|
-
content = File.open(file, "rb") { |f| f.read }
|
242
|
-
put content, File.join(current_path, file)
|
243
|
-
end
|
272
|
+
files.each { |file| top.upload(file, File.join(current_path, file)) }
|
244
273
|
end
|
245
274
|
|
246
275
|
desc <<-DESC
|
@@ -255,7 +284,7 @@ namespace :deploy do
|
|
255
284
|
set :use_sudo, false
|
256
285
|
DESC
|
257
286
|
task :restart, :roles => :app, :except => { :no_release => true } do
|
258
|
-
|
287
|
+
try_runner "#{current_path}/script/process/reaper"
|
259
288
|
end
|
260
289
|
|
261
290
|
desc <<-DESC
|
@@ -413,7 +442,7 @@ namespace :deploy do
|
|
413
442
|
the :use_sudo variable to false.
|
414
443
|
DESC
|
415
444
|
task :start, :roles => :app do
|
416
|
-
|
445
|
+
run "cd #{current_path} && #{try_runner} nohup script/spin"
|
417
446
|
end
|
418
447
|
|
419
448
|
desc <<-DESC
|
@@ -428,8 +457,8 @@ namespace :deploy do
|
|
428
457
|
the :use_sudo variable to false.
|
429
458
|
DESC
|
430
459
|
task :stop, :roles => :app do
|
431
|
-
|
432
|
-
|
460
|
+
run "if [ -f #{current_path}/tmp/pids/dispatch.spawner.pid ]; then #{try_runner} #{current_path}/script/process/reaper -a kill -r dispatch.spawner.pid; fi"
|
461
|
+
try_runner "#{current_path}/script/process/reaper -a kill"
|
433
462
|
end
|
434
463
|
|
435
464
|
namespace :pending do
|