使用Rake在Bundle范围外执行系统命令

时间:2014-06-18 11:27:47

标签: ruby-on-rails-4 rake bundler

假设我有这个Rake任务:

namespace :db do
  namespace :dump do.
    desc 'Backup database dump to s3'
    task :backup => :environment do 
      cmd = ['backup', 'perform',  '-t project_backup',  "-c #{Rails.root.join 'lib', 'backup', 'config.rb'}"] 
      system(*cmd)                      # ...I've tried `` & exec() sa well, same thing
    end
  end
end

备份gem是独立的ruby gem应用程序,其依赖关系需要与应用程序捆绑器隔离。换句话说,它不能成为Gemfile的一部分。此gem只需安装在gem install backup

当我通过bash控制台运行backup命令时,它成功运行:

$ backup perform -t validations_backup -c /home/equivalent/my_project/lib/backup/config.rb

当我执行rake db:dump:backup时,我会得到

backup is not part of the bundle. Add it to Gemfile. (Gem::LoadError)

...当我从bash

运行带有bundle exec的备份命令时,这是同样的事情
$ bundle exec backup perform -t validations_backup -c /home/equivalent/my_project/lib/backup/config.rb

...意味着当作为rake任务的一部分运行时,backup命令在bundler上执行。

我的问题:如何在捆绑范围内运行rake db:dump:backup,这意味着backup命令不会通过捆绑包执行?

谢谢

2 个答案:

答案 0 :(得分:20)

我找到了解决此问题的方法here

namespace :db do
  namespace :dump do
    desc 'Backup database dump to s3'
    task :backup do
      Bundler.with_clean_env do
        sh "backup perform -t project_backup -c #{Rails.root.join 'lib', 'backup', 'config.rb'}"
      end
    end
  end
end

这里的关键是将不能在Bundler环境下运行的代码包含在这样的块中:

Bundler.with_clean_env do
  # Code that needs to run without the bundler environment loaded
end

答案 1 :(得分:0)

这是Capistrano解决方案,当我们弄清楚如何修复Rake时,我提到了那些需要它的人。

class BackupDatabaseCmd
  def self.cmd
    # some logic to calculate :
    'RAILS_ENV=production backup perform -t name_of_backup_task -c  /home/deploy/apps/my_project/current/lib/backup/config.rb'
    # in the configuration file I'm loading `config/database.yml`
    # and passing them to backup gem configuration
  end
end

namespace :backup do
  namespace :database do
    task :to_s3 do
      on roles(:web) do
        within release_path do
          with rails_env: fetch(:rails_env) do
            execute(BackupDatabaseCmd.cmd)
          end
        end
      end
    end
  end
end

# cap production backup:database:to_s3