2
votes

This question follows the "Make rake task from gem available everywhere?" for which I'm not fully satisfied with the Railties approach since it induces a dependency on Rails3 which seems to me overkilling compared to what I want. Also, I dislike the idea to create an extra binary as suggested in this question

So, assuming I have the below layout:

.
├── CHANGELOG.md
├── Gemfile
├── Gemfile.lock
├── LICENCE.md
├── README.md
├── Rakefile
├── my_gem.gemspec
├── lib
│   ├── my_gem
│   │   ├── common.rb
│   │   ├── loader.rb
│   │   ├── tasks
│   │   │   └── sometasks.rake
│   │   └── version.rb
│   └── my_gem.rb

where lib/my_gem/tasks/sometasks.rake has some nested rake tasks definition:

#.....................
namespace :n1 do
    #.....................
    namespace :n2 do

        desc "Tasks n1:n2:t1"
        task :t1 do |t|
            puts "Task 1"
        end

        desc "Tasks n1:n2:t2"
        task :t2 do |t|
            puts "Task 2"
        end

    end # namespace n1:n2
end # namespace n1

How can I easily share these tasks in another external Rakefile with a simple syntax such as require "my_gem/sometasks" once the gem is installed?

I tested the following configuration in a separate directory with success yet I still think it's a complicated syntax. Any help to simplify the load / include/ require would be welcome:

  • add a GemFile containing

    gem 'my_gem', :path => '~/path/to/my_gem'

  • add a Rakefile with the following content:

    require "my_gem"
    load "my_gem/tasks/sometasks.rake"
    
    desk "Test my_gem"
    task :toto do |t|
    puts "task toto"
    end 
    

In the above configuration, it works:

$> bundle exec rake -T
 rake n1:n2:t1       # Task n1:n2:t1
 rake n1:n2:t1       # Task n1:n2:t2
 rake toto           # Test my_gem

Yet if I get rid of .rake extension in the Rakefile, I have a load error

rake aborted!
LoadError: cannot load such file -- my_gem/tasks/sometasks

Any hint?

1

1 Answers

3
votes

I found a way, inspired from Bundler to offer a simplified interface (and [gem_tasks.rb](https://github.com/bundler/bundler/blob/master/lib/bundler/gem_tasks.rb):

  • create a file lib/my_gem/sometasks_tasks.rb with an install_tasks method

    require 'rake'
    
    module MyGem
      class SomeTasks
        include Rake::DSL if defined? Rake::DSL
        def install_tasks
           load 'my_gem/tasks/sometasks.rake'
        end
      end 
    end 
    MyGem::SomeTasks.new.install_tasks
    
  • In the application’s Rakefile, it is now enough to add require 'my_gem/sometasks_tasks'