詳細検索

Get top-level task names within Capistrano 3 tasks

Avatar
by maeno
3 min read

Get top-level task names within Capistrano 3 tasks
Translated from 日本語 • View original

When I was writing a task in Capistrano3, I had a hard time obtaining the top-level task name because I had a hard time obtaining the top-level task name because I had a hard time subtracting the name of the top-level task executed as a cap command in the task.

Basically, if you want to get your task name in a task in Capistrano3, you can draw it as an argument to the block as follows:

desc "main task"
task :main_task => :sub_task do |task|
    run_locally do
        info ": This task name: #{task}"
        info ": Running main deploy task!"
    end
end

desc "sub task"
task :sub_task do |task|
    run_locally do
        current_task = task.name_with_args.split(':').last
        info ": This task name: #{current_task}"
    end
end

When you perform the above task, it looks like this.

$ cap test deploy:main_task
INFO: This task name: sub_task
INFO: This task name: deploy:main_task
INFO: Running main deploy task!

However, if you create a subtask that reads the common configuration of the deployment and build a task chain that executes the subtask before all the main tasks, and you want to branch out some of the subtasks only when a specific main task is executed, you will need to get the task name of the main task in the subtask. In other words, I want to get the top-level task (the main task in the example) that is executed by the cap command, but I had a hard time realizing this because I couldn't find the TIPS. Capistrano's task handling is implemented in the Rake class used in the core, so it was necessary to get it from the Application method of that Rake class.

Example of a subtask that took a top-level task and branched it out:

desc "main task1 : initialize"
task :initialize => :set_options do
    run_locally do
        info ": Running initialization to deploy"
    end
end

desc "main task2 : deployment"
task :deployment => :set_options do
    run_locally do
        info ": Running application deploy!"
    end
end

desc "common sub task : set options"
task :set_options do |task|
    set :top_level_task, task.application.top_level_tasks.last.split(':').last

run_locally do
        info ": Top level task name: #{fetch(:top_level_task)}"
        if (fetch(:top_level_task) == 'initialize') then
            info ": If main-task is named initialize, this task running."
        else
            info ": Perform the task in the case of the main task of deployment."
        end
    end
end

The result of the above task is

$ cap test deploy:initialize
INFO: Top level task name: initialize
INFO: If main-task is named initialize, this task running.
INFO: Running initialization to deploy
$ cap test deploy:deployment
INFO: Top level task name: deployment
INFO: Perform the task in the case of the main task of deployment.
INFO: Running application deploy!

and it can be seen that the processing of even one subtask is different because the top-level task (main task) executed by even one is different.

When cutting out tasks and making them common, the 'Rake::Application.top_level_tasks' method is quite useful.

Related Articles