Yes, but that wasn't flexible or elegant enough ;)

This is what I've ended up with, which seems to be working as desired.
I'd be very interested if someone has something better for the line
where I call Kernel#caller.

def at_once(joiner=' && ')
 nested = caller.any?{|c|c =~ /config\/deploy\.rb.+at_once'$/}
 unless nested
   cmds ||= Array.new
   self.class.send(:define_method, :get_cmd) {|c|cmds << c}
   alias old_run run
   alias run get_cmd
 end
 yield
 unless nested
   alias run old_run
   run cmds.join(joiner)
 end
end

namespace :env do
 task :init do
   at_once do
     run "cd #{deploy_to}"
     run "eval `#{deploy_to}/bin/env.sh`"
   end
 end

 task :sandbox do
   set :current_envronment, :sandbox
   set :rails_env, :sandbox
   set :deploy_to, "/var/www/#{application}-sandbox"
 end

 task :echo do
   at_once do
     init
     run 'echo $RAILS_ENV'
     run 'which ruby'
     run 'which gem'
   end
end

$ cap env:sandbox env:echo
 * executing `env:sandbox'
 * executing `env:echo'
 * executing `env:init'
 * executing "cd /var/www/myapp-sandbox && eval
`/var/www/myapp-sandbox/bin/env.sh` && echo $RAILS_ENV && which ruby
&& which gem"
   servers: ["example.com"]
   [example.com] executing command
 ** [out :: example.com]
 ** [out :: example.com] /var/www/myapp-sandbox/usr/bin/ruby
 ** [out :: example.com] /var/www/myapp-sandbox/usr/bin/gem
   command finished


-Ian

On 1/9/08, Jamis Buck <[EMAIL PROTECTED]> wrote:
> The easiest thing to do is probably going to be something like this:
>
>    run "x && y"
>
> If x is something you always want to run for all of your commands,
> then you can do something like this:
>
>    def run_with_x(y)
>      run "x && #{y}"
>    end
>
>    run_with_x("y")
>
> - Jamis
>
> On Jan 9, 2008, at 4:44 PM, Ian Smith-Heisters wrote:
>
> >
> > Ok, that's what I was beginning to suspect.
> >
> > So I thought I'd be clever and write a little helper method that would
> > help me string together a bunch of commands with, say, ' && ':
> >
> >>> def run(cmd); puts "I have yer #{cmd}"; end
> > => nil
> >>> def at_once(joiner=' && ')
> >>>  cmds = Array.new
> >>>  Object.define_method(:get_cmd) {|c|cmds << c}
> >>>  alias :old_run :run
> >>>  alias :run :get_cmd
> >>>  yield
> >>>  alias :run :old_run
> >>>  run cmds.join(joiner)
> >>> end
> > => nil
> >>> at_once{run('x');run('y')}
> > I have yer x && y
> > => nil
> >>> run 'x'
> > I have yer x
> > => nil
> >>> run 'y'
> > I have yer y
> > => nil
> >>>
> >
> > Which works fine on the console. Unfortunately, when I stick the
> > at_once definition at the top of my deploy.rb script, it runs into all
> > kinds of problems like "`method_missing': undefined method `at_once'
> > for #<Capistrano::Configuration::Namespaces::Namespace:0xb7859b18>"
> > when I try to use it.
> >
> > Any ideas on how to get that to work?
> >
> > Thanks,
> > Ian
> >
> > On 1/9/08, Jamis Buck <[EMAIL PROTECTED]> wrote:
> >> Each invocation of run() or sudo() is done in a brand new SSH
> >> channel.
> >> Running commands via capistrano is not at all like executing commands
> >> in a shell like bash--environment settings do not stick from one
> >> command to the next. If you have setup that you want done on each
> >> run(), you will need to do as you said and create a wrapper method
> >> that prepends the setup you want done to each command.
> >>
> >> - Jamis
> >>
> >> On Jan 8, 2008, at 5:29 PM, I. E. Smith-Heisters wrote:
> >>
> >>>
> >>> Hi all,
> >>>
> >>> I have a bunch of staging servers, all of which have their own,
> >>> custom
> >>> compiled ruby and gem versions. In order to work with a given server
> >>> instance, a user is supposed to eval a script that sets up their
> >>> bash
> >>> environment. Like this:
> >>>
> >>> $ cd /var/www/staging-x
> >>> $ eval `bin/env.sh`
> >>> $ which ruby
> >>> /var/www/staging-x/usr/bin/ruby
> >>> $ which gem
> >>> /var/www/staging-x/usr/bin/gem
> >>>
> >>> When I use Cap to run "eval `bin/env.sh`", the variables it exports
> >>> are not persisted:
> >>>
> >>> namespace :env do
> >>> task :init do
> >>>   run "cd #{deploy_to}"
> >>>   run "eval `#{deploy_to}/bin/env.sh`"
> >>> end
> >>>
> >>> task :sandbox do
> >>>   set :rails_env, :sandbox
> >>>   set :deploy_to, "/var/www/#{application}-sandbox"
> >>>   init
> >>> end
> >>>
> >>> task :echo do
> >>>   run 'echo $RAILS_ENV'
> >>>   run 'which ruby'
> >>>   run 'which gem'
> >>> end
> >>> end
> >>>
> >>> $ cap env:sandbox env:echo
> >>> <snip>
> >>> * executing `env:echo'
> >>> * executing "echo $RAILS_ENV"
> >>>   servers: ["example.com"]
> >>>   [example.com] executing command
> >>> ** [out :: example.com]
> >>>   command finished
> >>> * executing "which ruby"
> >>>   servers: ["example.com"]
> >>>   [example.com] executing command
> >>> ** [out :: example.com] /usr/bin/ruby
> >>>   command finished
> >>> * executing "which gem"
> >>>   servers: ["example.com"]
> >>>   [example.com] executing command
> >>> *** [err :: example.com] which: no gem in (/usr/kerberos/bin:/usr/
> >>> local/bin:/bin:/usr/bin)
> >>>   command finished
> >>> command "which gem" failed on example.com
> >>>
> >>> As you can see, the PATH variable still points to the system version
> >>> of ruby, and since the system doesn't have gem installed, "which
> >>> gem"
> >>> kills the script outright.
> >>>
> >>> I've been looking around and I see lots of problems surrounding
> >>> people's bashrc files being read and other ssh configuration issues,
> >>> but this really seems to be something to do with how Capistrano is
> >>> executing each command and the persistence of the environment
> >>> between
> >>> them. A colleague suggested I do something like
> >>>
> >>> run "eval `bin/env.sh` && foobar"
> >>>
> >>> which I guess is a possibility, but hardly an elegant solution,
> >>> since
> >>> I'd have to prefix each command with the eval statement (probably
> >>> best
> >>> accomplished by extending "run").
> >>>
> >>> Thanks in advance for any help you might be able to offer.
> >>>
> >>> -Ian
> >>>>>
> >>
> >>
> >>
> >
> > > >
>
>
>

--~--~---------~--~----~------------~-------~--~----~
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/capistrano
-~----------~----~----~----~------~----~------~--~---

Reply via email to