Maneira recomendada de interromper uma compilação Gradle

162

Como posso parar uma compilação Gradle depois de detectar um problema? Posso usar uma declaração, lançar uma exceção, fazer um System.exit (má ideia) ou usar uma função dedicada no Gradle (mas não consegui encontrar uma). Qual é a melhor maneira para Gradle (e por quê?).

Kartoch
fonte

Respostas:

117

Eu costumo lançar a exceção relevante do org.gradle.apipacote , por exemplo, InvalidUserDataExceptionquando alguém digitou algo inválido ou GradleScriptExceptionpor erros mais gerais.

Se você deseja interromper a tarefa ou ação atual e passar para a próxima, também pode lançar um StopActionException

tim_yates
fonte
5
Você também pode usar TaskExecutionException se uma tarefa não for executada com êxito. (Isto é verdadeiro de acordo com as Gradle 1,11 docs, eu não tenho certeza de quando foi introduzido.)
Josh Gagnon
existem opções de sintaxe legais aqui? Considere a sintaxe das pré-condições de kotlin: require(something != whatever) { "No good!" }ao contrário das mais detalhadas e do tipo ee #if(something != whatever){ throw new GradleException("No good!") }
Groostav
O pior GradleScriptExceptioné que ele requer um segundo parâmetro para uma causa.
Trejkaz 25/05
... É claro que estamos evitando dizer que isso é " programação por exceções " ?! Eu tenho um código legado escrito dessa maneira e é um horror manter ... Nos dias de hoje, a filosofia em torno makeé que rules(tarefas) foram bem-sucedidas ou falharam. Uma vez tentei return false- Gradle simplesmente ignorou e continuou a correr.
será
87

Se você deseja interromper a construção, lance:

throw new GradleException('error occurred')

ou jogue as subclasses para a exceção acima. Algumas das exceções da subclasse, na verdade, apenas falham na tarefa atual, mas continuam com a construção.

skipy
fonte
28

Atualmente, não existe um método dedicado, embora tenha havido discussões para adicionar um.

A maneira recomendada de interromper uma compilação Gradle é lançar uma exceção. Como o Groovy não tem exceções verificadas e o Gradle, por padrão, não imprime o tipo de exceção, não é tão crítico qual exceção é lançada. Nos scripts de construção, o GradleException é frequentemente usado, mas uma asserção Groovy também parece razoável (dependendo das circunstâncias e do público). O importante é fornecer uma mensagem clara. Adicionar uma causa (se disponível) ajuda na depuração ( --stacktrace).

Gradle fornece tipos de exceção dedicados StopExecutionException/ StopActionExceptionpara interromper a tarefa / ação atual, mas continuando a construção.

Peter Niederwieser
fonte
19

Outra opção, se você não deseja capturar a exceção mais tarde, é chamar a tarefa Ant Fail. É um pouco mais fácil de ler na minha opinião e você pode dar uma boa mensagem ao usuário sem usar o --stacktrace.

task (tarball, dependsOn: warAdmin) << {
    ant.fail('The sky is falling!!')
}

Dá uma mensagem como:

* What went wrong:
Execution failed for task ':tarball'.
> The sky is falling!!

Provavelmente você pode entender isso (talvez ele ative o BuildException da formiga?), Mas se esse for um objetivo, eu não usaria o ant.fail. Eu facilitaria a visualização de qual exceção capturar, lançando a exceção gradle padrão, como tim_yates sugeriu.

Gus
fonte
Como faço para configurá-lo? Chame-o?
powder366
1
apenas chamar ant.fail ( 'mensagem de sua escolha') sem configuração necessária
Gus
2
Parece que a saída deste é idêntica a usar throw new GradleException("The sky is falling!!")(Gradle 3.4.1)
mgaert
@mgaert Parece que me lembro que há 4 anos, quando escrevi isso, a mensagem impressa diferia (mas isso faz muito tempo e não sinto vontade de descobrir qual versão estava atual naquele momento e verificá-la). Além disso, o IMHO ant.fail comunica mais claramente a intenção de interromper completamente a compilação, enquanto a exceção lançada é lida como algo que pode ser capturado e manipulado.
Gus
12

Lançar uma GradleException simples funciona para interromper o script de construção. Isso funciona muito bem para verificar a configuração do ambiente necessária.

GradleException('your message, why the script is stopped.')

Exemplo:

if(null == System.getenv()['GRADLE_USER_HOME']) {
    throw new GradleException('Required GRADLE_USER_HOME environment variable not set.')
}
edvox1138
fonte
5

Aqui está um fragmento de código que tenta emular como a tarefa Gradle javac gera erros:

task myCommand(type:Exec) {

    ... normal task setup ....

    ignoreExitValue true
    standardOutput = new ByteArrayOutputStream()
    ext.output = { standardOutput.toString() }
    doLast {
        if (execResult.exitValue) {
            logger.error(output())
            throw new TaskExecutionException( it,
                new Exception( "Command '${commandLine.join(' ')}' failed; "
                              + "see task output for details." )
            )
        }
    }
}

Quando o comando retorna, 0não há saída. Qualquer outro valor imprimirá o standardOutput e interromperá a compilação.

NOTA: Se o seu comando também gravar no errorOutput, talvez seja necessário incluí-lo no log de erros.

cmcginty
fonte