Saturday, January 14, 2012

Rake Fundamentals: FileLists

In the last post, we created a rakefile that will copy a discreet set of *.bin files to a package directory for distribution using a single “publish” task.  But it’s pretty verbose.  We can refactor a bit to make the rakefile smaller, and make it handle an arbitrary list of *.bin files to be published to the /package directory using a FileList.  A FileList is pretty simple – it’s just an array of file names.  We’ll gather up all the *.bin files in the source/bin directory, and iterate through them to dynamically create file tasks for each of them and append each of those file tasks to the publish task’s prerequisite list.  Here we go:

require 'rake'

BIN_DIR     = "source/bin"
PACKAGE_DIR = "package"

directory PACKAGE_DIR

BUILD_PRODUCTS = FileList[File.join(BIN_DIR, "**/*.bin")]
BUILD_PRODUCTS.each do |product|
packaged = product.sub(BIN_DIR, PACKAGE_DIR)
file packaged => product do
cp product, packaged, :verbose => true
end
task :publish => [PACKAGE_DIR, packaged]  
end

desc "publish *.bin files to #{PACKAGE_DIR}"
task :publish

We cut out a bunch of stuff we don’t really need, and all we’re left with on the command line is the publish task:

image

We don’t really care about all the individual file tasks, or the PACKAGE_DIR directory task, we just want our development team to care about the publish task.  So we set BUILD_PRODUCTS to a list of all the *.bin files in the BIN_DIR, and stuffed them all into the publish task that appears in our task list.  And to make it appear in the task list, we just give it a description after we get out of the .each do…end loop.  The completed publish task works just like it did before, except that now it can handle a completely arbitrary list of *.bin files.  Try it out – run “rake publish”, add a file called “file4.bin” to /source/bin, and then run “rake publish” again and see what happens.

1 comment:

Anonymous said...

Brill exactly what I needed. Perfect, thank you so much.