aef
aef

Reputation: 4698

How to stop Rake from unnecessarily executing file tasks with dependencies?

File tasks in Rake should only be executed when the file they are named after doesn't exist yet.

I have one file task that builds a directory and one file task that creates a file within that directory. Now the file cannot be created unless the directory exists, so I set the directory task to be a dependency for the file task:

file "directory" do
  mkdir_p "directory"
end

file "file" => "directory" do
  touch "directory/file"
end

desc "Create file"
task build: "file"

When I first run the build task here, everything works according to plan: first the directory is created, then the file:

$ rake -t build
** Invoke build (first_time)
** Invoke file (first_time)
** Invoke directory (first_time)
** Execute directory
mkdir -p directory
** Execute file
touch directory/file
** Execute build

When I run it a second time after both the file and its containing directory have been created, I would expect Rake to do nothing (not_needed), because all the files the file tasks are related to are already existent. Instead, the directory task is skipped but the file task is executed:

$ rake -t build
** Invoke build (first_time)
** Invoke file (first_time)
** Invoke directory (first_time, not_needed)
** Execute file
touch directory/file
** Execute build

How can I make Rake not run the file task if directory and file both already exist?

Upvotes: 1

Views: 278

Answers (1)

Draco Ater
Draco Ater

Reputation: 21226

Your file task is wrong. It states, as if it creates file in root directory, but actually it creates file in directory directory. Rake checks if the file exists in the root directory, and as it is not there, runs the task. For it to work properly you need to rename the file task:

file "directory/file" => "directory" do
  touch "directory/file"
end

desc "Create file"
task build: "directory/file"

This way Rake check the right file for existence and does not run the 'directory/file' task.

** Invoke build (first_time)
** Invoke directory/file (first_time, not_needed)
** Invoke directory (first_time, not_needed)
** Execute build

Upvotes: 2

Related Questions