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

时间:2022-08-25 16:30:36

I'm new to Rake and using it to build .net projects. What I'm interested in is having a Summary task that prints out a summary of what has been done. I want this task to always be called, no matter what tasks rake was invoked with.

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

Is there an easy way to accomplish this?

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

Thanks

谢谢


Update on the question, responding to Patrick's answer what I want is the after task to run once after all other tasks, so the output I want is:

关于这个问题的更新,回应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

and if

而如果

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

    $rake test3
test1
test2
test3
after

Even though the bounty is gone, any further help much appreciated. (Sadily I don't think that I can offer another bounty.)

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

7 个解决方案

#1


10  

Posting this as a new answer to keep the other one available. This is much less elegant as I have to get into the guts of Rake and manually update the task list, but it works.

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

Outputs:

输出:

$ rake test1
test1
after

$ rake test1 test2
test1
test2
after

#2


36  

You should be able to do this with 'enhance':

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

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

This will cause 'my_after_task' to be invoked after 'my_task'.

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

If you want to apply this to all tasks, just loop over all the tasks and call enhance for each:

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

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

Full test file:

完整的测试文件:

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

And the output:

并输出:

$ rake test1
test1
after

$ rake test2
test2
after

#3


10  

Found this simple elegant answer here that uses the Ruby method at_exit.

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

It's worth noting that the method defined after at_exit will run every time the rake script is invoked regardless of the task run, or if any task is run. This includes when running rake -T (to list available tasks). Make sure that at_exit only does anything if a previous task told it to do so.

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

rakefile.rb

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? }

shell

贝壳

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

You also don't need to make it run a task if you don't want to.

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

at_exit do
  puts "cleanup"
end

Or make it run an method

或者让它运行一个方法

def on_exit_do_cleanup
  puts "cleanup"
end

at_exit { on_exit_do_cleanup }

And you may want to make sure you only do the cleanup if a task actually ran so that rake -T won't also do a cleanup.

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

rakefile.rb

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 }

#4


4  

Apart from the ugly Rake.application.instance_variable_set, you can enhance the last task on the command-line like so:

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

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

That should do exactly what you need to do!

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

#5


4  

You could use the Kernel.trap call and attach to the "Exit" signal. It will fire upon both normal and abnormal exit.

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

Put this early in your rakefile:

把它放在你的rakefile中:

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

Now any time you make a "final" task it will be executed at the very end of the program. no matter what.

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

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

#6


1  

I don't know if it's the best way but it's the simpler:

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

Make all your "public tasks" Summary ones that call real tasks.

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

task :compile => :realcompile do
   summary stuff
end

#7


0  

If anyone came here looking for how to run a task before all other tasks (eg, a special env loading task), you can still use the same enhance method, except only the first arguement:

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

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

#1


10  

Posting this as a new answer to keep the other one available. This is much less elegant as I have to get into the guts of Rake and manually update the task list, but it works.

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

Outputs:

输出:

$ rake test1
test1
after

$ rake test1 test2
test1
test2
after

#2


36  

You should be able to do this with 'enhance':

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

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

This will cause 'my_after_task' to be invoked after 'my_task'.

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

If you want to apply this to all tasks, just loop over all the tasks and call enhance for each:

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

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

Full test file:

完整的测试文件:

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

And the output:

并输出:

$ rake test1
test1
after

$ rake test2
test2
after

#3


10  

Found this simple elegant answer here that uses the Ruby method at_exit.

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

It's worth noting that the method defined after at_exit will run every time the rake script is invoked regardless of the task run, or if any task is run. This includes when running rake -T (to list available tasks). Make sure that at_exit only does anything if a previous task told it to do so.

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

rakefile.rb

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? }

shell

贝壳

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

You also don't need to make it run a task if you don't want to.

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

at_exit do
  puts "cleanup"
end

Or make it run an method

或者让它运行一个方法

def on_exit_do_cleanup
  puts "cleanup"
end

at_exit { on_exit_do_cleanup }

And you may want to make sure you only do the cleanup if a task actually ran so that rake -T won't also do a cleanup.

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

rakefile.rb

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 }

#4


4  

Apart from the ugly Rake.application.instance_variable_set, you can enhance the last task on the command-line like so:

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

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

That should do exactly what you need to do!

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

#5


4  

You could use the Kernel.trap call and attach to the "Exit" signal. It will fire upon both normal and abnormal exit.

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

Put this early in your rakefile:

把它放在你的rakefile中:

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

Now any time you make a "final" task it will be executed at the very end of the program. no matter what.

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

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

#6


1  

I don't know if it's the best way but it's the simpler:

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

Make all your "public tasks" Summary ones that call real tasks.

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

task :compile => :realcompile do
   summary stuff
end

#7


0  

If anyone came here looking for how to run a task before all other tasks (eg, a special env loading task), you can still use the same enhance method, except only the first arguement:

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

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