Forma recomendada de detener una compilación de Gradle

162

¿Cómo puedo detener una compilación de Gradle después de detectar un problema? Puedo usar una afirmación, lanzar una excepción, hacer un System.exit (mala idea) o usar una función dedicada en Gradle (pero no pude encontrar una). ¿Cuál es la mejor manera para Gradle (y por qué?).

Kartoch
fuente

Respuestas:

117

Por lo general, lanzo la excepción relevante del org.gradle.apipaquete , por ejemplo, InvalidUserDataExceptioncuando alguien ha ingresado algo no válido o GradleScriptExceptionpor errores más generales.

Si desea detener la tarea o acción actual y pasar a la siguiente, también puede lanzar un StopActionException

tim_yates
fuente
55
También puede usar TaskExecutionException si una tarea no se ejecuta correctamente. (Esto es cierto de acuerdo con los documentos de Gradle 1.11, no estoy seguro de cuándo fue presentado).
Josh Gagnon
¿hay alguna buena opción de sintaxis aquí? Considere la sintaxis de las condiciones previas de kotlin: a require(something != whatever) { "No good!" }diferencia de las más detalladas y tipo-eeif(something != whatever){ throw new GradleException("No good!") }
Groostav
Lo horrible GradleScriptExceptiones que requiere un segundo parámetro para una causa.
Trejkaz
... ¡Por supuesto que estamos evitando decir que esto es " programación por excepciones "? Tengo el legado codificado escrito de esa manera y es un horror mantenerlo ... En los viejos tiempos la filosofía makees que rules(las tareas) tuvieron éxito o fracasaron. Una vez lo intenté return false: Gradle simplemente lo ignoró y continuó corriendo.
será el
87

Si quieres detener la construcción, lanza:

throw new GradleException('error occurred')

o arroje las subclases para la excepción anterior. Algunas de las excepciones de subclase en realidad solo fallan en la tarea actual pero continúan con la compilación.

skipy
fuente
28

Actualmente no existe un método dedicado, aunque ha habido discusiones para agregar uno.

La forma recomendada de detener una compilación de Gradle es lanzar una excepción. Como Groovy no tiene excepciones marcadas, y Gradle por defecto no imprime el tipo de excepción, no es tan importante qué excepción se produce. En los scripts de compilación, GradleException se usa a menudo, pero una aserción Groovy también parece razonable (dependiendo de las circunstancias y la audiencia). Lo importante es proporcionar un mensaje claro. Agregar una causa (si está disponible) ayuda a depurar ( --stacktrace).

Gradle proporciona tipos de excepción dedicados StopExecutionException/ StopActionExceptionpara detener la tarea actual / acción de tarea pero continuar la compilación.

Peter Niederwieser
fuente
19

Otra opción si no desea poder detectar la excepción más adelante es llamar a la tarea de falla de hormiga. En mi opinión, es un poco más fácil de leer y puede dar un buen mensaje al usuario sin usar --stacktrace.

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

Te da un mensaje como:

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

Probablemente puedas atrapar esto (¿tal vez arroja la BuildException de ant?) Pero si ese es un objetivo, entonces no usaría ant.fail. Simplemente facilitaría ver qué excepción atrapar lanzando una excepción estándar de gradle como sugirieron tim_yates.

Gus
fuente
¿Cómo lo configuro? ¿Llámalo?
polvo366
1
simplemente llame a ant.fail ('mensaje de su elección') sin necesidad de configuración
Gus
2
Parece que el resultado de esto es idéntico al uso throw new GradleException("The sky is falling!!")(Gradle 3.4.1)
mgaert
@mgaert Parece recordar que hace 4 años, cuando escribí esto, el mensaje impreso era diferente (pero eso es mucho tiempo y no tengo ganas de averiguar qué versión estaba vigente en ese momento y verificar). Más allá de eso, IMHO ant.fail comunica más claramente la intención de detener completamente la compilación, mientras que la excepción lanzada se lee como algo que podría ser atrapado y manejado.
Gus
12

Lanzar una GradleException simple funciona para detener el script de compilación. Esto funciona muy bien para verificar la configuración del entorno requerida.

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

Ejemplo:

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

Aquí hay un fragmento de código que intenta emular cómo la tarea Gradle javac arroja errores:

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." )
            )
        }
    }
}

Cuando el comando regresa 0no hay salida. Cualquier otro valor imprimirá la salida estándar y detendrá la compilación.

NOTA: Si su comando también escribe en errorOutput, es posible que deba incluirlo en el registro de errores.

cmcginty
fuente