如何在执行所有其他任务后运行Rake任务? (即Rake AfterBuild任务)

我是Rake的新手并使用它来构建.net项目。 我感兴趣的是有一个Summary任务,打印出已完成内容的摘要。 无论rake调用了什么任务,我都希望始终调用此任务。

有一个简单的方法来实现这一目标吗?

谢谢


关于这个问题的更新,回应Patrick的回答我想要的是在所有其他任务之后运行一次的后续任务,所以我想要的输出是:

task :test1 do puts 'test1' end task :test2 do puts 'test2' end Rake::Task.tasks.each do |t|  # t.enhance do # puts 'after' # end end $ rake test1 test1 after $rake test2 test2 after $rake test1 test2 test1 test2 after 

而如果

 task :test3 =>[:test1, :test2] puts 'test3' end $rake test3 test1 test2 test3 after 

尽管赏金已经消失,但任何进一步的帮助都非常值得赞赏。 (可悲的是,我不认为我可以提供另一笔赏金。)

将此作为新答案发布,以保持另一个可用。 这不太优雅,因为我必须进入Rake的内核并手动更新任务列表,但它的工作原理。

 task :test1 do puts 'test1' end task :test2 do puts 'test2' end task :after do puts 'after' end # top_level_tasks is't writable so we need to do this ugly # instance_variable_set hack... current_tasks = Rake.application.top_level_tasks current_tasks << :after Rake.application.instance_variable_set(:@top_level_tasks, current_tasks) 

输出:

 $ rake test1 test1 after $ rake test1 test2 test1 test2 after 

你应该可以用’增强’来做到这一点:

 Rake::Task["my_task"].enhance do Rake::Task["my_after_task"].invoke end 

这将导致在’my_task’之后调用’my_after_task’。

如果要将其应用于所有任务,只需遍历所有任务并为每个任务调用增强function:

 Rake::Task.tasks.each do |t| t.enhance do Rake::Task["my_after_task"].invoke end end 

完整的测试文件:

 task :test1 do puts 'test1' end task :test2 do puts 'test2' end Rake::Task.tasks.each do |t| t.enhance do puts 'after' end end 

并输出:

 $ rake test1 test1 after $ rake test2 test2 after 

在这里找到了这个简单优雅的答案,它使用了Ruby方法at_exit

值得注意的是, at_exit之后定义的方法将在每次调用rake脚本时运行,无论任务运行如何,或者是否运行任何任务。 这包括运行rake -T (列出可用任务)。 确保at_exit仅在前一个任务告知它时才执行任何操作。

rakefile.rb

 desc "Lovely task a" task :a do puts "a" end desc "Lovely task b" task :b do puts "b" end task :cleanup do puts "cleanup" end at_exit { Rake::Task[:cleanup].invoke if $!.nil? } 

贝壳

 $ rake ab a b cleanup $ rake -T rake a # Lovely task a rake b # Lovely task b cleanup 

如果您不想,也不需要让它运行任务。

 at_exit do puts "cleanup" end 

或者让它运行一个方法

 def on_exit_do_cleanup puts "cleanup" end at_exit { on_exit_do_cleanup } 

并且您可能希望确保只有在任务实际运行时才进行清理,以便rake -T也不会进行清理。

rakefile.rb

 do_cleanup = false desc "Lovely task a" task :a do puts "a" do_cleanup = true end desc "Lovely task b" task :b do puts "b" do_cleanup = true end task :cleanup do return unless $!.nil? # No cleanup on error return unless do_cleanup # No cleanup if flag is false puts "cleanup" end at_exit { Rake::Task[:cleanup].invoke } 

除了丑陋的Rake.application.instance_variable_set ,您可以像这样增强命令行上的最后一个任务:

  last_task = Rake.application.top_level_tasks.last Rake::Task[last_task].enhance do puts 'after' end 

这应该完全符合你的需要!

您可以使用Kernel.trap调用并附加到“Exit”信号。 它将在正常和exception退出时触发。

把它放在你的rakefile中:

 Kernel.trap("EXIT") do Rake::Task[:final].invoke end 

现在,只要你完成“最终”任务,它就会在程序的最后执行。 无论。

 task :final do puts "Hit return to continue..." STDIN.getc end 

我不知道这是不是最好的方式,但它更简单:

完成所有“公共任务”,称为实际任务的摘要。

 task :compile => :realcompile do summary stuff end 

如果有人来到这里寻找如何所有其他任务之前运行任务(例如,一个特殊的环境加载任务),你仍然可以使用相同的增强方法,除了第一个争论:

 task :environment do env = (ENV['RACK_ENV'] || 'production').downcase # do things before other tasks end # run environment task before all tasks for setup Rake::Task.tasks.each do |t| next if t.name == 'environment' t.enhance [:environment] end