require 'capistrano/scm/base'

module Capistrano
  module SCM
    
    # An SCM module for using git as your source control tool. Assumes you
    # are using a shared git repository. Use it by specifying the following
    # line in your configuration:
    #
    #   set :scm, :git
    #
    # You must set <tt>:branch</tt>, which is the reference to the branch
    # you are deploying, for example:
    # 
    #   set :branch, "remotes/origin/master"
    #
    # Also, this module accepts a <tt>:git</tt> configuration variable,
    # which (if specified) will be used as the full path to the git
    # executable on the remote machine:
    #
    #   set :git, "/opt/local/bin/git"
    #
    # Remember to set <tt>:repository</tt> to the path of your git repo:
    #
    #   set :repository, "someuser@somehost:/home/myproject"
    class Git < Base
      def current_revision(actor)
        git  = configuration[:git] ? configuration[:git] : "git"
        exec = "cd #{actor.current_path} && git rev-parse HEAD"

        result = ""
        actor.run(exec, :once => true) do |ch, str, out|
          result = out if str == :out
          raise "Could not determine current revision" if str == :err
        end

        result
      end

      def checkout(actor)
        git      = configuration[:git] ? configuration[:git] : "git"
        branch   = configuration[:branch] 

        fail "No branch specified, use for example 'set :branch, \"remotes/origin/master\"' in your deploy.rb" unless branch

        execute  = "#{git} clone #{configuration.repository} #{actor.release_path}; "
        execute += "cd #{actor.release_path} ; #{git} checkout -b deploy #{branch}; " 

        run_checkout(actor, execute, &git_stream_handler(actor))
      end

      private

      def git_stream_handler(actor)
        Proc.new do |ch, stream, out|
          prefix = "#{stream} :: #{ch[:host]}"
          actor.logger.info out, prefix
          if out =~ %r{password:}
            actor.logger.info "git is asking for a password", prefix
            ch.send_data "#{actor.password}\n"
          elsif out =~ %r{\(yes/no\)}
            actor.logger.info "git is asking whether to connect or not", prefix
            ch.send_data "yes\n"
          elsif out =~ %r{passphrase}
            message = "git needs your key's passphrase, sending empty string"
            actor.logger.info message, prefix
            ch.send_data "\n"
          end
        end
      end
    end

  end
end


