假设我有这个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
命令不会通过捆绑包执行?
谢谢
答案 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