Iterating Sub-Projects with Rake

Large parts of our system are written in C++, and we have some
components that consist of several separate C++ projects that are
related to each other. We are careful to follow the
Acyclic Dependency Principle,
but we’d still like to be able to build the whole family of projects
together and in the correct order.

I recently helped a co-worker simplify this process, and I thought our
solution was worth sharing. It’s a pretty simple idea, but it
requires a mental shift from “Rake is just a build DSL” to “Rake is
Ruby”.

We use gitslave to create a
master project that includes all of the sub-projects. We then
create a top-level Rakefile in the master project.

The basic idea is that we have a set of related projects that must be
built in some order, and we have a common set of Rake tasks that we’d
like to run on each of the projects.

Rakefile

PROJECTS=%w{child parent1 parent2 grandparent}

defiterating_task(*task_names)

task_names.eachdo|task_name|

tasktask_namedo

iteratetask_name

end

end

end

iterating_task:default,:build,:test,:clean,:clobber,:deploy

defiterate(task_name)

PROJECTS.eachdo|project|

Dir.chdir(project)do

puts"Running `rake #{task_name}' in #{p}"

sh"rake #{task_name}"

end

end

end

I’d love to move iterating_task down to the bottom of the file, but
it needs to be defined before use.

With this Rakefile in place, we can run something like rake test
in the master project, and will iterate through all of the projects in
order and run their tests.