Más métodos de las tareas

Qué distintos métodos tenemos aparte de doLast, como doFirst, y qué debemos conocer al usarlo. Además, cómo usar mustRunAfter.

Este curso ha sido marcado como anticuado y no está siendo revisado de forma activa. Es posible que la información pueda estar desactualizada o que los enlaces se hayan roto.

Cuando trabajamos con Gradle, uno de los aspectos fundamentales es entender cómo manejar las tareas y sus métodos asociados para definir comportamientos específicos durante la construcción del proyecto. Hemos visto que doLast es un método muy importante que nos permite añadir acciones que se ejecutan al final de una tarea. Por ejemplo, podemos definir una tarea llamada holaMundo y dentro de ella usar doLast para incluir código que se ejecutará cuando la tarea termine, como imprimir mensajes o manipular archivos con Groovy o Java.

Este método doLast acepta como parámetro una cláusula, que en Groovy es una función anónima encerrada entre corchetes. Esto significa que podemos pasarle un bloque de código que Gradle interpretará y ejecutará en el momento adecuado. Pero doLast no es el único método que podemos usar para definir acciones en una tarea; también existe doFirst, que funciona de manera similar pero ejecuta el código que le pasamos al principio de la tarea.

Si definimos dentro de una tarea tanto doFirst como doLast, Gradle se encargará de ejecutar primero el bloque de doFirst y luego el de doLast. Por ejemplo, si en la tarea holaMundo ponemos un doFirst que imprima llamando doFirst y un doLast que imprima llamando doLast, al ejecutar la tarea veremos esos mensajes en ese orden.

Sin embargo, es importante no confundir la ejecución de doFirst con la ejecución de otras tareas de las que pueda depender nuestra tarea. Por ejemplo, si creamos una tarea holaMundoAgain que depende de holaMundo y definimos en ambas tareas bloques doFirst y doLast que impriman mensajes identificativos, al ejecutar holaMundoAgain primero se ejecutará completamente la tarea holaMundo (incluyendo sus doFirst y doLast) y solo después se ejecutará holaMundoAgain. Esto significa que el doFirst de holaMundoAgain no se ejecuta antes que la tarea holaMundo, sino después de que esta haya terminado.

Esta diferencia se debe a que Gradle trabaja en varias fases: inicialización, configuración y ejecución. Durante la fase de configuración, Gradle interpreta el archivo de construcción y establece las dependencias entre tareas, así como los bloques doFirst y doLast. Luego, en la fase de ejecución, Gradle ejecuta las tareas en el orden determinado por esas dependencias. Por eso, cualquier código que pongamos directamente dentro de la definición de la tarea (fuera de doFirst o doLast) se ejecuta en la fase de configuración, antes de que comience la ejecución real de las tareas.

Por ejemplo, si dentro de la tarea holaMundo ponemos un println directamente, este mensaje aparecerá antes que los mensajes de doFirst y doLast cuando ejecutemos la tarea, porque se ejecuta en la fase de configuración.

Un error común es pensar que podemos usar doFirst para ejecutar código antes que otras tareas de las que depende nuestra tarea. Esto no es así. Si queremos que una tarea se ejecute antes que otra, debemos organizar las dependencias correctamente y no intentar invocar la ejecución de una tarea dentro del bloque doFirst de otra. Intentar llamar a execute() de otra tarea dentro de doFirst puede causar problemas y no es la forma recomendada de controlar el orden de ejecución.

Para controlar el orden en que se ejecutan las tareas cuando hay múltiples dependencias, Gradle ofrece el modificador mustRunAfter. Este modificador nos permite indicar que una tarea debe ejecutarse después de otra si ambas están en la lista de tareas a ejecutar. Por ejemplo, si tenemos dos tareas a y b, y definimos b.mustRunAfter a, entonces aunque invoquemos gradle b a, Gradle ejecutará primero la tarea a y luego la tarea b.

Esto es especialmente útil para asegurarnos de que ciertas tareas se ejecuten en un orden específico sin crear dependencias estrictas que obliguen a ejecutar una tarea siempre que se ejecute otra. Así, podemos tener una tarea que incluya código que debe ejecutarse antes que otra tarea, y usar mustRunAfter para garantizar ese orden.

En resumen, para ejecutar código antes que otra tarea, lo mejor es crear una tarea separada con ese código y usar mustRunAfter para controlar el orden de ejecución. No debemos confiar en que doFirst ejecute código antes que las dependencias de la tarea, ni intentar invocar tareas manualmente dentro de doFirst. Entender estas fases y métodos nos ayuda a organizar mejor nuestras tareas y evitar errores comunes en la construcción con Gradle.

Un ejemplo sencillo para ilustrar el uso de doFirst, doLast y mustRunAfter sería el siguiente:

task holaMundo {
    doFirst {
        println "holaMundo.doFirst"
    }
    doLast {
        println "holaMundo.doLast"
    }
}

task holaMundoAgain(dependsOn: holaMundo) {
    doFirst {
        println "holaMundoAgain.doFirst"
    }
    doLast {
        println "holaMundoAgain.doLast"
    }
}

task a {
    doLast {
        println "Ejecutando tarea a"
    }
}

task b {
    doLast {
        println "Ejecutando tarea b"
    }
}

b.mustRunAfter a

Si ejecutamos gradle holaMundoAgain, veremos que primero se ejecuta completamente holaMundo (con sus doFirst y doLast) y luego holaMundoAgain. Si ejecutamos gradle b a, Gradle ejecutará primero a y luego b debido a la regla mustRunAfter.

Con este conocimiento, podemos manejar las tareas en Gradle de forma más precisa y evitar confusiones sobre el orden de ejecución y las fases en las que se ejecuta cada bloque de código.

Lista de reproducción
  1. 1
    Instalar Gradle
    7 minutos
  2. 2
    Creando las primeras tareas
    7 minutos
  3. 3
    Más sobre tareas
    8 minutos
  4. 4
    Cómo usar Gradle con Java
    11 minutos
  5. 5
    Creando aplicaciones con Application
    3 minutos
  6. 6
    Dependencia entre tareas
    5 minutos
  7. 7
    Más métodos de las tareas
    9 minutos
  8. 8
    Ejecución condicional con onlyIf
    5 minutos
  9. 9
    finalizedBy
    2 minutos
  10. 10
    Tareas base de Gradle
    3 minutos
  11. 11
    Tarea Copy
    6 minutos
  12. 12
    Tarea Exec
    6 minutos
  13. 13
    Tarea Zip
    5 minutos
  14. 14
    Importar en IntelliJ IDEA
    6 minutos
  15. 15
    Importar en Eclipse
    5 minutos
  16. 16
    Importar en NetBeans
    4 minutos
  17. 17
    Dependencias con Maven
    11 minutos
  18. 18
    Qué aprender ahora
    5 minutos
  19. 19
    ¿Qué es Gradle?
    6 minutos