==== 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? _______________________________________________ Rake-devel mailing list [email protected] http://rubyforge.org/mailman/listinfo/rake-devel
