2014-06-18 25 views
9

讓我們說我有這樣的Rake任務:用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 

備份的寶石是站在哪個依賴關係需要從應用程序捆綁隔離單獨的紅寶石寶石應用。換句話說,它不能成爲Gemfile的一部分。這種寶石只需安裝在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) 

...這是同樣的事情,當我運行備份命令與bundle exec從bash

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

...這意味着backup命令在作爲rake任務的一部分運行時通過bundler執行。

我的問題:如何運行rake db:dump:backup outsite管束範圍,這意味着backup命令那倒在捆綁被執行?

謝謝

+0

...順便說一句,它成功地作爲一個遠程capistrano任務 – equivalent8

+0

你解決了嗎?我有同樣的問題... – Lichtamberg

+0

不,不是由Rake我仍然使用Capistrano來做到這一點。以Capistrano爲例發帖回覆 – equivalent8

回答

17

我發現了一個辦法解決這個問題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.with_clean_env do 
    # Code that needs to run without the bundler environment loaded 
end 
+2

我不能夠感謝你 - 這個問題已經殺死我今晚!你是超級巨星! –

+2

謝謝,我可以選擇你作爲我的新神嗎? –

+1

如果您嘗試通過在應用程序中調用shell來運行此應用程序,也適用。您可能會收到「找不到命令」和「rubygems_integration」和「無法找到可執行文件」(添加以幫助搜索者找到此文件)。只需在這個「Bundler.with_clean_env」塊中調用你的shell,它就可以工作。非常感謝! – JosephK

0

這裏是Capistrano的解決方案,我被提爲那些誰需要它,而我們找出如何解決耙。

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