require 'engineyard-serverside/logged_output' module EY module Serverside module Strategies class Git module Helpers def update_repository_cache unless strategy.fetch && strategy.checkout abort "*** [Error] Git could not checkout (#{strategy.to_checkout}) ***" end end def create_revision_file_command strategy.create_revision_file_command(c.release_path) end def short_log_message(revision) strategy.short_log_message(revision) end def strategy # Ensure the git ssh config is up to date with the current app. ENV['GIT_SSH'] = ssh_executable klass = Module.nesting[1] # Use [] to access attributes instead of calling methods so # that we get nils instead of NoMethodError. # # Rollback doesn't know about the repository location (nor # should it need to), but it would like to use #short_log_message. klass.new( :repository_cache => c[:repository_cache], :app => c[:app], :repo => c[:repo], :ref => c[:branch] ) end end include LoggedOutput attr_reader :opts def initialize(opts) @opts = opts end def usable_repository? File.directory?(opts[:repository_cache]) && `#{git} remote -v | grep origin`[opts[:repo]] end def fetch if usable_repository? logged_system("#{git} fetch -q origin 2>&1") else FileUtils.rm_rf(opts[:repository_cache]) logged_system("git clone -q #{opts[:repo]} #{opts[:repository_cache]} 2>&1") end end def checkout info "~> Deploying revision #{short_log_message(to_checkout)}" in_git_work_tree do (logged_system("git checkout -q '#{to_checkout}'") || logged_system("git reset -q --hard '#{to_checkout}'")) && logged_system("git submodule sync") && logged_system("git submodule update --init") && logged_system("git clean -dfq") end end def to_checkout return @to_checkout if @opts_ref == opts[:ref] @opts_ref = opts[:ref] @to_checkout = if branch?(opts[:ref]) "origin/#{opts[:ref]}" else opts[:ref] end end def create_revision_file_command(dir) %Q{#{git} show --pretty=format:"%H" | head -1 > "#{dir}/REVISION"} end def short_log_message(rev) `#{git} log --pretty=oneline --abbrev-commit -n 1 '#{rev}'`.strip end private def in_git_work_tree Dir.chdir(git_work_tree) { yield } end def git_work_tree opts[:repository_cache] end def git "git --git-dir #{git_work_tree}/.git --work-tree #{git_work_tree}" end def branch?(ref) remote_branches = `#{git} branch -r` remote_branches.each_line do |line| return true if line.include?("origin/#{ref}") end false end end end end end