« Wikileaks and the Obama Administration | Main | The Republican Party creates its own noose, but the Democrats don't apply it »

March 28, 2011

Proposed Modification to Rake's Discovery of Gem Tasks

Background:

I'm building a Sinatra app with the orientdb gem, and I'm working on making a couple basic rake tasks, so that people using OrientDB and ruby can have access to database tasks like activerecord has.  But since I'm not using Rails, I don't have railties and personally, I'd rather not have to require the files of all the tasks I could have access to inside the Rakefile.


Solution:

I patched Rake::Application, so that it would discover any and all tasks inside of the folder 'tasks' inside your gems load_paths.  The cool thing about this is that it could make the need to have tasks inside a railtie absolutely unnecessary, because rake would find them for you anyway.  The only requirement this introduces aside from a changed directory structure is Bundler.

I know gems currently don't necessarily use this format for placing their rake tasks, but if gems placed their tasks in [load_path]/tasks then non-rails users could access the great rake tasks they contain.  [Update - new patch now finds all tasks in all load path directories, so there's no need to put the tasks in a specific folder.]

If you want to add the patch to your rake so that you can start using custom rake tasks in your own gems and discover all other tasks that your gems allow you to use, the code is below.

[UPDATE - Until the time when rake accepts the patch, you can now use the gem I made.  In your Rakefile, just do the following.  Railties are now unnecessary!]

====

#Rakefile
require 'rake'
require 'alltasks'

====

That's it!

The code for the rake patch:

###
# We are replacing Rake::Application.raw_load_rakefile
# This will be in lib/rake.rb for people that installed it via gem and in lib/rake/application.rb for people that have the repository
###

    def raw_load_rakefile # :nodoc:
      rakefile, location = find_rakefile_location
      if (! options.ignore_system) &&
          (options.load_system || rakefile.nil?) &&
          system_dir && File.directory?(system_dir)
        puts "(in #{Dir.pwd})" unless options.silent
        glob("#{system_dir}/*.rake") do |name|
          add_import name
        end
      else
        fail "No Rakefile found (looking for: #{@rakefiles.join(', ')})" if
          rakefile.nil?
        @rakefile = rakefile
        Dir.chdir(location)
        puts "(in #{Dir.pwd})" unless options.silent
        $rakefile = @rakefile if options.classic_namespace
        load File.expand_path(@rakefile) if @rakefile && @rakefile != ''
        options.rakelib.each do |rlib|
          glob("#{rlib}/*.rake") do |name|
            add_import name
          end
        end
      end     

     ####
     # New Code
     ####
      # load gem rake files if Bundler is defined
      if defined?(Bundler)
        Bundler.load.specs.each do |spec|
          #look for tasks in the gem's load paths
          spec.load_paths.each do  |load_path|
            if File.directory?(load_path)
              Dir.foreach(load_path) do |path|
                check_dir = File.join(load_path, path)
                if File.directory?(check_dir)
                  glob("#{check_dir}/**/*.rake") do |name|
                    add_import name
                  end
                end
              end
            end
          end
        end
      end
     ####
     # End New Code
     ####
  
      load_imports
    end

 

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d8341e8a9253ef014e8707a853970d

Listed below are links to weblogs that reference Proposed Modification to Rake's Discovery of Gem Tasks:

Comments

blog comments powered by Disqus
Powered by TypePad