Dev Series #1
Beginning Rake Tips
Welcome to 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.
I also rolled up these tips as a sample project: https://github.com/shawnbaden/dev-series-1
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
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