How do I return early from a rake task?

冷暖自知 提交于 2019-12-17 17:28:40

问题


I have a rake task where I do some checks at the beginning, if one of the checks fails I would like to return early from the rake task, I don't want to execute any of the remaining code.

I thought the solution would be to place a return where I wanted to return from the code but I get the following error

unexpected return

回答1:


A Rake task is basically a block. A block, except lambdas, doesn't support return but you can skip to the next statement using next which in a rake task has the same effect of using return in a method.

task :foo do
  puts "printed"
  next
  puts "never printed"
end

Or you can move the code in a method and use return in the method.

task :foo do
  do_something
end

def do_something
  puts "startd"
  return
  puts "end"
end

I prefer the second choice.




回答2:


You can use abort(message) from inside the task to abort that task with a message.




回答3:


I tend to use abort which is a better alternative in such situations, for example:

task :foo do
  something = false
  abort 'Failed to proceed' unless something
end



回答4:


Return with an Error ❌

If you're returning with an error (i.e. an exit code of 1) you'll want to use abort, which also takes an optional string param that will get outputted on exit:

task :check do
  errors = get_errors

  abort( "There are #{errors.count} errors!" ) if errors.any?

  # Do remaining checks...
end

On the command line:

$ rake check && echo "All good"
#=> There are 2 errors!

Return with Success ✅

If you're returning without an error (i.e. an exit code of 0) you'll want to use exit, which does not take a string param.

task :check do
  errors = get_errors

  exit if errors.empty?

  # Process errors...
end

On the command line:

$ rake check && echo "All good"
#=> All good

This is important if you're using this in a cron job or something that needs to do something afterwards based on whether the rake task was successful or not.




回答5:


If you need to break out of multiple block levels, you can use fail.

For example

task :something do
  [1,2,3].each do |i|
    ...
    fail "some error" if ...
  end
end

(See https://stackoverflow.com/a/3753955/11543.)




回答6:


If you meant exiting from a rake task without causing the "rake aborted!" message to be printed, then you can use either "abort" or "exit". But "abort", when used in a rescue block, terminates the task as well as prints the whole error (even without using --trace). So "exit" is what I use.




回答7:


I used next approach suggested by Simone Carletti, since when testing rake task, abort, which in fact is just a wrapper for exit, is not the desired behavior.

Example:

task auto_invoice: :environment do
  if Application.feature_disabled?(:auto_invoice)
    $stderr.puts 'Feature is disabled, aborting.'
  next
end


来源:https://stackoverflow.com/questions/2316475/how-do-i-return-early-from-a-rake-task

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!