Выполнить системную команду с использованием Rake вне области пакета

#ruby-on-rails-4 #rake #bundler

#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 `` amp; exec() sa well, same thing
    end
  end
end
  

Backup gem — это отдельное приложение ruby gem, зависимости которого необходимо изолировать от пакета приложений. Другими словами, она не может быть частью Gemfile . Этот драгоценный камень просто устанавливается поверх gem install backup

Когда я запускаю backup команду через консоль bash, она успешно запускается:

 $ 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 помощью from bash

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

… это означает, что backup команда выполняется через bundler при запуске как часть задачи rake.

мой вопрос: как я могу запустить rake db:dump:backup вне области действия пакета, что означает, что backup команда не будет выполняться через пакет?

Спасибо

Комментарии:

1. … кстати, он также успешно работает как удаленная задача capistrano

2. Вы решили это? У меня такая же проблема…

3. нет, не с помощью Rake я все еще использую Capistrano для этого. Отправка ответа с примером Capistrano

Ответ №1:

Я нашел обходной путь для этой проблемы здесь:

 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. Я не могу отблагодарить вас достаточно — эта проблема убивала меня сегодня вечером!! Ты суперзвезда!

2. Спасибо, могу я выбрать тебя своим новым богом?

3. Также применяется, если вы пытаетесь запустить это, вызвав оболочку в приложении. Вы можете получить «команда не найдена» и «rubygems_integration» и «не удается найти исполняемый файл» (добавление, чтобы помочь поисковикам найти это). Просто оберните вызов вашей оболочки в этот блок «Bundler.with_clean_env do», и это сработает. Большое спасибо!!

Ответ №2:

Вот решение 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