Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to recursive rake? -- or suitable alternatives

I want my projects top level Rakefile to build things using rakefiles deeper in the tree; i.e. the top level rakefile says how to build the project (big picture) and the lower level ones build a specific module (local picture).

There is of course a shared set of configuration for the minute details of doing that whenever it can be shared between tasks: so it is mostly about keeping the descriptions of what needs building, as close to the sources being built. E.g. /Source/Module/code.foo and cie should be built using the instructions in /Source/Module/Rakefile; and /Rakefile understands the dependencies between modules.

I don't care if it uses multiple rake processes (ala recursive make), or just creates separate build environments. Either way it should be self-containable enough to be processed by a queue: so that non-dependent modules could be built simultaneously.

The problem is, how the heck do you actually do something like that with Rake!? I haven't been able to find anything meaningful on the Internet, nor in the documentation. I tried creating a new Rake::Application object and setting it up, but whatever methods I try invoking, only exceptions or "Don't know how to build task ':default'" errors get thrown. (Yes, all rakefiles have a :default). Obviously one could just execute 'rake' in a sub directory for a :modulename task, but that would ditch the options given to the top level; e.g. think of $(MAKE) and $(MAKEFLAGS).

Anyone have a clue on how to properly do something like a recursive rake?

like image 908
TerryP Avatar asked Jun 12 '10 00:06

TerryP


2 Answers

you can require rake files from other rake files and run the tasks from the required file.

put this in rakefile.rb:

require 'foo/rakefile.rb'

task :default => [:bar]

put this in foo/rakefile.rb:

task :bar do
  puts "baz"
end

run the root level rakefile and it will print "baz" to the screen. you should be able to organize your rake files and common code however you want using this idea

like image 81
Derick Bailey Avatar answered Nov 11 '22 12:11

Derick Bailey


As mentioned in my earlier post, here is the code snippet that supports almost like recursive rake behavior including options passing, dry-run, trace, top-level-task.

rake:

#!/usr/bin/env ruby

begin
  require 'rubygems'
  gem 'rake'
rescue LoadError
end

$sub_directories = []
$top_level_task_provided__skip_subdir = 0
module Rake
   REDUCE_COMPAT = true if ARGV.include?("--reduce-compat")
   RAKE_OPTS = ARGV.clone.join(" ") 
   module DSL
     def subdirs dirs
        puts "DIRS: #{dirs}"
        $sub_directories = dirs
     end
   end
end

require 'rake'

Rake.application.standard_exception_handling do
   Rake.application.init
   $top_level_task_provided__skip_subdir = 1 if Rake.application.top_level_tasks.size >= 1 and Rake.application.top_level_tasks[0] != "default"
   Rake.application.load_rakefile
   if Rake.application.tasks.size == 0 and $sub_directories.size != 0 then
      desc "Default task when only subdirs is present in a rakefile"
      task :default do
         puts "Default subdir task"
      end
   end
   Rake.application.top_level
end

if $top_level_task_provided__skip_subdir == 0 then
    $sub_directories.each do |d|
        unless rake_system("cd #{d} && pwd && ruby #{File.expand_path $0} #{Rake::RAKE_OPTS}") then
            exit(1)
        end
    end
end
like image 39
siva008 Avatar answered Nov 11 '22 12:11

siva008