module Capistrano::Deploylock

Constants

VERSION

Public Class Methods

load_into(configuration) click to toggle source
# File lib/capistrano/deploylock.rb, line 6
def self.load_into(configuration)
  configuration.load do
    _cset :deploy_lock_basename, "deploy_lock"
    _cset(:deploy_lock_dirname) { "#{shared_path}/system" }
    _cset(:deploy_lock_template_path) { File.join(File.dirname(__FILE__), "templates", "deploy_lock.yml") }
    _cset(:deploy_lock_remote_path) { "#{deploy_lock_dirname}/#{deploy_lock_basename}.yml" }
    _cset(:deploy_lock_remote_log_path) {"#{deploy_lock_dirname}/#{deploy_lock_basename}.log" }
    _cset(:deploy_lock_file_local_path) {"./public/system/#{deploy_lock_basename}.yml" }

    def remote_file_exists?(full_path)
      'true' ==  capture("if [ -e #{full_path} ]; then echo 'true'; fi").strip
    end

    def lock_force_end(with_log=false)
      if remote_file_exists?(deploy_lock_remote_path)
        puts '[SKIP] ロックファイルを削除します'
        lock_end_log if with_log
        run "rm -f #{deploy_lock_remote_path}"
      end
    end

    def lock_start_log
      run "echo [started], #{Time.now}, #{git_config_user_name} >> #{deploy_lock_remote_log_path}"
    end

    def lock_end_log
      run "echo [ended], #{Time.now}, #{git_config_user_name} >> #{deploy_lock_remote_log_path}"
    end

    def git_config_user_name
      `git config --get user.name`
    end

    def remove_local_file
      FileUtils.rm deploy_lock_file_local_path, force: true
    end

    namespace :deploy do
      namespace :lock do
        desc 'デプロイロックを確認する'
        task :start, roles: :web do
          on_rollback { run "rm -f #{deploy_lock_remote_path}" }
          require 'erb'
          puts "\n**** [DEPLOY LOCK] ****"
          puts "24時間後まであなたの名前を元に他人のデプロイをロックします。"
          puts "この操作は下記のコマンドで取り消しできます。"
          puts "bundle exedc cap $STAGENAME deploy:lock:end"

          #      対話用
          #      print "\n今日から何日間ロックしますか? [1-10/n]: "
          #      STDOUT.flush
          #      ans= STDIN.gets.chomp
          #      if ["", 'n'].include? ans
          #        puts "[SKIPPED] デプロイロックをスキップしました。"
          #        exit
          #      end
          #
          #      day = ans.to_i
          #      unless (1..10).include?(day)
          #        puts "[FAILED] days must set [1-10/n]"
          #        exit
          #      end

          day = 1
          expired_at = Time.now + (day * (60 * 60 * 24))

          user = git_config_user_name
          puts "\n**** [LOCKED] #{rails_env}はロックされ、有効期限内が設定されました. **** "
          puts "\n  locked_user  : #{user}"
          puts "  expired_at   : #{expired_at}\n\n"

          erb = ERB.new(File.read("#{deploy_lock_template_path}.erb")).result(binding)
          put erb, "#{deploy_lock_remote_path}", mode: 0644
          lock_start_log
        end

        desc 'デプロイロックを解除する'
        task :end, roles: :web do
          lock_force_end(true)
        end

        desc 'デプロイロックを設定する'
        task :check, roles: :web do
          unless remote_file_exists?(deploy_lock_remote_path)
            puts '[SKIP] ロックファイルがありません.'
            next
          end

          FileUtils.rm deploy_lock_file_local_path, force: true
          FileUtils.mkdir_p './public/system'

          get deploy_lock_remote_path, deploy_lock_file_local_path
          lock = YAML.load_file deploy_lock_file_local_path

          if Time.now > lock["expired_at"]
            puts '[SKIP] ロックファイルの設定期限が過ぎています.'
            remove_local_file
            lock_force_end(false)
            next
          end

          current_user = git_config_user_name.chomp
          if lock["user"] == current_user
            puts '[SKIP] あなたのロックファイルです.'
            remove_local_file
            next
          end

          puts "\n**** [LOCKED] #{rails_env}はロックされ、有効期限内です. **** "
          puts "\n  locked_user  : #{lock["user"]}"
          puts "  expired_at   : #{lock["expired_at"]}\n\n"

          puts "ロックは下記のコマンドで取り消しできます。"
          puts "bundle exedc cap $STAGENAME deploy:lock:end"

          remove_local_file
          run "hostname; exit 1"
        end
      end
    end
  end
end

Public Instance Methods

git_config_user_name() click to toggle source
# File lib/capistrano/deploylock.rb, line 35
def git_config_user_name
  `git config --get user.name`
end
lock_end_log() click to toggle source
# File lib/capistrano/deploylock.rb, line 31
def lock_end_log
  run "echo [ended], #{Time.now}, #{git_config_user_name} >> #{deploy_lock_remote_log_path}"
end
lock_force_end(with_log=false) click to toggle source
# File lib/capistrano/deploylock.rb, line 19
def lock_force_end(with_log=false)
  if remote_file_exists?(deploy_lock_remote_path)
    puts '[SKIP] ロックファイルを削除します'
    lock_end_log if with_log
    run "rm -f #{deploy_lock_remote_path}"
  end
end
lock_start_log() click to toggle source
# File lib/capistrano/deploylock.rb, line 27
def lock_start_log
  run "echo [started], #{Time.now}, #{git_config_user_name} >> #{deploy_lock_remote_log_path}"
end
remote_file_exists?(full_path) click to toggle source
# File lib/capistrano/deploylock.rb, line 15
def remote_file_exists?(full_path)
  'true' ==  capture("if [ -e #{full_path} ]; then echo 'true'; fi").strip
end
remove_local_file() click to toggle source
# File lib/capistrano/deploylock.rb, line 39
def remove_local_file
  FileUtils.rm deploy_lock_file_local_path, force: true
end