Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #9379 (closed enhancement: fixed)

Opened 1 year ago

Last modified 1 year ago

[PATCH] Add 'match' as a remote dependency

Reported by: adam Assigned to: minam
Priority: normal Milestone: 1.x
Component: Capistrano Version: edge
Severity: normal Keywords:
Cc:

Description

from capistrano Google group, as per Jamis's suggestion that I throw it in here.

Jamis, I didn't see any test examples for remote dependencies... I wasn't quite sure how to start creating test cases for this particular example. If you would like me to chip in that regard, let me know.

Jamis, the 'depend' and 'deploy:check' are awesome. I added an additional option that you might consider handy. I sometimes need to check the output of a command call, like 'ruby -v' (in that case I want to know if ruby 1.8.6 is being used because it is incompatible with parts of my codebase). With the extension, I can now declare this in my capify file:

depend :remote, :match, "ruby -v", /ruby (1\.8\.[4-5])/i

the code is not as clean as I would like, but the two main changes are adding a 'def match' and modifying your private 'def try' so it can accept a block if given. That way we can capture the output and manipulate it once it is all back.

anyway, the code is listed below.

thanks! Adam

module Capistrano 
  module Deploy 
    class RemoteDependency 
      def match(command, match, options={}) 
        @message = "the output from `#{command}' did not match #{match}" 
        match = /#{match}/ if match.is_a?(String) 

        # we collect the full output per server.  This is a bit inefficient because we would 
        # probably want to fail when the first server we find doesn't meet the 'match' criterion 
        # but we need to gather the full output before we can do a match.  Some of the commands run, 
        # like 'java -version' return on multiple lines... 
        output_per_server = {} 
        try_with_block("#{command} ", options) do |ch, stream, out| 
          warn "#{ch[:server]}: #{out}" if stream == :err 
          output_per_server[ch[:server]] ||= '' 
          output_per_server[ch[:server]] += out 
        end 

        #it is possible for some of these commands to return a status ! = 0. 
        #For example, rake --version does not return 0. 
        # but for this check we just care if the output matches, so reset the success flag 
        @success = true 
        errored_hosts = [] 
        output_per_server.each_pair do |server, output| 
          @message = "the output '#{output.chop}' from `#{command}' did not match #{match}" 
          next if output =~ match 
          @success = false 
          errored_hosts << server 
        end 
        unless errored_hosts.empty? 
          @hosts = errored_hosts.join(', ') 
        end 
        self 
      rescue Capistrano::CommandError => e 
        @success = false 
        @hosts = e.hosts.join(', ') 
      end 

      private 

      def try_with_block(command, options, &block) 
        return unless @success # short-circuit evaluation 
        configuration.run(command, options, &block) 
      rescue Capistrano::CommandError => e 
        @success = false 
        @hosts = e.hosts.join(', ') 
      end 

    end 
  end 
end

Change History

09/01/07 02:10:46 changed by minam

  • status changed from new to closed.
  • resolution set to fixed.

(In [7386]) Add a match remote dependency method (closes #9379)