Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you check to see if a file exists (on the remote server) in Capistrano?

Like many others I've seen in the Googleverse, I fell victim to the File.exists? trap, which of course checks your local file system, not the server you are deploying to.

I found one result that used a shell hack like:

if [[ -d #{shared_path}/images ]]; then ... 

but that doesn't sit well with me, unless it were wrapped nicely in a Ruby method.

Has anybody solved this elegantly?

like image 415
Teflon Ted Avatar asked Nov 02 '09 14:11

Teflon Ted


2 Answers

In capistrano 3, you can do:

on roles(:all) do   if test("[ -f /path/to/my/file ]")     # the file exists   else     # the file does not exist   end end 

This is nice because it returns the result of the remote test back to your local ruby program and you can work in simpler shell commands.

like image 99
Matt Connolly Avatar answered Oct 22 '22 08:10

Matt Connolly


@knocte is correct that capture is problematic because normally everyone targets deployments to more than one host (and capture only gets the output from the first one). In order to check across all hosts, you'll need to use invoke_command instead (which is what capture uses internally). Here is an example where I check to ensure a file exists across all matched servers:

def remote_file_exists?(path)   results = []    invoke_command("if [ -e '#{path}' ]; then echo -n 'true'; fi") do |ch, stream, out|     results << (out == 'true')   end    results.all? end 

Note that invoke_command uses run by default -- check out the options you can pass for more control.

like image 36
Patrick Reagan Avatar answered Oct 22 '22 10:10

Patrick Reagan