読者です 読者をやめる 読者になる 読者になる

Capistrano3のコードを読んでみる1 ~設定ファイルのパス設定~

Capistranoを実行時に利用するconfig/deploy.rbとかproduction.rb、staging.rbのパスを変更できるのか気になったのでソースコードを読んでみました。
結論としては、変更可能ですがcapistrano/setupをCapfileでrequireする前にsetする必要があります。
また、Capfileファイルのパスも変えられるかが気になって見てみましたが、capfile、capfile.rb、Capfile.rbにファイル名の変更は可能という結論になりました。

/lib/capistrano/application.rb

色々省略してますが、初期化処理としてcapfileの読み込みを行います。

module Capistrano
  class Application < Rake::Application
    def initialize
      super
      @rakefiles = %w{capfile Capfile capfile.rb Capfile.rb} << capfile
    end

    private

    # allows the `cap install` task to load without a capfile
    def capfile
      File.expand_path(File.join(File.dirname(__FILE__),'..','Capfile'))
    end
  end
end

/lib/capistrano/setup.rb

load 'capistrano/defaults.rb'では、/lib/capistrano/defaults.rbで、setしなかった場合のデフォルト値が定義されています。
load:defaultsをImmutableTask(/lib/capistrano/immutable_task.rb)として定義しているので、CapistranoのタスクでもOverride出来ません。
stage_config_pathやdeploy_config_pathは/lib/capistrano/dsl/paths.rbで定義されています。
configure_backend は/lib/capistrano/configuration.rbで定義されていて、sshkitの設定を行います。

namespace :load do
  task :defaults do
    load 'capistrano/defaults.rb'
  end
end

stages.each do |stage|
  Rake::Task.define_task(stage) do
    set(:stage, stage.to_sym)

    invoke 'load:defaults'
    Rake.application["load:defaults"].extend(Capistrano::ImmutableTask)
    load deploy_config_path
    load stage_config_path.join("#{stage}.rb")
    load "capistrano/#{fetch(:scm)}.rb"
    I18n.locale = fetch(:locale, :en)
    configure_backend
  end
end

require 'capistrano/dotfile'

setup.rbの最後でrequireしているdotfile.rbの内容は以下のとおりです。

dotfile = Pathname.new(File.join(Dir.home, '.capfile'))
load dotfile if dotfile.file?

/lib/capistrano/install.rb

ファイルの中身は、以下のようになっています。

load File.expand_path(File.join(File.dirname(__FILE__),'tasks/install.rake'))

/lib/capistrano/task/install.rakeを実行しています。
install.rakeはcap install の際に実行される処理が定義されています。

/lib/capistrano/deploy.rb

require 'capistrano/framework'

load File.expand_path("../tasks/deploy.rake", __FILE__)

/lib/capistrano/framewok.rb

以下のように、framework.rakeを呼び出しています。

load File.expand_path("../tasks/framework.rake", __FILE__)
require 'capistrano/install'

task/deploy.rake

task/framework.rakeでは、Capistranoが提供するコマンド(?)のインターフェースが定義されています。

namespace :deploy do

  desc 'Start a deployment, make sure server(s) ready.'
  task :starting do
  end

  desc 'Started'
  task :started do
  end
 
  #以下、省略

また、:rollback、:deployの処理はここで定義されています。

  #以下、省略

  desc 'Rollback to previous release.'
  task :rollback do
    %w{ starting started
        reverting reverted
        publishing published
        finishing_rollback finished }.each do |task|
      invoke "deploy:#{task}"
    end
  end
end

desc 'Deploy a new release.'
task :deploy do
  set(:deploying, true)
  %w{ starting started
      updating updated
      publishing published
      finishing finished }.each do |task|
    invoke "deploy:#{task}"
  end
end
task default: :deploy

task/framework.rake

task/deploy.rake はtask/framework.rakeで定義してあったインターフェースの実装を担当しています。(全てではないですが)
また、実際の処理はinvokeで処理を委譲しています。

namespace :deploy do

  task :starting do
    invoke 'deploy:check'
    invoke 'deploy:set_previous_revision'
  end

  #以下、省略