10

Let say I have this Rake task:

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

Backup gem is stand alone ruby gem application which dependencies needs to be isolated from application bundler. In other words it cannot be part of Gemfile. This gem is simply installed over gem install backup

When I run backup command over bash console, it successfully run:

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

When I execute rake db:dump:backup I will get

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

...which is the same thing when I run backup command with bundle exec from bash

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

...meaning that the backup command is executed over bundler when run as part of rake task.

my question: How can I run rake db:dump:backup outsite the bundle scope, meaning that backup command won`t be executed over bundler?

Thank you

equivalent8
  • 13,754
  • 8
  • 81
  • 109

2 Answers2

20

I found a workaround for this problem 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

The key here is to enclose the code that must not run under bundler's environment in a block like this:

Bundler.with_clean_env do
  # Code that needs to run without the bundler environment loaded
end
Ernesto
  • 3,837
  • 6
  • 35
  • 56
  • 2
    I can't thank you enough - this issue has been KILLING me tonight!! You superstar! – Andy Jeffries Oct 07 '15 at 21:03
  • 2
    Thanks, can I elect you as my new god? – Edison Machado Aug 11 '16 at 22:26
  • 1
    Also applies if you are trying to run this by invoking a shell within an app. You may get "command not found" and "rubygems_integration" and "cannot find executable" (adding to help searchers find this). Just wrap calling your shell within this "Bundler.with_clean_env do" block and it works. Thanks So Very Much!! – JosephK Aug 16 '17 at 16:35
0

Here is the Capistrano solution I was mentioning for those who need it while we figure out how to fix 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
equivalent8
  • 13,754
  • 8
  • 81
  • 109