Skip to content

Commit ba0d313

Browse files
committed
Remote file task
The commit introduces a `remote_file` task, allowing the existence of a remote file to be set as a prerequisite. These tasks can in turn depend on local files if required. In this implementation, the fact that we're dealing with a file in the shared path is assumed. As as example, this task can be used to ensure that files to be linked exist before running the `check:linked_files` task: namespace :deploy do namespace :check do task :linked_files => 'config/newrelic.yml' end end remote_file 'config/newrelic.yml' => '/tmp/newrelic.yml', roles: :app file '/tmp/newrelic.yml' do |t| sh "curl -o #{t.name} https://rpm.newrelic.com/accounts/xx/newrelic.yml" end
1 parent 251956c commit ba0d313

4 files changed

Lines changed: 95 additions & 0 deletions

File tree

lib/capistrano/dsl/task_enhancements.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,26 @@ def after(task, post_task, *args, &block)
1111
invoke(post_task)
1212
end
1313
end
14+
15+
def remote_file(task)
16+
target_roles = task.delete(:roles) { :all }
17+
define_remote_file_task(task, target_roles)
18+
end
19+
20+
def define_remote_file_task(task, target_roles)
21+
Rake::Task.define_task(task) do |t|
22+
prerequisite_file = t.prerequisites.first
23+
file = shared_path.join(t.name)
24+
25+
on roles(target_roles) do
26+
unless test "[ -f #{file} ]"
27+
info "Uploading #{prerequisite_file} to #{file}"
28+
upload! File.open(prerequisite_file), file
29+
end
30+
end
31+
32+
end
33+
end
34+
1435
end
1536
end
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
require 'integration_spec_helper'
2+
3+
describe 'cap deploy:started', slow: true do
4+
before do
5+
install_test_app_with(config)
6+
copy_task_to_test_app('spec/support/tasks/database.cap')
7+
end
8+
9+
let(:config) {
10+
%{
11+
set :stage, :#{stage}
12+
set :deploy_to, '#{deploy_to}'
13+
set :repo_url, 'git://github.com/capistrano/capistrano.git'
14+
set :branch, 'v3'
15+
server 'localhost', roles: %w{web app}, user: '#{current_user}'
16+
set :linked_files, %w{config/database.yml}
17+
set :linked_dirs, %w{config}
18+
}
19+
}
20+
21+
describe 'linked_files' do
22+
23+
before do
24+
cap 'deploy:check:linked_dirs'
25+
end
26+
27+
subject { cap 'deploy:check:linked_files' }
28+
29+
context 'where the file does not exist' do
30+
it 'creates the file with the remote_task prerequisite' do
31+
expect(subject).to match 'Uploading'
32+
expect(subject).not_to match 'config/database.yml does not exist'
33+
expect(subject).to match 'successful'
34+
end
35+
end
36+
37+
context 'where the file already exists' do
38+
before do
39+
FileUtils.touch(shared_path.join('config/database.yml'))
40+
end
41+
42+
it 'will not recreate the file if it already exists' do
43+
expect(subject).not_to match 'Uploading'
44+
expect(subject).not_to match 'config/database.yml does not exist'
45+
expect(subject).to match 'successful'
46+
end
47+
end
48+
49+
end
50+
end
51+

spec/support/tasks/database.cap

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace :deploy do
2+
namespace :check do
3+
task :linked_files => 'config/database.yml'
4+
end
5+
end
6+
7+
remote_file 'config/database.yml' => '/tmp/database.yml', roles: :all
8+
9+
file '/tmp/database.yml' do |t|
10+
sh "touch #{t.name}"
11+
end

spec/support/test_app.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,19 @@ def gemfile
8383
test_app_path.join('Gemfile')
8484
end
8585

86+
def capfile
87+
test_app_path.join('Capfile')
88+
end
89+
8690
def current_user
8791
`whoami`.chomp
8892
end
93+
94+
def task_dir
95+
test_app_path.join('lib/capistrano/tasks')
96+
end
97+
98+
def copy_task_to_test_app(source)
99+
FileUtils.cp(source, task_dir)
100+
end
89101
end

0 commit comments

Comments
 (0)