レーキタスクから早期に戻るにはどうすればよいですか?


226

最初にいくつかのチェックを行うrakeタスクがあります。チェックの1つが失敗した場合、rakeタスクから早く戻りたいので、残りのコードを実行したくありません。

解決策は、コードから戻りたい場所にリターンを配置することだと思いましたが、次のエラーが発生します

unexpected return

回答:


285

Rakeタスクは基本的にブロックです。ラムダを除くブロックはreturnをサポートしていませんがnext、rakeタスクで使用する次のステートメントにスキップして、メソッドでreturnを使用するのと同じ効果があります。

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

または、メソッド内でコードを移動し、メソッドでreturnを使用できます。

task :foo do
  do_something
end

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

私は2番目の選択を好みます。


18
私も2番目が一番好きです。rakeを使うほど、重要なコードをタスク定義の外に置いておくことができます。100%しっかりしたルールではありませんが、取り組むべき良いガイドラインのようです。
マイクウッドハウス

6
私は試してbreakみましたが、このエラーが発生しました:レーキが中止されました!proc-closureからの中断(--traceを使用してタスクを実行して完全なトレースを表示)
pupeno '19年

4
私は次を使用することを好みます。早期リターンをサポートするためだけに新しいメソッドを宣言する必要があるのはなぜですか?
Derek Greer

5
複数のブロック内に深くネストされている場合はどうしますか?(nextから抜け出すためにブロックの「レベル」にあります場合にのみ機能します。
MJS

3
警告:Rakeタスクでメソッドを宣言することは、名前空間に関係なく、ロードされたすべてのRakeタスクに対してグローバルであるため、悪い考えです。ブロック内のコードは、ブロックを実行しているもの(.eachメソッドを考える)によって複数回呼び出される可能性があるため、breakの代わりにNextが使用されます。
Leslie Viljoen

181

abort(message)タスク内から使用して、メッセージでそのタスクを中止できます。


5
@TylerRickいいえ、それはKernel#abortです。
Jo Liss

10
この方法は、自動的に終了ステータスを設定するため、失敗した状況で終了する場合に優れています。
samuil 2014年

これは勝者です。また、引数エラーの使用フィードバックを提供する簡単な方法です。
David Hempy

インラインよりもはるかに説明next。大好きです。
SomeSchmo、

22

私はabortそのような状況でより良い代替手段である例えばを使用する傾向があります:

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

1
しかしabort1終了コードで終了せずにどうすればよいですか?多くの場合、Rakeタスクはコマンドラインで使用され、成功または失敗を判断します。「成功」はありabortますか?
ジョシュア・ピンター

2
私自身の質問に答えました:はexit正常に終了するための良い方法のように見えます
ジョシュアピンター

19

エラーで戻る❌

あなたが戻っている場合エラー(すなわちの終了コード1)あなたが使用したいと思うabortも、終了時に出力されますオプションの文字列のparamを取り、:

task :check do

  # If any of your checks fail, you can exit early like this.
  abort( "One of the checks has failed!" ) if check_failed?

end

コマンドラインで:

$ rake check && echo "All good"
#=> One of the checks has failed!

成功して戻る✅

あなたが戻っている場合はなし(すなわちの終了コードエラー0)あなたが使用したいと思うexitどの、しない文字列のparamを取ります。

task :check do

  # If any of your checks fail, you can exit early like this.
  exit if check_failed?

end

コマンドラインで:

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

これをcronジョブで使用する場合や、rakeタスクが成功したかどうかに基づいて後で何かを実行する必要がある場合に重要です。



8

「レーキを中止しました!」を引き起こさずにレーキタスクを終了するつもりなら メッセージを出力する場合は、「中止」または「終了」を使用できます。ただし、「abort」をレスキューブロックで使用すると、タスクが終了し、エラー全体が出力されます(--traceを使用しなくても)。つまり、「exit」が私が使用するものです。


3
一般に、現在の proc / method / etc からジャンプするだけではないため、return / breakの代わりに「exit」を使用することは悪い考えだと思います。-プロセス全体を終了し、呼び出し側メソッドが後で実行することを意図していた可能性のあるコードをスキップします(クリーンアップを含む可能性があります)。しかし、レーキタスクの場合、それはおそらく問題ではないと思います...
タイラーリック

0

nextレーキタスクをテストするときabort、実際にはのラッパーにすぎexitないは望ましい動作ではないため、私はSimone Carlettiが提案したアプローチを使用しました。

例:

task auto_invoice: :environment do
  if Application.feature_disabled?(:auto_invoice)
    $stderr.puts 'Feature is disabled, aborting.'
  next
end
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.