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

Cha*_*ler 18 ruby rake

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

有没有一种简单的方法来实现这一目标?

谢谢


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

task :test1 do 
  puts 'test1'
end

task :test2 do 
  puts 'test2'
end

Rake::Task.tasks.each do |t|
    <Insert rake magic here>
#  t.enhance do 
#    puts 'after'
#  end
end

$ rake test1
test1
after

$rake test2
test2
after

$rake test1 test2  
test1
test2
after
Run Code Online (Sandbox Code Playgroud)

而如果

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

    $rake test3
test1
test2
test3
after
Run Code Online (Sandbox Code Playgroud)

即使赏金消失了,任何进一步的帮助都非常赞赏.(可悲的是,我不认为我可以提供另一笔赏金.)

Pat*_*hie 37

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

Rake::Task["my_task"].enhance do
  Rake::Task["my_after_task"].invoke
end
Run Code Online (Sandbox Code Playgroud)

这将导致在'my_task'之后调用'my_after_task'.

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

Rake::Task.tasks.each do |t| 
  t.enhance do 
    Rake::Task["my_after_task"].invoke
  end
end
Run Code Online (Sandbox Code Playgroud)

完整的测试文件:

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
Run Code Online (Sandbox Code Playgroud)

并输出:

$ rake test1
test1
after

$ rake test2
test2
after
Run Code Online (Sandbox Code Playgroud)


Pat*_*hie 11

将此作为新答案发布,以保持另一个可用.这不太优雅,因为我必须进入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)
Run Code Online (Sandbox Code Playgroud)

输出:

$ rake test1
test1
after

$ rake test1 test2
test1
test2
after
Run Code Online (Sandbox Code Playgroud)

  • 您根本不需要使用instance_variable_set - ``Rake.application.top_level_tasks <<:after```将正常工作. (3认同)
  • 当然.顺便说一句,我正在参加一个会议并追踪Jim Weirich(耙子的作者),看看这是解决这个问题的最好办法.他的回答是,Rake没有内置的方法来做这件事,但是如果有人能想出一个通用的方法,那么他就可以接受补丁了.所以代码:Rake应用程序有一个读者来跟踪要运行的名为'top_level_tasks'的任务.因为它是只读的,我们需要读出它,更新它然后使用instance_variable_set将更改推回到应用程序中.如果它被读取,我们可以在一行中完成所有操作. (2认同)

Nat*_*ate 10

在这里找到了这个使用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? }
Run Code Online (Sandbox Code Playgroud)

贝壳

$ rake a b
a
b
cleanup
$ rake -T
rake a # Lovely task a
rake b # Lovely task b
cleanup
Run Code Online (Sandbox Code Playgroud)

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

at_exit do
  puts "cleanup"
end
Run Code Online (Sandbox Code Playgroud)

或者让它运行一个方法

def on_exit_do_cleanup
  puts "cleanup"
end

at_exit { on_exit_do_cleanup }
Run Code Online (Sandbox Code Playgroud)

并且您可能希望确保只有在任务实际运行时才进行清理,以便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 }
Run Code Online (Sandbox Code Playgroud)


awe*_*ndt 5

除了丑陋之外Rake.application.instance_variable_set,您还可以在命令行上增强最后一个任务,如下所示:

  last_task = Rake.application.top_level_tasks.last
  Rake::Task[last_task].enhance do
    puts 'after'
  end
Run Code Online (Sandbox Code Playgroud)

这应该正是您需要做的!