Search code examples
ruby-on-railsrake-task

How can I require a gem inside a rake task that isn't in gemfile?


I'm trying to use a gem in a rake task, but I don't want to include it in the dev build. So not in the development part of the Gemfile.

I don't want to include it in the Gemfile, because it's slow to install, and on the M2 Mac it doesn't always work.

So I'm trying to only include it in the rake task that's going to use it.

Here's my contrived example

namespace :utility do
  task contrived_test_funct: :environment do
    begin
      gem 'rmagick'
    rescue LoadError
      system("gem install rmagick")
      gem 'rmagick'
    end

    require 'RMagick'
    file_names = Dir.glob(File.join("/tmp", "**", "*"))
    file_names = file_names.select { |f| f.include?(".pdf") }
    file_names.each do |file_name|
      im = Magick::Image.read(file_name)
      im[0].write(filename.gsub(".pdf",".jpg"))
    end
  end
end

This should just take all the PDF's in my temp dir and spit them out as jpgs. And if I have the gem in my gemfile and remove the begin/rescue block it all works a treat on my local system.

When I remove the gemfile changes and uncomment the begin/rescue block, it falls over

I get this

Gem::LoadError: rmagick is not part of the bundle. Add it to your Gemfile.

QUESTION: How can I require a gem only in a specific rake task inside a rails app/repo ?


Solution

  • I have a partial solution. Not perfect but it gets me across the line.

    You can add a new gem group in the rails gemfile

    group :special_group, optional: true do
      gem 'rmagick'
    end
    

    Then in the rake task you can require the gem. You can also catch the error and let your fellow devs know how to install the gem.

    begin
      require 'RMagick'
    rescue LoadError
       abort("RMagick is selectively installed, Run `bundle config set --local with rmagick`" +
     "and then bundle install and this rake task again")
    end