如何在执行所有其他任务后运行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