Home / Alt manpages / rake(1)

  • rake(1)
  • User command
  • linux

Build a Small Ruby Project Safely with Rake

You will finish with a small Rake project that has a named task, a dependency, an automatically loaded helper task, and a dry-run check before it writes a file. The examples use Rake 13.0.6, installed here as the rake package. Allow about fifteen minutes. You need Ruby, Rake, a shell, and a directory where you can create and remove test files.

Rake reads tasks and dependencies from Ruby files. Its usual file is Rakefile; a directory named rakelib is also searched for .rake files. Rake does not need root privileges for this workflow. Do not run it with sudo unless the task is deliberately managing a root-owned project, because task actions can run arbitrary Ruby and shell commands.

1. Check the installed command

Start in the project directory, not in a parent directory that might contain an unrelated Rakefile:

$ command -v rake
/usr/bin/rake
$ rake --version
rake, version 13.0.6

The installed manual documents Rake 11.2.2, while the executable reports 13.0.6. That difference is a reminder to treat the installed command and its output as authoritative for this machine. Use rake -V or rake --version when a script or build report needs to record the version.

Checkpoint: if command -v rake finds nothing, stop and use your normal package manager or Ruby setup. Do not copy a Rakefile into a random directory and assume the command is available there.

2. Define one task in a Rakefile

Create a file named Rakefile in a disposable project directory. This task writes a short greeting, so choose a directory where that file does not contain useful data:

desc "Create a greeting file"
task :greet do
  File.write("greeting.txt", "hello\n")
end

The desc line supplies the description shown by rake -T. The task body is ordinary Ruby. Rake evaluates it only when the task is invoked, so merely listing tasks does not create the output.

Run the task and inspect the result:

$ rake greet
$ test -s greeting.txt && cat greeting.txt
hello

A task runs once per Rake invocation. If you run rake greet greet, Rake still invokes the named task once. To run the work again, start a new Rake process, or use a task designed to remove or refresh its output.

3. Add a dependency and inspect the task graph

Make an aggregate task depend on greet:

desc "Create a greeting file"
task :greet do
  File.write("greeting.txt", "hello\n")
end

task :all => [:greet]

The dependency says that greet must be available before all runs. It does not add an implicit file timestamp check. Rake tasks are not automatically make rules just because Rake is make-like.

Inspect the dependency tree without executing the task:

$ rake -P
rake check
rake greet
rake all
    greet

Your output can include other tasks from installed or project files. The useful line here is the indented greet beneath all. Use rake -T when you need the public, described tasks rather than the complete graph.

4. Load helper tasks from rakelib

Rake automatically imports .rake files from rakelib. Put a separate check there:

desc "Check the greeting file"
task :check do
  abort "greeting.txt is missing" unless File.file?("greeting.txt")
  puts "greeting file exists"
end

Now list the described tasks:

$ rake -T
rake check  # Check the greeting file
rake greet  # Create a greeting file

Rake searches for a Rakefile in the current directory and then parent directories unless told not to. That convenience can become a distraction in a monorepo: rake -N -T disables the parent-directory search. Use rake -f path/to/SpecificRakefile -T when the file is not the one Rake would normally choose.

5. Preview a task before it changes files

Use the dry-run option before a task that writes, deletes, packages, migrates or deploys:

$ rake -n greet
rake greet
rake (dry run) execute greet

The exact trace wording can vary with the installed Rake release. The useful property is that -n does not execute the task action. Confirm this by checking the file timestamp or existence in a directory that started without the output. A dry run is only a preview of Rake's task execution. Ruby code evaluated while the Rakefile is loaded can still have side effects, so keep top-level code in a Rakefile free of writes and external commands.

Warning: rake -B forces all prerequisites, including ones that would otherwise be considered up to date. It is not a safer version of a normal build. Review the task graph and use it only when rebuilding everything is intended.

6. Diagnose the first failure

Ask Rake what it knows before changing the project:

$ rake -T
$ rake -W greet
$ rake -D greet
$ rake --trace greet

-T lists described tasks, -W reports where a matching task was defined, and -D prints its description. The trace option shows task invocation and execution, and enables a full backtrace. Use it when a dependency ran earlier than expected or an exception is hidden in a larger build.

If Rake reports that no task matches, check the spelling, current directory, selected -f file, and whether the task is in a .rake file under rakelib. If an action fails after partially writing an output, keep the original input and inspect the incomplete output before rerunning. Prefer writing to a new temporary name and renaming it only after successful validation when the task manages valuable files.

Done means

  • rake --version identifies the executable you tested.
  • The project has a Rakefile with a named task and an explicit dependency.
  • rake -T and rake -P show the tasks and graph you expect.
  • A helper task in rakelib is discovered without manually loading it.
  • rake -n was used before a task with meaningful side effects.
  • You know whether Rake is reading the current directory's file or a parent project's file.