Como volto cedo de uma tarefa de rake?

226

Eu tenho uma tarefa de rake em que faço algumas verificações no início. Se uma das verificações falhar, gostaria de retornar mais cedo da tarefa de rake, não quero executar nenhum código restante.

Eu pensei que a solução seria colocar um retorno onde eu queria retornar do código, mas eu recebo o seguinte erro

unexpected return
Janak
fonte

Respostas:

285

Uma tarefa Rake é basicamente um bloco. Um bloco, exceto lambdas, não suporta retorno, mas você pode pular para a próxima instrução usando a nextqual em uma tarefa rake tem o mesmo efeito de usar retorno em um método.

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

Ou você pode mover o código em um método e usar return no método

task :foo do
  do_something
end

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

Eu prefiro a segunda escolha.

Simone Carletti
fonte
18
Eu também gosto do segundo. Quanto mais eu uso o rake, mais eu gosto de manter o código não trivial fora da definição da tarefa. Não é uma regra 100% firme, mas parece ser uma boa orientação para se trabalhar.
Mike Woodhouse
6
Eu tentei com breake tenho este erro: rake abortado! romper com proc-fechamento (Veja traço cheio executando tarefa com --trace)
pupeno
4
Eu prefiro usar o próximo. Por que devemos declarar um novo método apenas para apoiar retornos antecipados?
Derek Greer
5
O que você faz se estiver profundamente aninhado em vários blocos? ( nextsó funciona se houver um "nível" de bloco para romper.
mjs 30/01
3
Aviso: declarar métodos nas tarefas Rake é uma péssima idéia, porque eles são globais para todas as tarefas Rake carregadas, irrelevantes para o espaço para nome. Próximo é usado em vez de quebra, porque o código no bloco pode ser chamado várias vezes pelo que estiver executando o bloco (pense no método .each).
Leslie Viljoen
181

Você pode usar abort(message)de dentro da tarefa para interromper a tarefa com uma mensagem.

Sergikon
fonte
5
@TylerRick Não, é o Kernel # abort .
Jo Liss
10
Dessa maneira, é superior para sair em situações sem êxito, pois define automaticamente o status de saída.
Samuil 28/05
Este é um vencedor. Também é uma maneira fácil de fornecer feedback de uso para erros de argumento.
David Hempy
Inline e muito mais explicativo do que next. Adoro.
SomeSchmo
22

Costumo usar abortqual é a melhor alternativa em tais situações, por exemplo:

task :foo do
  something = false
  abort 'Failed to proceed' unless something
end
khelll
fonte
1
Mas como você abortsem sair com um 1código de saída? As tarefas de rake são frequentemente usadas na linha de comando para determinar o sucesso ou o fracasso. Existe um "sucesso" abort?
Joshua Pinter
2
Respondi minhas próprias perguntas: parece que exité uma boa maneira de sair com sucesso.
Joshua Pinter
19

Retornar com um erro ❌

Se você estiver retornando com um erro (ou seja, um código de saída de 1), você desejará usar abort, o que também exige um parâmetro de string opcional que será gerado na saída:

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

Na linha de comando:

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

Retorne com sucesso ✅

Se você estiver retornando sem um erro (ou seja, um código de saída de 0), você desejará usar exit, o que não exige um parâmetro de string.

task :check do

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

end

Na linha de comando:

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

Isso é importante se você estiver usando isso em um trabalho cron ou algo que precise fazer algo posteriormente com base em se a tarefa rake foi bem-sucedida ou não.

Joshua Pinter
fonte
8

Se você pretendia sair de uma tarefa de rake sem causar o "rake abortado!" mensagem a ser impressa, você pode usar "abortar" ou "sair". Mas "abortar", quando usado em um bloco de recuperação, finaliza a tarefa e imprime todo o erro (mesmo sem usar --trace). Então "exit" é o que eu uso.

ZX12R
fonte
3
Em geral, acho que usar "exit" em vez de return / break é uma péssima idéia, uma vez que não sai do proc / method / etc atual . - sai de todo o processo e ignora qualquer código que o método de chamada possa ter a intenção de ser executado posteriormente (incluindo possivelmente alguma limpeza). Mas para uma tarefa rake Eu acho que provavelmente não é um problema ...
Tyler Rick
0

eu usei next abordagem sugerida por Simone Carletti, já que o teste da tarefa de rake abort, que na verdade é apenas um invólucro exit, não é o comportamento desejado.

Exemplo:

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