Building Shareable Rake Tasks with a Gem

25 October 2016 on . 3 minutes to read

Rake

Too much Repition

The situation: lots of projects, and you’ve got important code to share. Except in this case, your code are rake tasks for devops, and you can’t just throw it into a module within a gem and have it run properly. Sharing rake tasks via a gem is slightly more complex than sharing module or code classes with a gem, so read on to see how I made it happen.

DRY Your Projects

In an earlier post (Rails 5 Base Application) I mentioned a recent uptick in the number of new projects I’ve started which has finally brought me to the point that I’ve established some common processes and started to extract them where possible. One component of my basic application are some custom rake tasks I use for heroku deploys and database backups. On rare occassions, I want something minor changed in that task. In the past, that means I’ll go and copy past the updated code around 3 or 4 active projects. Now, with that list rapidly growing, I need a way to have shared code amongst all my projects. Time to bring Bundler and RubyGems up to bat.

Gem Creation and Sharing Your Code

What follows are some basic steps to extract rake my_task:talk which is shared among applications into a local gem repository to share among your apps.

Bundle Init

First, some basic steps to get a gem up and running (for local dev, I won’t go into publishing it here):

mkdir rake_gem
cd rake_gem
bundle init

This leaves you with a skeleton to get you going and a few prompted customization options. Now, to the good stuff.

Code and Structure

The below snippets assume you’re still in the rake_gem directory.

#./lib/tasks/my_task
namespace :my_task
  desc 'Say something'
  task :talk
    puts "Something."
  end
end

Now, since the above is in lib/tasks rather the gem directory, you have to make sure it’s both included in your code, and also available to Rails when it’s included as a gem. We’ll solve this problem in reverse. What’s needed is a Railtie so that way Rails (and therefore rake) is aware of the task. Besides just the documentation, Andy Atkinson has an older but succinct rundown of part of the process which you may find helpful.

#./lib/rake_gem/railtie.rb
class RakeGem::Railtie < Rails::Railtie
  rake_tasks do
    load 'tasks/my_task.rake'
  end
end

Finally, make sure your Railtie is included in your gem.

#./lib/rake_gem.rb
require "rake_gem/version"
require "rake_gem/railtie" if defined?(Rails)

module RakeGem
end

At this point, you can test it out locally. Go to your rails app and add the following to your Gemfile:

gem 'rake_gem', path: "~/rake_gem"

Bundle install to ensure Bundler’s happy with your gem then testing it will give you the following:

bundle install
bundle exec rake my_task:talk
Something

Wrap Up

That’s all there is to it. You can now publish this gem or just use it locally for testing; whatever suits your needs. I try to keep these examples as succinct as possible to prevent getting stuck in the weeds and to showcase the MVP version of functionality.


If you enjoy having free time and the peace of mind that a professional is on your side, then you’d love to have me work on your project.

Contact or view a list of available services to see how I’ll make your life better, easier and bring satisfaction back into you running your business.