如何通过capistrano 3运行自定义rake任务?

时间:2014-05-23 12:13:44

标签: ruby-on-rails ruby rake capistrano capistrano3

哪种方式,我可以通过远程服务器上的capistrano运行rake命令。

例如我有lib/task/reparse.rake一些方法

desc "it's take csv file, makes some changes and fill db with this info"
task :example1 => :environment do
  require 'csv'
  rows_to_insert = []
  # some actions
  # ...
end
本地服务器上的

一切都很好 - 我只是运行rake reparse:example1 它的工作(正确填充db)。 所以问题是 - 如何在部署后在真实主机上运行此命令?

我使用的是rails 4.1 + capistrano 3。

P.S。网站上的例子对我不起作用 How do I run a rake task from Capistrano?

如果我尝试cap production rake:invoke task=reparse:land 它失败了:

cap aborted!
Don't know how to build task 'rake:invoke'

一些修正

namespace :somenamespace do
  task :runrake do  
    on roles(:all), in: :sequence, wait: 5 do      
      within release_path do
        execute :rake, ENV['task'], "RAILS_ENV=production"
      end 
    end
  end
end

以这种方式开始通过

执行
cap production somenamespace:runrake task=custom_task_file:custom_method1

5 个答案:

答案 0 :(得分:5)

基于capistrano/rails gem:https://github.com/capistrano/rails/blob/master/lib/capistrano/tasks/migrations.rake

namespace :somenamespace do
  task :runrake do
    on roles(:all) do
      within release_path do
        with rails_env: fetch(:rails_env) do
          execute :rake, ask :task
        end
      end 
    end
  end
end

答案 1 :(得分:3)

所以我一直在努力。接缝运作良好。但是,您需要一个形成器才能真正利用代码。

如果您不想使用格式化程序,只需将日志级别设置为调试模式。

SSHKit.config.output_verbosity = Logger::DEBUG

Cap Stuff

namespace :invoke do
  desc 'Run a bash task on a remote server. cap environment invoke:bash[\'ls -la\'] '
  task :bash, :execute do |_task, args|
    on primary :app do
      within deploy_to do
        with rails_env: fetch(:rails_env) do
          SSHKit.config.format = :supersimple
          execute args[:execute]
        end
      end
    end
  end

  desc 'Run a rake task on a remote server. cap environment invoke:rake[\'db:migrate\'] '
  task :rake, :task do |_task, args|
    on primary :app do
      within current_path do
        with rails_env: fetch(:rails_env) do
          SSHKit.config.format = :supersimple
          rake args[:task]
        end
      end
    end
  end
end

这是我为使用上面的代码而构建的格式化程序。它基于:在sshkit中内置的textsimple,但它不是一种调用自定义任务的坏方法。哦,这很多不适用于最新版本的sshkit gem。我知道它适用于1.7.1。我这样说是因为master分支已经改变了可用的SSHKit :: Command方法。

module SSHKit
  module Formatter
    class SuperSimple < SSHKit::Formatter::Abstract
      def write(obj)
        case obj
        when SSHKit::Command    then write_command(obj)
        when SSHKit::LogMessage then write_log_message(obj)
        end
      end
      alias :<< :write

      private

      def write_command(command)
        unless command.started? && SSHKit.config.output_verbosity == Logger::DEBUG
          original_output << "Running #{String(command)} #{command.host.user ? "as #{command.host.user}@" : "on "}#{command.host}\n"
          if SSHKit.config.output_verbosity == Logger::DEBUG
            original_output << "Command: #{command.to_command}" + "\n"
          end
        end

        unless command.stdout.empty?
          command.stdout.lines.each do |line|
            original_output << line
            original_output << "\n" unless line[-1] == "\n"
          end
        end

        unless command.stderr.empty?
          command.stderr.lines.each do |line|
            original_output << line
            original_output << "\n" unless line[-1] == "\n"
          end
        end

      end

      def write_log_message(log_message)
        original_output << log_message.to_s + "\n"
      end
    end
  end
end

答案 2 :(得分:2)

您可以创建相应的capistrano任务来运行特定的rake任务:

namespace :guests do
  desc 'Remove guest users older than 7 days'
  task :clean do
    on roles(:app) do
      within release_path do
        with rails_env: fetch(:rails_env) do
          execute :rake, 'guests:delete_old_guest_users'
        end
      end
    end
  end
end

答案 3 :(得分:1)

您需要在Capistrano配置中加载自定义rake任务:

# config/deploy.rb || config/deploy/production.rb
load 'lib/task/reparse.rake'

检查控制台cap -T

中的新任务

答案 4 :(得分:0)

尝试capistrano-rake

在不搞乱自定义capistrano任务或详细介绍的情况下,您只需安装gem即可开始在远程服务器上执行rake任务,如下所示:

print _parse_args() == argparse.Namespace(config_file=None) # True