Rake is a popular task runner in Ruby.
What is a task?
- Making a backup of your database
- Running your tests
- Gathering & reporting stats
These are small tasks that without Rake would be scattered all over your project on different files.
Rake centralizes access to your tasks.
Rake also makes a few things easier, like finding files that match a certain pattern & that have been modified recently.
One more thing:
Don’t confuse Rake with Rack, very similar names, but completely different things.
- Rake is a task runner.
- Rack helps Ruby servers & frameworks work together.
Now:
Let’s explore Rake in more detail!
Who Uses Rake?
Rails!
If you have done anything with Rails at all, you’re probably familiar with the rake db:migrate
command.
Or rake routes
.
That’s Rake in action right there.
Notice that Rails, since version 5.0, allows you to call most rake
commands with rails
instead.
In other words:
You can do rails db:migrate
, but Rake is still doing the work.
How to Write a Rake Task
Here’s a simple Rake task:
desc "Print reminder about eating more fruit." task :apple do puts "Eat more apples!" end
You can put this code inside a file named Rakefile
, or if you’re using Rails, you can save this under lib/tasks/apple.rake
.
To run this task:
rake apple # "Eat more apples!"
Inside the task, you can write normal Ruby code, but there are some helpful Rake methods you can use.
For example:
- ruby (run a Ruby file)
- sh (run system commands)
- safe_ln (create a symbolic link in your file system)
Rake includes the FileUtils
module.
That means you can copy files with cp
, create directories with mkdir_p
, and even change file permissions with chown
.
Here’s an example:
task :clean_cache do rm_r FileList["tmp/cache/*"] end
Careful with rm_r
(remove with recursion) as it will delete files without confirmation, if you want to add a confirmation step you can add a dependent task (covered later in this article) & raise an exception if you don’t want to continue.
Running Rake Commands Inside Another Directory
You may want to run a Rake command inside a specific directory.
Here’s how:
task :import do puts "Importing data..." Dir.chdir(Rails.root.join("data")) { ruby "load-data.rb" } end
In this example, I’m running a Ruby script inside the data
folder in my Rails project.
How to Use Namespaces in Rake
Because tasks can have similar names, it’s easy to use the same name twice.
That’s why Rake has namespaces.
For example:
You can create a backup
namespace for all your backup tasks.
Like this:
namespace :backup do task :create do # ... end task :list do # ... end task :restore do # ... end end
To run a namespaced task:
rake backup:create
Dependent Tasks
Rake allows you to define a list of other tasks that must run before the current task.
With this, you can do any setup that the task needs.
Example:
task create_examples: "load_database" do # ... end
In this example, load_database
will run before create_examples
.
The list of dependent tasks can also be an array of strings or an array of symbols.
Run A Rake Task Within Another Task
If instead of having a set of task that run BEFORE the current task, you want to run another task within the current task, then you can use the following code.
Example:
task :coverage do ENV['COVERAGE'] = 'true' Rake::Task["test"].execute end
This can be helpful to set environment variables that enable test coverage & other options.
How to Use Rake Rules
Rules define file extension transformations.
Example:
task compress: FileList["/tmp/*.txt"].ext(".txt.gz") rule '.txt.gz' => '.txt' do |t| sh "gzip", "-k", "-f", t.source end
The benefit of using rules is that once a file has been compressed, it won’t be compressed again until the source file changes.
Notice a few things in this code:
- We use the
FileList
class, which is part of Rake, to define a list of files we want to work with. - The rule starts with the TARGET extension, to make the rule match we have to use
.ext(".txt.gz")
on theFileList
. - This
.txt.gz => .txt
doesn’t mean we go fromtxt.gz
totxt
, it’s the other way around. The arrow is hash syntax.
Rake Options & Commands
Here’s a list of useful Rake options:
- rake -T (list available tasks)
- rake -P (list tasks & their dependencies)
- rake -W (list tasks & where they are defined)
- rake -V (verbose mode, echo system commands)
- rake -t (debugging mode)
- rake -f (use a specific Rakefile)
For example, in a Rails app:
> rake -T test rake test # Runs all tests in test folder except system ones rake test:db # Run tests quickly, but also reset db rake test:system # Run system tests only
Summary
You have learned about Rake, a popular task runner for Ruby.
Use rake -T
to find out what tasks are available, create your own tasks & add them to the Rakefile
, or inside the lib/tasks
folder, and remember that Rake
& Rack
are different things.
Don’t forget to share this article so more people can enjoy it 🙂
Thanks for reading!
Love your articles , Thanks.
Thanks for reading Henry! 🙂
Simple to follow, but with some great takeaway tips. I especially liked the useful command line options. Thanks 🙂
Thanks for reading Andrew! 🙂
Very hepfull Jesus. Thanks you… I will ‘rake’ backup’s database….:)
Thank you Simon! Regular backups are always good 🙂
Very informative 🙂 Thanks
Thanks for reading Shena! 🙂