A Gem that Provides Rake Tasks
I'm building a Gem and I want it to provide Rake tasks when it is used in other projects.
I'm going to create a separate .rake
file for each of tasks I want to expose. These will be in a folder named after the namespace I want to use. I'm also going to create a Rakefile
inside my gem which will expose these to the client (I might have another Rakefile which contains the tasks I'm using during the development of the gem but I don't want to expose these to the client).
I'm going to have a namespace called foobar
and two tasks, first
and second
. This way I can use the tasks by calling rake foobar:first
etc. I'm going to use this directory structure:
. └── lib ├── my_gem │ ├── tasks │ │ └── foobar │ │ ├── first.rake │ │ └── second.rake │ └── Rakefile └── my_gem.rb
The Rakefile contains the following:
require 'my_gem'
path = File.expand_path(__dir__)
Dir.glob("#{path}/tasks/**/*.rake").each { |f| import f }
and my .rake
files look like:
namespace :foobar do
desc "Say hello"
task :hello do
puts "Hello world"
end
end
Using the tasks in a ruby project
To use these tasks in another plain-old-ruby project, that project needs to include this in it's Rakefile:
require 'my_gem'
spec = Gem::Specification.find_by_name 'my_gem'
rakefile = "#{spec.gem_dir}/lib/my_gem/Rakefile"
load rakefile
Using the tasks in a Rails project
To play nicely with Rails, our my_gem
can provide a railtie. This should live in lib/my_gem
.
require 'my_gem'
require 'rails'
module MyGem
class Railtie < Rails::Railtie
railtie_name :my_gem
rake_tasks do
path = File.expand_path(__dir__)
Dir.glob("#{path}/tasks/**/*.rake").each { |f| load f }
end
end
end
and the my_gem.rb
should be modified to include the loading of the railtie:
module MyGem
require 'my_gem/railtie' if defined?(Rails)
end
Member discussion