Rake 元编程:如何从列表中创建多个任务

Rake metaprogramming: How to create multiple tasks from list

实际上我想要一个 Capistrano 脚本(基于 rake)。

如何像这样转换多个任务:

desc 'Runs rake db:seed'
task :seed do
  on roles :db do
    within release_path do
      with rails_env: fetch(:rails_env) do
        execute :rake, "db:seed"
      end
    end
  end
end

变成这样:

task_list = %i(
  db:seed
  db:reset
  db:migrate
  db:seed:testusers
  db:seed:testorders
)

task_list.each do |task_name|
  desc %(Runs rake #{task_name})
  task :task_name do
    on roles :db do
      within release_path do
        with rails_env: fetch(:rails_env) do
          execute :rake, task_name
        end
      end
    end
  end

end

我的问题是 task_name 被用作任务定义中环境设置的键。

如何用这种方式定义多个任务?

怎么样:

task_list = %i(
  db:seed
  db:reset
  db:migrate
  db:seed:testusers
  db:seed:testorders
)

task_list.each do |task_name|
  desc %(Runs rake #{task_name})
  task {task_name => [:set_rails_env]} do
    on primary fetch(:migration_role) do
      within release_path do
        with rails_env: fetch(:rails_env) do
          execute :rake, task_name
        end
      end
    end
  end
end

编辑:看到您将签名从 task_name: [:dependency] 更改为更简单的 task_name,您必须执行以下操作:

task_list.each do |task_name|
  desc %(Runs rake #{task_name})
  task task_name do
    ...
  end
end

上面的原因是task_name: :foo:task_name => :foo的语法糖。由于您希望动态评估密钥,因此将散列更改为 task_name => :foo,其中 task_name 是一个包含符号的变量。

换句话说 - 您不希望按字面意思调用您的任务 task_name - 您希望它被称为您的变量 task_name 包含的内容。