Dev Series #1
Beginning Rake Tips
Welcome to Dev Series #1.
Related resources: https://github.com/shawnbaden/dev-series-1
Recently in my first month as a professional software engineer (after more than a decade in quality assurance) I needed to setup several Rake tasks in a couple of different projects. One project I started from scratch and the other was an existing project. Beyond a few toy projects over the years, this is my first real Ruby experience and my first time using Rake. During the process I found some best practices for using Rake I plan to use going forward.
Set The Default Task To List All Available Tasks
I found it useful to have Rake’s default task list all available tasks for the project. For a small project I could see setting the default task to the most common task. But for most projects what exactly is the default? Rather than guessing what the default task is or typing out “rake --tasks” just set :default to list all tasks.
task :default do
system "rake --tasks"
end
Keep Rakefile Small And Group Similar Tasks Into Their Own .rake Files
A project’s Rakefile can quickly become difficult to navigate if everyone treats it like a dumping ground. Similar tasks may even end up not grouped together. Rather than trying to group similar tasks together in Rakefile I found it made the most sense to keep Rakefile relatively small and lightweight and then logically group like tasks into separate files.
lib/
tasks/
doughnut.rake # tasks to make doughnuts
cake.rake # tasks to make cakes
Rakefile
Use Namespaces
Closely related to separating similar tasks into individual .rake files, use the same process to create namespaces for similar tasks. I like to match the file name to the namespace.
# doughnuts.rake
namespace :doughnuts do
namespace :raised do
task :doughnut1 do end
task :doughnut2 do end
task :doughnut3 do end
end
namespace :cake do
task :doughnut1 do end
task :doughnut2 do end
task :doughnut3 do end
end
end
# cakes.rake
namespace :cakes do
namespace :raised do
task :cake1 do end
task :cake2 do end
task :cake3 do end
end
end
A Task And A Namespace Can Have The Same Path
I didn’t expect this to work but it turns out a task can share the same path as a namespace. For me this solves the case to “run all” tasks under a namespace. An example illustrates this best.
task :doughnuts do
# run all doughtnuts:* tasks
end
namespace :doughnuts do
task :raised do
# run all doughtnuts:raised:* tasks
end
namespace :raised do
task :doughnut1 do end
task :doughnut2 do end
task :doughnut3 do end
end
task :cake do
# run all doughtnuts:cake:* tasks
end
namespace :cake do
task :doughnut1 do end
task :doughnut2 do end
task :doughnut3 do end
end
end
For Passing Parameters To Tasks, Prefer Environmental Variables
This seems to be the prevailing wisdom and after using environmental varaibles myself I agree.
I like environmetal variables for passing parameters to Rake tasks because it looks cleaner and it provides flexibility in several ways. Sticking with my running example:
> rake doughnuts:raised:doughnut1 NUMBER_TO_MAKE=1 # make 1 raised doughnut1
> rake doughnuts:raised:doughnut2 NUMBER_TO_MAKE=2 # make 2 raised doughnut2
> rake doughnuts:raised:doughnut1 NUMBER_TO_MAKE=3 # make 3 raised doughnut3
> rake doughnuts:raised NUMBER_TO_MAKE=5 # make 5 of each raised doughnut
> rake doughnuts:cake NUMBER_TO_MAKE=4 # make 4 of each cake doughnut
> rake doughnuts:cake:doughnut3 NUMBER_TO_MAKE=2 # make 2 cake doughnut3
> export NUMBER_TO_MAKE=10
> rake doughnuts:raised:doughnut3 # make 10 raised doughnut3
> rake doughnuts:cake # make 10 of each cake doughnut
> rake doughnuts:raised:doughnut2 NUMBER_TO_MAKE=2 # make 2 raised doughnut2
What’s Up Next?
In the next edition of Dev Series I’m eyeing JSON Feed.
Originally published May 20, 2017