sábado, 29 de agosto de 2015

Multi-proyecto con gradle


Vamos analizar la necesidad de crear un proyecto, compuesto de varias sub-proyectos.
  • Nos permite realizar una separación lógica de nuestro proyecto. Un clasico es el bom( la B.d), service(La capa de negocio), webapp (La capa de vista).
  • Esta separación nos va evitar que desde un modulo no se puedan llamar a clases del otro ( Si los configuramos como capas separadas). Ejemplo, llamar desde un servicio a la request de un contenedor de servlet que pertenece a la capa de vista.
Cada sub-proyecto va a ser independiente entre si, aunque lo normal es que tenga rasgos comunes.
Ojo: Esto es un ejemplo de como darle utilidad a los subproyectos.
Vamos a ver en este articulo un ejemplo, simple de montar un proyecto raiz y 2 modulos (bom, service).
El ejemplo esta en la siguiente dirección https://github.com/blancoparis-tfc/MultiProyectoGradle.

Organización del fichero.


El proyecto raiz ( o padre), contendrá cada uno de los sub-proyectos (El nombre de la carpeta será el nombre de cada uno de los subProyectos:
Organización del proyecto:
  • build.gradle: El buil del proyecto raiz.
  • settings.gradle: Donde indicaremos los modulos.
  • bom(Directorio): Es el subProyecto  bom.
  • service(Directorio): Es el sub-proyecto service.

Vamos a crear un tarea que nos diga el nombre de cada proyecto, para lo cual nos vamos a apoyar en el buid.gradle del proyecto raiz, vamos a poner una configuración común, de la tarea hola.

Configurar los sub-proyectos.


Ahora le indicamos los sub-proyectos, que en nuestro caso van a ser bom y service.
Fichero (settings.gradle)
include 'bom','service'

Configurar todos los proyectos.


Aquí vamos a ver como establecer la configuración a todos los proyectos.
Fichero (build.gradle)
allprojects {
  task hola << { task -> println "Soy $task.project.name"}
}
$task.project.name—> Accede al nombre del proyecto
La etiqueta allprojects nos pone la configuración en todos los proytectos, incluido el proyecto raiz
Ahora le indicamos los sub-proyectos, que en nuestro caso van a ser bom y service.
Fichero (settings.gradle)
include 'bom','service'
Ahora ejecutamos la tarea hola, ejecutando
gradle –q hola
El resultado es:
>Soy MultiProyectoGradle
>Soy bom
>Soy service

Configurar solo los submodulos


Aqui vamos a ver como establecer la configuración solo para los submodulos, para lo cual vamos a utilizar subprojects.
allprojects {
  task hola << { task -> println "Soy $task.project.name"}
}
subprojects{
  hola << {println "   - Dependo de multi-proyecto"}
}
Ahora ejecutamos la tarea hola, ejecutando
gradle –q hola
El resultado es:
>Soy MultiProyectoGradle
>Soy bom
>    - Dependo de multi-proyecto
>Soy service
>    - Dependo de multi-proyecto

Establecer un comportamiento especifico a un proyecto.


Ahora vamos a verr, como podemos indicar una configuración especifica a un sub-proyecto en cuestión, para lo cual vamos a usar project('<nombre del sub-proyecto).<tarea>
allprojects {
  task hola << { task -> println "Soy $task.project.name"}
}
subprojects{
  hola << {println "   - Dependo de multi-proyecto"}
}
project(':bom').hola << {
  println "        - Soy el proyecto  donde va a estar el modelo de dominio "
}
Ahora ejecutamos la tarea hola, ejecutando
gradle –q hola
>Soy MultiProyectoGradle
>Soy bom
>    - Dependo de multi-proyecto
>          - Soy el proyecto donde va a estar el modelo de dominio
>Soy service
>    - Dependo de multi-proyecto

Nota: La configuración del modulo, lo idea es que este en su propio scripts del proyecto, pero asi vemos como podemos establecer la configuración desde el modulo raiz.

Configurar los sub-proyectos


Ahora vamos a ver como configurar cada sub-modulo, con su propio scripts de gradle

/bom/build.gradle
hola.doLast {
  println "             - Soy el proyecto donde vamos a definir el modelo de dominio";
}
/service/build.gradle
hola.doLast {
  println "             - Soy el proyecto que implementa la capa de negocio";
}
Ahora ejecutamos la tarea hola, ejecutando
gradle –q hola
>Soy MultiProyectoGradle
>Soy bom
>    - Dependo de multi-proyecto
>          - Soy el proyecto donde vamos a definir el modelo de dominio
>Soy service
>    - Dependo de multi-proyecto
>          - Soy el proyecto que implementa la capa de negocio

Reglas de ejecución:


En este caso sigue la regla de ejecutar todas las tareas que se encuentren en la jerarquía, hacia abaojo, por lo cual si entramos en el directorio bom, solo ejecutara la de bom. 

 bom/gradle –q hola

>Soy bom
>    - Dependo de multi-proyecto
>          - Soy el proyecto donde vamos a definir el modelo de dominio

El orden de ejecución es el alfabetico por defecto segun los encuentra  en la jerarquia, por lo cual en el nivel inferior, (ejecuta el multi-proyecto (nivel 0), luego bom y service.

Establecer el orden de ejecución:


Como hemos visto en los ejemplos anteriores, el orden de ejecución es el raiz y el resto por orden alfabetico.

Aunque en este caso no lo necesitamos vamos a ver como establecer un orden de ejecución entre los diferentes sub-proyectos.

Para este ejemplo crearemos la tarea inverso y en le proyecto bom, le vamos a indicar que esta tarea le precede el service, para lo cual utilizaremos el atributo dependsOn

/bom/build.gradle
hola.doLast {
  println "             - Soy el proyecto donde vamos a definir el modelo de dominio";
}
task inverso(dependsOn: ":service:inverso") <<{
  println " El ultimo es bom";
}
/service/build.gradle
hola.doLast {
  println "             - Soy el proyecto que implementa la capa de negocio";
}
task inverso <<{
  println " El primero es service";
}
gradle –q inverso
> El primero es service
> El ultimo es bom

Conclusión

En este articulo hemos visto con unos ejemplos tontos diferentes comportamientos, a la hora de trabajar con un proyecto en gradle por módulos, sin meter ninguna complicación mas. Para realizarlo me he basado en la documentación de gradle oficial, donde vienen muchas mas cosas en el siguiente enlace (https://docs.gradle.org/current/userguide/multi_project_builds.html#multiprojectUseSubprojects)

Nota: En la documentación oficial de gradle hay muchas mas cosas, como mecanismos para filtrar etc...

No hay comentarios:

Publicar un comentario