2012-05-11 12 views
14

Tener un extracto de https://github.com/gradle/gradle/blob/master/build.gradle:configuración personalizada condicional para proyectos Gradle

ext { 
    isDevBuild = { 
    gradle.taskGraph.hasTask(developerBuild) 
    } 
} 

task developerBuild { 
    description = 'Builds distributions and runs pre-checkin checks' 
    group = 'build' 
    dependsOn testedDists 
} 

Cuando he usado este enfoque para crear una configuración personalizada en mi proyecto he descubierto que:

isDevBuild === true 

es decir, que siempre es cierto porque la tarea 'developerBuild' está dentro de mi proyecto build.gradle, y por lo tanto en gráfico. Tienen un par de configuraciones "diferentes" (esCIBuild, isCommitBuild, isFinalReleaseBuild, ...) así que supongo que tengo algo mal aquí.

¿Alguien puede explicar cómo hacer que esta configuración sea condicional en función de algún parámetro externo?

Respuesta

35

taskGraph.hasTask() indica si una tarea está en la tarea ejecución gráfico, es decir si se ejecutará. Debido a que el gráfico de ejecución de la tarea sólo se crea después de la fase de configuración, este método tiene que ser llamado de una devolución de llamada whenReady (o en fase de ejecución):

gradle.taskGraph.whenReady { graph -> 
    if (graph.hasTask(developerBuild)) { 
     // do conditional configuration 
    } 
} 

Para que esto sea más fácil de leer, podemos introducir un nuevo método :

def onlyFor(task, config) { 
    gradle.taskGraph.whenReady { graph -> 
     if (graph.hasTask(task)) { 
      project.configure(project, config) 
     } 
    } 
} 

Ahora podemos escribir:

onlyFor(developerBuild) { ... } 
onlyFor(ciBuild) { ... } 

Otra forma más sencilla de resolver este problema es comprobar si un nombre de tarea en particular está contenida en gradle.startParameter.taskNames. Sin embargo, esto tiene dos limitaciones: en primer lugar, compara los nombres de la tarea , que pueden marcar la diferencia en las compilaciones de proyectos múltiples. En segundo lugar, solo encontrará las tareas que se hayan especificado directamente (por ejemplo, en la línea de comandos), pero no las dependencias de las mismas.

PD .: En su código, isDevBuild siempre mantiene debido a un cierre (no nulo) es true según la verdad maravilloso. (En contraste con isDevBuild(), isDevBuild no llamará al cierre.)

+0

Volviendo a la aserción del libro "Construyendo y Probando con Gradle": el conocimiento de Groovy no es más, es necesario empezar a trabajar con Gradle. Gracias por tu ayuda. Lo comprobaré más tarde hoy. –

+1

No diría que es imprescindible para comenzar, pero es necesario implementar soluciones avanzadas como esta. (Una alternativa simple que requiere menos conocimiento de Groovy es cambiar entre diferentes configuraciones basadas en una propiedad del sistema). De nuevo, gran parte de este código podría escribirse en estilo Java (con clases internas anónimas y similares), o literalmente en Java si lo moví a un plugin. El verdadero desafío en este caso particular es comprender el lado Gradle de las cosas: la API del gráfico de tareas, la fase de configuración vs. ejecución, etc. –

+0

Su solución funciona bien. Muchas gracias. Para la nota que pones en P.S. : No puedo llamar directamente a 'isDevBuild()' cuando ejecuto la creación de Gradle con 'ciBuild jar' por ejemplo (y no puedo usar ambas configuraciones al mismo tiempo) - aunque usted demostró que puedo llamar al cierre solo para fines educativos. –

Cuestiones relacionadas