file test in within block behaves unexpected

32 views
Skip to first unread message

ruud

unread,
Feb 26, 2015, 9:46:35 AM2/26/15
to capis...@googlegroups.com
Versions:
  • Ruby 2.0.0
  • Capistrano 3.3.5
Platform:
  • debian wheezy.

hello group,

I encountered an unexpected feature of capistrano. When I test a file or directory with 'if test [ -d .....]', in a within block, the directory of that test is based on the working directory instead of the directory in the within block.

Who can explain what happens?

The following Capfile illustrates this; the second task is the most readable, but does not work as I expect. The first, in which the file test is done outside the within block, is a working version of it. Has this anything to do with the ssh toolkit? Can I use the second task by adjusting the used syntax?


require 'capistrano/setup'
require 'capistrano/deploy'

namespace :rbg do
    desc 'check git directory'
    task :check_gitdir do
        on roles :installatie, :test do
            if test ( "[ -d "  + fetch( :deploy_to) + "/.git ]" )
                info " git-dir exists"
            else
                info " git-dir does not exist"
                within deploy_to do
                    execute :git, 'init'
                end
            end
        end
    end
       
    task :check_gitdir_doesn_work do
        on roles :installatie, :test do
            within deploy_to do
                if test "[ -d .git ]"
                    info " git-dir exists"
                else
                    info " git-dir does not exist"
                    execute :git, 'init'
                end
            end
        end
    end
end  
 

Output of task 1 (correct) when applying this on a host with a .git directory within the deploy directory:

INFO git-dir exists

Output of task 2 in the same situation:

INFO git-dir does not exist
INFO [e64c94b6] Running /usr/bin/env git init as dep...@172.xx.xx.xx
INFO [e64c94b6] Finished in 0.238 seconds with exit status 0 (successful).
INFO [b45c3b5b] Running /usr/bin/env git remote add repo REPOSITORYNAME as .......

Thanks in advance for helping me understanding what is going on.

Ruud

Lee Hambley

unread,
Feb 26, 2015, 11:51:50 AM2/26/15
to Capistrano
It's documented *somewhere*, I recall having written about why, the long and short version is "anything with a whitespace in it is not safe for us to modify, and prepend and append paths, commands, etc", that unfortunately also applies to test(), and of course there is no `test(:some, :symbol)` syntax that makes sense.

I'd suggest to use the `capture()` api to `capture(:pwd)`, and use Ruby's `File.join()` APIs (or, just concatenate the strings) to build the command to test for.

If you do happen to stumble on the docs, I'd be happy to have an improvement PR to make it more visible, as when I wrote it, and even I can't find it is a bad sign :(

--
You received this message because you are subscribed to the Google Groups "Capistrano" group.
To unsubscribe from this group and stop receiving emails from it, send an email to capistrano+...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/capistrano/8d2bab9b-3355-43c3-be15-66a3e0606324%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

ruud

unread,
Mar 2, 2015, 3:34:54 AM3/2/15
to capis...@googlegroups.com


On Thursday, 26 February 2015 17:51:50 UTC+1, Lee Hambley wrote:
It's documented *somewhere*, I recall having written about why, the long and short version is "anything with a whitespace in it is not safe for us to modify, and prepend and append paths, commands, etc", that unfortunately also applies to test(), and of course there is no `test(:some, :symbol)` syntax that makes sense.


hi Lee,
thank you for the explanation. I knew about the whitespace issues, but not it applied to test() as well. I'm glad I have a clear rule about what I can expect and what not.
 
I'd suggest to use the `capture()` api to `capture(:pwd)`, and use Ruby's `File.join()` APIs (or, just concatenate the strings) to build the command to test for.


Yes, I already made a function that essentially did this. But my main goal was to understand  why my task was failing. So I am completely content now.

Thanks again, Ruud

Lee Hambley

unread,
Mar 2, 2015, 3:36:54 AM3/2/15
to Capistrano
Thanks, it's something we've strugged with since v3, the new API is great, *if* your command is simple enough to concatenate. I think without going down the road of relational algebra for composing parts of commands, or writing a bash lexer/parser combo, i'll always struggle to work with anything with whitespaces in, and it really cheapens the user experience, unfortunately :( Any recommendations you can make of how we might fix the docs now that you know better how it works would be very welcome indeed.

--
You received this message because you are subscribed to the Google Groups "Capistrano" group.
To unsubscribe from this group and stop receiving emails from it, send an email to capistrano+...@googlegroups.com.

ruud

unread,
Mar 2, 2015, 3:41:22 AM3/2/15
to capis...@googlegroups.com


On Monday, 2 March 2015 09:36:54 UTC+1, Lee Hambley wrote:
Thanks, it's something we've strugged with since v3, the new API is great, *if* your command is simple enough to concatenate. I think without going down the road of relational algebra for composing parts of commands, or writing a bash lexer/parser combo, i'll always struggle to work with anything with whitespaces in, and it really cheapens the user experience, unfortunately :( Any recommendations you can make of how we might fix the docs now that you know better how it works would be very welcome indeed.

hi Lee,
I'd be glad to, but I have to find it in the first place. I will try and see later on today.

Ruud
 

ruud

unread,
Mar 2, 2015, 10:23:32 AM3/2/15
to capis...@googlegroups.com


On Thursday, 26 February 2015 17:51:50 UTC+1, Lee Hambley wrote:
I'd suggest to use the `capture()` api to `capture(:pwd)`, and use Ruby's `File.join()` APIs (or, just concatenate the strings) to build the command to test for.

hi Lee,

just for the records: it is possible to give a list to test(), so that
  if test "[ -d .git ]"
could also be written as
if test('[ ', '-d', '.git ]' )
resulting in expected behaviour (within-dir is used).

regards, Ruud

Lee Hambley

unread,
Mar 2, 2015, 10:41:08 AM3/2/15
to Capistrano
Thanks Ruud,

For what it's worth:L

`if test('[ ', '-d', '.git ]' )`

Can be written as `test -d git`, as `[` is a bash alias for `test`, and ] is a noop :)

So, that could be:

`if test(:test, '-d .git')`

which isn't toooooooo bad :)

--
You received this message because you are subscribed to the Google Groups "Capistrano" group.
To unsubscribe from this group and stop receiving emails from it, send an email to capistrano+...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages