¿Cómo puedo importar una secuencia de comandos de Gradle a otra?

97

Tengo una secuencia de comandos gradle compleja que incluye una gran cantidad de funcionalidades en torno a la construcción e implementación de varios proyectos de netbeans en varios entornos.

El script funciona muy bien, pero en esencia todo está configurado a través de media docena de mapas que contienen información del proyecto y del entorno.

Quiero abstraer las tareas en otro archivo, para poder simplemente definir mis mapas en un archivo de compilación simple e importar las tareas desde el otro archivo. De esta manera, puedo usar las mismas tareas básicas para varios proyectos y configurar esos proyectos con un simple conjunto de mapas.

¿Alguien puede decirme cómo puedo importar un archivo gradle a otro, de manera similar a la tarea de Ant? He rastreado los documentos de Gradle en vano hasta ahora.

Información adicional

Después de la respuesta de Tom a continuación, pensé en intentar aclarar exactamente lo que quiero decir.

Básicamente, tengo un script de Gradle que ejecuta varios subproyectos. Sin embargo, los subproyectos son todos proyectos de Netbeans y vienen con sus propios scripts de compilación de hormigas, por lo que tengo tareas en gradle para llamar a cada uno de estos.

Mi problema es que tengo alguna configuración en la parte superior del archivo, como:

projects = [
    [name:"MySubproject1", shortname: "sub1", env:"mainEnv", cvs_module="mod1"],
    [name:"MySubproject2", shortname: "sub2", env:"altEnv", cvs_module="mod2"]
]

Luego genero tareas como:

projects.each({
    task "checkout_$it.shortname" << {
         // Code to for example check module out from cvs using config from 'it'.
    }
})

Tengo muchos de estos tipos de fragmentos de generación de tareas, y todos son genéricos: dependen por completo de la configuración en la lista de proyectos.

Entonces, lo que quiero es una forma de poner esto en un script separado e importarlo de la siguiente manera:

projects = [
    [name:"MySubproject1", shortname: "sub1", env:"mainEnv", cvs_module="mod1"],
    [name:"MySubproject2", shortname: "sub2", env:"altEnv", cvs_module="mod2"]
]

import("tasks.gradle") // This will import and run the script so that all tasks are generated for the projects given above.

Entonces, en este ejemplo, tasks.gradle tendrá todo el código genérico de generación de tareas y se ejecutará para los proyectos definidos en el archivo principal build.gradle. De esta manera, tasks.gradle es un archivo que puede ser utilizado por todos los proyectos grandes que constan de varios subproyectos con archivos de compilación de Netbeans.

Anthony Roy
fuente
3
Considere la construcción "aplicar desde: 'other.gradle'" para importar declaraciones externas. (Consulte "12.4. Configuración del proyecto mediante un script de compilación externo" aquí gradle.org/0.9-preview-1/docs/userguide/… )
Petr Gladkikh
@PetrGladkikh apply fromejecuta inmediatamente las tareas externas. Esto puede no ser preferible en la lógica de ejecución (es decir, querría ejecutar las tareas cuando quiera, no de inmediato).
IgorGanapolsky
Esta afirmación en el comentario anterior no es cierta : apply fromejecuta inmediatamente las tareas externas. No se deje engañar. Las tareas externas se configuran, no se ejecutan.
Jarekczek

Respuestas:

17

La respuesta a la pregunta resultó estar en el sistema de complementos, donde puede agregar la funcionalidad deseada en un conjunto de complementos que pueden ser archivos maravillosos ubicados en el directorio buildSrc/src/main/groovy. Los complementos también se pueden empaquetar como un Jar, aunque no lo he probado.

Detalles aquí: Complementos personalizados

Anthony Roy
fuente
Solo para que sepa que el enlace está roto, aquí hay una actualización gradle.org/docs/current/userguide/…
JARC
Enlace del complemento: gradle.org/docs/current/userguide/…
JARC
4

Bueno, es difícil saber qué le sirve mejor sin ver realmente su archivo de compilación.

Podría suponer que establecer su entorno como compilación multiproyecto debería proporcionarle la abstracción que está buscando.

En la raíz de su proyecto build.gradle, define todas las cosas específicas de su dominio, así como las cosas que se aplican a todos sus subproyectos:

repositories {
    add(new org.apache.ivy.plugins.resolver.FileSystemResolver()) {
        name = 'destRepo'
        addIvyPattern( file( project.properties['repo.dest.dir']).absolutePath + '/[organisation]/[module]/ivys/ivy(-[revision]).xml')
        addArtifactPattern( file( project.properties['repo.dest.dir']).absolutePath + '/[organisation]/[module]/[type]s/[artifact](-[revision]).[ext]')
        descriptor = 'optional'
        checkmodified = true
    }
    ...
}
...
subprojects {
    sourceCompatibility = 1.5
    targetCompatibility = 1.5
    group = 'my.group'
    version = '1.0'
    uploadArchives {
        uploadDescriptor = true
        repositories {
            add rootProject.repositories.destRepo
        }
    }
    apply{ type my.group.gradle.api.plugins.MyPlugin }
    ...
}

dependsOnChildren()

El directorio raíz del proyecto también puede contener un gradle.propertiesarchivo en el que defina las propiedades utilizadas por sus proyectos:

buildDirName=staging
repo.dest.dir=/var/repo
...

Luego, en un archivo adicional de la raíz de su proyecto llamado settings.gradle, en realidad apunta a sus subproyectos:

include 'my-first-component',
        'my-second-component'
...
project(':my-first-component').projectDir = new File(rootDir, 'path/to/first/component')
project(':my-second-component').projectDir = new File(rootDir, 'path/to/second/component')
...

Cada directorio de subproyecto contiene un build.gradlearchivo que contiene únicamente las cosas específicas del subproyecto.

No importa si invoca gradledesde la raíz de su proyecto o el directorio de subproyectos, gradle considerará automáticamente todas sus definiciones realizadas en los distintos archivos.

También tenga en cuenta que no se ejecutará ninguna tarea de compilación para la raíz de su proyecto siempre que no cargue ningún complemento más allá del complemento predeterminado en el nivel raíz.

Tom
fuente
1
Gracias por tomarse el tiempo para responder. No se trata de subproyectos con los que tengo problemas, sino de crear una "biblioteca" de tareas comunes. Edité mi pregunta original con más información y fragmentos de código para aclarar las cosas.
Anthony Roy
1
Entonces, en lugar de realizar la importación ("tasks.gradle") de tu muestra, tendrías la sección de subproyectos {} especificando el código genérico de generación de tareas usado por todos tus subproyectos. ¡¿Esto debería proporcionar la misma abstracción que estás buscando ?!
Tom
¿Es realmente necesario el complemento Ivy aquí? ¿No se puede utilizar Gradle solo?
IgorGanapolsky