Comment revenir tôt d'une tâche de râteau?

226

J'ai une tâche de râteau où je fais quelques vérifications au début, si l'une des vérifications échoue, je voudrais revenir tôt de la tâche de râteau, je ne veux pas exécuter le code restant.

Je pensais que la solution serait de placer un retour là où je voulais revenir du code mais j'obtiens l'erreur suivante

unexpected return
Janak
la source

Réponses:

285

Une tâche Rake est essentiellement un bloc. Un bloc, à l'exception de lambdas, ne prend pas en charge le retour, mais vous pouvez passer à l'instruction suivante en utilisant nextce qui dans une tâche de râteau a le même effet que d'utiliser le retour dans une méthode.

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

Ou vous pouvez déplacer le code dans une méthode et utiliser return dans la méthode.

task :foo do
  do_something
end

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

Je préfère le deuxième choix.

Simone Carletti
la source
18
J'aime aussi le deuxième. Plus j'utilise rake, plus j'aime garder le code non trivial en dehors de la définition de la tâche. Ce n'est pas une règle 100% ferme, mais cela semble être une bonne ligne directrice à suivre.
Mike Woodhouse
6
J'ai essayé avec breaket j'ai cette erreur: rake avorté! pause de proc-fermeture (Voir la trace complète en exécutant la tâche avec --trace)
pupeno
4
Je préfère utiliser ensuite. Pourquoi devrions-nous déclarer une nouvelle méthode juste pour prendre en charge les retours anticipés?
Derek Greer
5
Que faites-vous si vous êtes profondément imbriqué dans plusieurs blocs? ( nextne fonctionne que s'il y a un "niveau" de bloc pour sortir.
mjs
3
Avertissement: déclarer des méthodes dans les tâches Rake est une mauvaise idée car elles sont globales pour toutes les tâches Rake chargées, sans rapport avec l'espace de noms. Next est utilisé au lieu de break car le code du bloc peut être appelé plusieurs fois par ce qui exécute le bloc (pensez à la méthode .each).
Leslie Viljoen
181

Vous pouvez utiliser abort(message)de l'intérieur de la tâche pour abandonner cette tâche avec un message.

Sergikon
la source
5
@TylerRick Non, c'est l'abandon du noyau # .
Jo Liss
10
Cette méthode est supérieure pour quitter en cas de non-réussite car elle définit automatiquement l'état de sortie.
samuil
Ceci est un gagnant. Également un moyen simple de fournir des commentaires sur l'utilisation des erreurs d'argument
David Hempy
Inline et beaucoup plus explicatif que next. Aimer.
SomeSchmo
22

J'ai tendance à utiliser abortce qui est une meilleure alternative dans de telles situations, par exemple:

task :foo do
  something = false
  abort 'Failed to proceed' unless something
end
khelll
la source
1
Mais comment faire abortsans sortir avec un 1code de sortie? Les tâches de râteau sont souvent utilisées dans la ligne de commande pour déterminer le succès ou l'échec. Y a-t-il un "succès" abort?
Joshua Pinter
2
J'ai répondu à mes propres questions: l'apparence exitest un bon moyen de quitter avec succès.
Joshua Pinter
19

Retour avec une erreur ❌

Si vous revenez avec une erreur (c'est-à-dire un code de sortie de 1) que vous voudrez utiliser abort, qui prend également un paramètre de chaîne facultatif qui sera sorti à la sortie:

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

Sur la ligne de commande:

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

Retour avec succès ✅

Si vous revenez sans erreur (c'est-à-dire un code de sortie de 0) que vous voudrez utiliser exit, qui ne prend pas de paramètre de chaîne.

task :check do

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

end

Sur la ligne de commande:

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

Ceci est important si vous l'utilisez dans un travail cron ou quelque chose qui doit faire quelque chose par la suite selon que la tâche de râteau a réussi ou non.

Joshua Pinter
la source
8

Si vous vouliez quitter une tâche de râteau sans provoquer le "râteau abandonné!" message à imprimer, vous pouvez alors utiliser soit "abandonner", soit "quitter". Mais "abandonner", lorsqu'il est utilisé dans un bloc de secours, met fin à la tâche et affiche toute l'erreur (même sans utiliser --trace). Donc, "quitter" est ce que j'utilise.

ZX12R
la source
3
En général, je pense que l'utilisation de "exit" au lieu de return / break est une mauvaise idée car elle ne se contente pas de sauter du proc / method / etc actuel . - il quitte l'intégralité du processus et ignore tout code que la méthode de l'appelant aurait pu être exécuté par la suite (y compris éventuellement un nettoyage). Mais pour une tâche de râteau, je suppose que ce n'est probablement pas un problème ...
Tyler Rick
0

J'ai utilisé l' nextapproche suggérée par Simone Carletti, car lors du test de la tâche de râteau abort, qui n'est en fait qu'un wrapper exit, ce n'est pas le comportement souhaité.

Exemple:

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