[Rake-devel] A handful of issues
James M. Lawrence
quixoticsycophant at gmail.com
Mon Jun 7 03:03:29 EDT 2010
==== 1 - Task#needed? applies to immediate prereqs only
file "a" => "b" do
touch "a"
end
file "b" => "c" do
touch "b"
end
file "c" do
touch "c"
end
task :default do
touch ["a", "b"]
sleep 1
touch "c"
p Rake::Task["a"].needed? # => false
# ... but "a" is needed because "c" is newer
end
==== 2 - Task#needed? can be wrong even for immediate prereqs
file "a" => "b" do
touch "a"
end
file "b" do
touch "b"
end
task :default do
touch "a"
rm_f "b"
p Rake::Task["a"].needed? # => false
# ... but "a" is needed because "b" will be newly created
end
==== 3 - Filesystem timestamp granularity
memo = []
file "a" => "b" do
memo << "a"
touch "a"
end
file "b" do
memo << "b"
touch "b"
end
task :default do
touch "a"
rm_f "b"
Rake::Task["a"].invoke
p memo # => ["b"]
# ... but should be ["b", "a"] since "b" is newer
end
==== 4 - Dependency relation should be transitive
memo = []
file "a" => "b" do
memo << "a"
touch "a"
end
file "b" => "c" do
memo << "b"
# does not create b
end
file "c" do
memo << "c"
touch "c"
end
task :default do
touch ["a", "b"]
rm_f "c"
sleep 1 # filesystem timestamp workaround
Rake::Task["a"].invoke
p memo # => ["c", "b"]
# ... but "a" is needed since it (transitively) depends on "c"
end
==== 5 - Trace output is misleading
file "a" => "b" do
touch "a"
end
file "b" => "c" do
touch "b"
end
file "c" do
touch "c"
end
task :default do
touch ["a", "b"]
sleep 1
touch "c"
Rake.application.options.trace = true
Rake::Task["a"].invoke
# =>
# touch a b
# touch c
# ** Invoke a (first_time, not_needed) <--- Liar! It is needed.
# ** Invoke b (first_time)
# ** Invoke c (first_time, not_needed)
# ** Execute b
# touch b
# ** Execute a <--- See?
# touch a
end
**** Discussion
==== 1 - Task#needed? applies to immediate prereqs only
Having Task#needed? recursively check all prereqs is needlessly slow,
so the current behavior is fine. However I think its use should be
deprecated in the published API. We could alias it to
Task#locally_needed? and additionally write Task#globally_needed?.
==== 2 - Task#needed? can be wrong even for immediate prereqs
Should be fixed if Task#needed? (or Task#locally_needed?) is
"officially" supported.
http://github.com/quix/rake/commits/mainline-file-task-needed
==== 3 - Filesystem timestamp granularity
Unless you have ext4fs, your filesystem most likely records timestamps
only to the nearest second, making it easy to create same-time files.
The fix is easy: change timestamp comparison from > to >=. It's a
pessimization: "When in doubt, rerun." It sounds safer, but what
consequences lurk?
http://github.com/quix/rake/commits/mainline-timestamp-granularity
==== 4 - Dependency relation should be transitive
Let ~> denote "eventually depends on". If a~>b and b~>c, then we want
a~>c. Thus if c executes then a should execute, as is implied by the
dependency graph. Parallel Rake has to assume transitivity, so its
behavior is different.
I think a file task which executes but does not update the file is
reneging. Regarding this as an error would make regular Rake
consistent with parallel Rake, sidestepping the transitivity issue.
==== 5 - Trace output is misleading
This is related to item 1 since "not_needed" reflects Task#needed?.
Perhaps change the output to "not_immediately_needed" or some such?
More information about the Rake-devel
mailing list