Simulating .PHONY in Rake
Published 2012-01-09 @ 16:55
Makefiles have a construct called .PHONY. You declare your task a non-filesystem based task like so:
1 |
.PHONY: mytask |
and then make knows that it shouldn’t force your task to run just because “mytask” doesn’t exist in the filesystem.
Rake doesn’t bother with such nonsense. It doesn’t assume that all tasks map to the filesystem. That’s great. What’s not great is that it does assume that if your file task has non-file-task dependencies, that they should probably rebuild even if those tasks have run. The problem code looks like:
1 2 3 |
def out_of_date?(stamp) # on FileTask @prerequisites.any? { |n| application[n, @scope].timestamp > stamp} end |
In my case, I was trying to intelligently hook up some generated files to isolate so they could access their compiler:
The problem is that :isolate is a regular task, and they calculate their dependencies like so:
1 2 3 |
def timestamp # on Task prerequisite_tasks.collect { |pre| pre.timestamp }.max || Time.now end |
:isolate doesn’t have any prerequisites, so it falls back to Time.now. This is wrong in my case, as it forces my parser files to regenerate every time.
What I need is a prerequisite that fixes this with a timestamp earlier than my files:
1 2 3 4 5 |
def (task(:phony)).timestamp # omg I love/hate this grammar construct Time.at 0 end task :isolate => :phony |
and everything is happy.
I’m going to officially ask that :phony gets added to rake so others can be spared this pain.