construccion de proyectos con gradle
DESCRIPTION
Estas son las slides que utilicé en la charla de la reunión de Septiembre de 2014 del GDG de Madrid. Desde hace tiempo, los desarrolladores venimos utilizando scripts para automatizar y facilitarnos la construcción automática de nuestros proyectos. En los intentos de estandarización de esos Scripts, la primera herramienta fue Ant, muy flexible, pero muy tediosa por lo verboso y por que siempre había que empezar desde cero. La llegada de Maven supuso una cierta convención en las tareas y fases de construcción de un proyecto. Pero también incluía una tremenda facilidad para la gestión de librerías y dependencias. A cambio, impone una cierta rigidez en la estructura del script. Gradle ha venido a buscar lo mejor de los dos mundos: la fexibilidad de Ant, la convención de Maven, la gestión de librerías de Ivy o Mvn.... y todo ello con un lenguaje de scripting más parecido al código que al XML en el que se basan las dos precedesoras. Desde hace meses, Google ya ha apostado por Gradle como sistema de construcción de proyectos para Android en su Android Studio. En esta charla, haremos una introducción a Gradle como herramienta de construcción de proyectos.TRANSCRIPT
![Page 1: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/1.jpg)
David Gómez G.@dgomezg
Construcción de proyectos con
![Page 2: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/2.jpg)
Automatizar la construcción… ¿Pur qué?
Foto de Steindy http://commons.wikimedia.org/wiki/File:Jose_Mourinho_-_Inter_Mailand_(7).jpg
• Evitar empaquetado manual
• Construir rápidamente
y en cualquier entorno
• Builds programadas (C.I.)
![Page 3: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/3.jpg)
HerramientasFichero de descripción
+
Código fuente
+
Gestión de dependencias
=
Artefacto
![Page 4: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/4.jpg)
Características • Basado en Java
• Configuración basada en XML
• Gestor de dependencias adicional (Ivy)
• Muy flexible
• Todas las tareas se definen específicamente
![Page 5: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/5.jpg)
Pegas • Muy verboso. XML muy extensos
• Difícil escribir lógica compleja (condiciones)
• Estructura de proyecto libre.
• Difícil de mantener
• Difícil de entender el proceso de construcción.
![Page 6: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/6.jpg)
Ejemplo
![Page 7: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/7.jpg)
Ejemplo <?xml version="1.0" encoding="UTF-8"?><project> <target name="clean"> <delete dir="build"/> </target> <target name="compile"> <mkdir dir="build/classes"/> <javac srcdir="src" destdir="build/classes"/> </target> <target name="jar"> <mkdir dir="build/jar"/> <jar destfile="build/jar/HelloWorld.jar" basedir="build/classes"> <manifest> <attribute name="Main-Class" value="com.autentia.dgomezg.sandbox.ant.HelloWorld"/> </manifest> </jar> </target>! <target name="run"> <java jar="build/jar/HelloWorld.jar" fork="true"/> </target>!</project>
![Page 8: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/8.jpg)
Ejemplo <?xml version="1.0" encoding="UTF-8"?><project> <target name="clean"> <delete dir="build"/> </target> <target name="compile"> <mkdir dir="build/classes"/> <javac srcdir="src" destdir="build/classes"/> </target> <target name="jar"> <mkdir dir="build/jar"/> <jar destfile="build/jar/HelloWorld.jar" basedir="build/classes"> <manifest> <attribute name="Main-Class" value="com.autentia.dgomezg.sandbox.ant.HelloWorld"/> </manifest> </jar> </target>! <target name="run"> <java jar="build/jar/HelloWorld.jar" fork="true"/> </target>!</project>
dolamroth:ant-sample dgomezg$ ant clean compile jar runBuildfile: /Users/dgomezg/Documents/workspace/ant-sample/build.xml!clean:!compile: [mkdir] Created dir: /Users/dgomezg/Documents/workspace/ant-sample/build/classes [javac] Compiling 1 source file to /Users/dgomezg/Documents/workspace/ant-sample/build/classes!jar: [mkdir] Created dir: /Users/dgomezg/Documents/workspace/ant-sample/build/jar [jar] Building jar: /Users/dgomezg/Documents/workspace/ant-sample/build/jar/HelloWorld.jar!run: [java] Hello World!BUILD SUCCESSFULTotal time: 1 seconddolamroth:ant-sample dgomezg$
![Page 9: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/9.jpg)
Características • Convención sobre configuración
• Estructura de proyecto determinada
• Proceso de construcción definido
• Gestor de dependencias
• Informes de construcción y de test
• Arquetipos
• Ampliable con Plugins (Mojos)
![Page 10: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/10.jpg)
Pegas • Estructura demasiado rígida
• Extensión complicada
• Fichero de build verboso
• Especialmente si configuramos plugins
![Page 11: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/11.jpg)
Ejemplo
![Page 12: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/12.jpg)
Ejemplo <?xml version="1.0" encoding="UTF-8"?><project> <modelVersion>4.0.0</modelVersion> <groupId>com.autentia.dgomezg.sandbox</groupId> <artifactId>mvn-sample</artifactId> <version>1.0.0</version></project>
![Page 13: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/13.jpg)
Ejemplo <?xml version="1.0" encoding="UTF-8"?><project> <modelVersion>4.0.0</modelVersion> <groupId>com.autentia.dgomezg.sandbox</groupId> <artifactId>mvn-sample</artifactId> <version>1.0.0</version></project>
dolamroth:mvn-sample dgomezg$ mvn package[INFO] Scanning for projects...[INFO] [INFO] ------------------------------------------------------------------------[INFO] Building mvn-sample 1.0.0[INFO] ------------------------------------------------------------------------[INFO] [INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ mvn-sample ---[debug] execute contextualize[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent![INFO] Copying 0 resource[INFO] [INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ mvn-sample ---[INFO] Nothing to compile - all classes are up to date[INFO] [INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ mvn-sample ---[debug] execute contextualize[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent![INFO] Copying 0 resource[INFO] [INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ mvn-sample ---[INFO] Nothing to compile - all classes are up to date[INFO] [INFO] --- maven-surefire-plugin:2.10:test (default-test) @ mvn-sample ---[INFO] Surefire report directory: /Users/dgomezg/Documents/workspace/mvn-sample/target/surefire-reports!------------------------------------------------------- T E S T S-------------------------------------------------------!Results :!Tests run: 0, Failures: 0, Errors: 0, Skipped: 0![INFO] [INFO] --- maven-jar-plugin:2.3.2:jar (default-jar) @ mvn-sample ---[INFO] Building jar: /Users/dgomezg/Documents/workspace/mvn-sample/target/mvn-sample-1.0.0.jar[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time: 0.876s[INFO] Finished at: Wed Nov 20 13:32:06 CET 2013[INFO] Final Memory: 7M/245M[INFO] ------------------------------------------------------------------------dolamroth:mvn-sample dgomezg$
![Page 14: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/14.jpg)
¿Qué se puede mejorar?Ficheros de build más concisos
Convención para estructura
Flexibilidad para requisitos
Builds incrementales
Reutilización de partes del script
Soporte para implementar lógica
![Page 15: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/15.jpg)
Características • Flexibilidad
• Definición de nuevas tareas
• Gestor de dependencias (Ivy)
• Convención sobre configuración
• Multi-Módulo
• Plugins
• Gestor de dependencias
![Page 16: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/16.jpg)
Características • Basado en Groovy
• Lenguaje completo
• Permite definir lógica más compleja
• Convenciones Flexibles
• Extensibilidad
• Integración con Ant (AntExecutor) y maven
![Page 17: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/17.jpg)
Ejemplo
![Page 18: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/18.jpg)
Ejemplo build.gradle
![Page 19: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/19.jpg)
Ejemplo apply plugin: 'java'!group = 'com.autentia.dgomezg.sandbox'archivesBaseName = 'gradle-sample'version = '0.1.0-SNAPSHOT'!
build.gradle
![Page 20: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/20.jpg)
Ejemplo apply plugin: 'java'!group = 'com.autentia.dgomezg.sandbox'archivesBaseName = 'gradle-sample'version = '0.1.0-SNAPSHOT'!
dolamroth:gradle-sample dgomezg$ gradle build:compileJava UP-TO-DATE:processResources UP-TO-DATE:classes UP-TO-DATE:jar:assemble:compileTestJava UP-TO-DATE:processTestResources UP-TO-DATE:testClasses UP-TO-DATE:test:check:build!BUILD SUCCESSFUL!Total time: 2.375 secsdolamroth:gradle-sample dgomezg$
build.gradle
![Page 21: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/21.jpg)
Ejemplo apply plugin: 'java'!group = 'com.autentia.dgomezg.sandbox'archivesBaseName = 'gradle-sample'version = '0.1.0-SNAPSHOT'!
dolamroth:gradle-sample dgomezg$ gradle build:compileJava UP-TO-DATE:processResources UP-TO-DATE:classes UP-TO-DATE:jar:assemble:compileTestJava UP-TO-DATE:processTestResources UP-TO-DATE:testClasses UP-TO-DATE:test:check:build!BUILD SUCCESSFUL!Total time: 2.375 secsdolamroth:gradle-sample dgomezg$
apply plugin: 'java'!group = 'com.autentia.dgomezg.sandbox'archivesBaseName = 'gradle-sample'version = '0.1.0-SNAPSHOT'!sourceCompatibility = 1.6!jar { manifest { attributes 'Main-Class': 'com.autentia.dgomezg.sandbox.gradle.HelloWorld' }}
build.gradle
![Page 22: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/22.jpg)
Fundamentos Gradle
![Page 23: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/23.jpg)
El proceso
![Page 24: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/24.jpg)
La lista de tareasgradle tasks o gradle tasks --all
![Page 25: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/25.jpg)
Groovy DSLTodo tiene un equivalente en clases java
http://gradle.org/docs/current/javadoc/index.html
![Page 26: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/26.jpg)
Groovy DSLMayor flexibilidad a la hora de definir nuevas tareas
![Page 27: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/27.jpg)
Groovy DSLMayor flexibilidad a la hora de definir nuevas tareas
task projectVersion { doLast { println ‘Project version’ + project.version }}
![Page 28: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/28.jpg)
Groovy DSLMayor flexibilidad a la hora de definir nuevas tareas
task projectVersion { doLast { println ‘Project version’ + project.version }}
dolamroth:gradle-sample dgomezg$ gradle projectVersion:projectVersionProject Version: 0.1.0-SNAPSHOT!BUILD SUCCESSFUL!Total time: 3.708 secs
![Page 29: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/29.jpg)
Groovy DSLMayor flexibilidad a la hora de definir nuevas tareas
task projectVersion { doLast { println ‘Project version’ + project.version }}
dolamroth:gradle-sample dgomezg$ gradle projectVersion:projectVersionProject Version: 0.1.0-SNAPSHOT!BUILD SUCCESSFUL!Total time: 3.708 secs
dolamroth:gradle-sample dgomezg$ gradle -q projectVersionProject Version: 0.1.0-SNAPSHOTdolamroth:gradle-sample dgomezg
![Page 30: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/30.jpg)
PluginsPermiten activar funcionalidades
![Page 31: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/31.jpg)
PluginsPermiten activar funcionalidades
apply plugin: 'java'apply plugin: 'maven'apply plugin: ‘eclipse'apply plugin: 'war'!group = 'com.autentia.dgomezg.sandbox'archivesBaseName = 'gradle-sample'version = '0.1.0-SNAPSHOT'!sourceCompatibility = 1.6
![Page 32: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/32.jpg)
PluginsPermiten activar funcionalidades
apply plugin: 'java'apply plugin: 'maven'apply plugin: ‘eclipse'apply plugin: 'war'!group = 'com.autentia.dgomezg.sandbox'archivesBaseName = 'gradle-sample'version = '0.1.0-SNAPSHOT'!sourceCompatibility = 1.6
$ gradle tasks!Build tasks-----------assemble - Assembles the outputs of this project.build - Assembles and tests this project.buildDependents - Assembles and tests this project and all projects that depend on it.buildNeeded - Assembles and tests this project and all projects it depends on.clean - Deletes the build directory.jar - Assembles a jar archive containing the main classes.war - Generates a war archive with all the compiled classes, the web-app content and the libraries.!Documentation tasks-------------------javadoc - Generates Javadoc API documentation for the main source code.!IDE tasks---------cleanEclipse - Cleans all Eclipse files.eclipse - Generates all Eclipse files.!Other tasks-----------install - Installs the 'archives' artifacts into the local Maven repository.
![Page 33: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/33.jpg)
Integración con antPropiedad ant disponible en todas las tareas
![Page 34: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/34.jpg)
Integración con antPropiedad ant disponible en todas las tareas
task projectVersion { doLast { ant.echo(message: 'Project Version: ' + project.version) }}
![Page 35: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/35.jpg)
Integración con antPropiedad ant disponible en todas las tareas
task projectVersion { doLast { ant.echo(message: 'Project Version: ' + project.version) }}
dolamroth:gradle-sample dgomezg$ gradle -q projectVersiondolamroth:gradle-sample dgomezg$ dolamroth:gradle-sample dgomezg$ gradle projectVersion:projectVersion[ant:echo] Project Version: 0.1.0-SNAPSHOT!BUILD SUCCESSFUL!Total time: 2.914 secsdolamroth:gradle-sample dgomezg$
![Page 36: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/36.jpg)
Integración con mavenPor defecto, toma las convenciones de maven
Se puede integrar con los repositorios de maven
![Page 37: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/37.jpg)
Integración con mavenPor defecto, toma las convenciones de maven
Se puede integrar con los repositorios de maven repositories { mavenRepo name: 'nexus', url: 'http://terraka:8080/nexus/content/repositories/public' mavenCentral() mavenRepo name: 'spring-milestones', url: 'http://maven.springframework.org/milestone' mavenRepo name: 'java.net', url: 'http://download.java.net/maven/2/'}
![Page 38: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/38.jpg)
Integración con mavenPor defecto, toma las convenciones de maven
Se puede integrar con los repositorios de maven repositories { mavenRepo name: 'nexus', url: 'http://terraka:8080/nexus/content/repositories/public' mavenCentral() mavenRepo name: 'spring-milestones', url: 'http://maven.springframework.org/milestone' mavenRepo name: 'java.net', url: 'http://download.java.net/maven/2/'}
Declaración compacta de dependencias
![Page 39: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/39.jpg)
Integración con mavenPor defecto, toma las convenciones de maven
Se puede integrar con los repositorios de maven repositories { mavenRepo name: 'nexus', url: 'http://terraka:8080/nexus/content/repositories/public' mavenCentral() mavenRepo name: 'spring-milestones', url: 'http://maven.springframework.org/milestone' mavenRepo name: 'java.net', url: 'http://download.java.net/maven/2/'}
Declaración compacta de dependenciasdependencies { compile "com.google.guava:guava:12.0", "org.apache.commons:commons-lang3:3.1", "org.slf4j:jcl-over-slf4j:1.6.1", "org.springframework.security:spring-security-core:3.0.1.RELEASE", "org.springframework:spring-jdbc:3.0.0.RELEASE", "org.springframework:spring-tx:3.0.0.RELEASE" runtime "org.apache.geronimo.specs:geronimo-jpa_3.0_spec:1.1.1", "org.apache.geronimo.specs:geronimo-servlet_2.4_spec:1.1.1" testCompile "junit:junit:4.5", "org.springframework:spring-test:3.0.0.RELEASE"}
![Page 40: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/40.jpg)
Integración con mavenSe pueden excluir dependencias transitivas
![Page 41: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/41.jpg)
Integración con mavenSe pueden excluir dependencias transitivas
configurations { sources.exclude group: 'com.google.code.guice' all*.exclude module: 'commons-logging'}
![Page 42: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/42.jpg)
Integración con mavenSe pueden excluir dependencias transitivas
configurations { sources.exclude group: 'com.google.code.guice' all*.exclude module: 'commons-logging'}
Se pueden subir artefactos al repositorio
![Page 43: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/43.jpg)
Integración con mavenSe pueden excluir dependencias transitivas
configurations { sources.exclude group: 'com.google.code.guice' all*.exclude module: 'commons-logging'}
Se pueden subir artefactos al repositorioapply plugin: 'maven'!uploadArchives {! repositories.mavenDeployer { def credentials = [userName: 'user', password: 'password'] uniqueVersion = true snapshotRepository(url: 'http://gitrepo:8081/nexus/content/repositories/snapshots') { authentication(credentials) } repository(url: 'http://gitrepo:8081/nexus/content/repositories/releases') { authentication(credentials) } }}
![Page 44: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/44.jpg)
PropiedadesSe pueden utilizar propiedades internas
![Page 45: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/45.jpg)
Propiedadesproject.ext { springVersion = ‘3.2.5.RELEASE’}!dependencies { compile “org.springframework.security:spring-security-core:${springVersion}”, "org.springframework:spring-jdbc:${springVersion}", "org.springframework:spring-tx:${springVersion}" testCompile "junit:junit:4.5", “org.springframework:spring-test:${springVersion}”}
Se pueden utilizar propiedades internas
![Page 46: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/46.jpg)
Propiedades
Se pueden utilizar propiedades externas
project.ext { springVersion = ‘3.2.5.RELEASE’}!dependencies { compile “org.springframework.security:spring-security-core:${springVersion}”, "org.springframework:spring-jdbc:${springVersion}", "org.springframework:spring-tx:${springVersion}" testCompile "junit:junit:4.5", “org.springframework:spring-test:${springVersion}”}
Se pueden utilizar propiedades internas
![Page 47: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/47.jpg)
Propiedades
Se pueden utilizar propiedades externasversion=0.1.0-SNAPSHOTspringVersion=3.2.5.RELEASEsharedLocation=https://raw.github.com/autentia/common/
gradle.properties
project.ext { springVersion = ‘3.2.5.RELEASE’}!dependencies { compile “org.springframework.security:spring-security-core:${springVersion}”, "org.springframework:spring-jdbc:${springVersion}", "org.springframework:spring-tx:${springVersion}" testCompile "junit:junit:4.5", “org.springframework:spring-test:${springVersion}”}
Se pueden utilizar propiedades internas
![Page 48: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/48.jpg)
Propiedades
dependencies { compile “org.springframework.security:spring-security-core:${springVersion}”, "org.springframework:spring-jdbc:${springVersion}", "org.springframework:spring-tx:${springVersion}" testCompile "junit:junit:4.5", “org.springframework:spring-test:${springVersion}”}
Se pueden utilizar propiedades externasversion=0.1.0-SNAPSHOTspringVersion=3.2.5.RELEASEsharedLocation=https://raw.github.com/autentia/common/
gradle.properties
build.gradle
project.ext { springVersion = ‘3.2.5.RELEASE’}!dependencies { compile “org.springframework.security:spring-security-core:${springVersion}”, "org.springframework:spring-jdbc:${springVersion}", "org.springframework:spring-tx:${springVersion}" testCompile "junit:junit:4.5", “org.springframework:spring-test:${springVersion}”}
Se pueden utilizar propiedades internas
![Page 49: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/49.jpg)
Gradle on JVM
![Page 50: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/50.jpg)
Gradle on JVMtask projectVersion { doLast { println ‘Project version’ + project.version }}
![Page 51: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/51.jpg)
Gradle on JVMtask projectVersion { doLast { println ‘Project version’ + project.version }}
dolamroth:gradle-sample dgomezg$ gradle projectVersion:projectVersionProject Version: 0.1.0-SNAPSHOT!BUILD SUCCESSFUL!Total time: 3.708 secs
![Page 52: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/52.jpg)
Gradle on JVMtask projectVersion { doLast { println ‘Project version’ + project.version }}
dolamroth:gradle-sample dgomezg$ gradle projectVersion:projectVersionProject Version: 0.1.0-SNAPSHOT!BUILD SUCCESSFUL!Total time: 3.708 secs
WTF!!!!
![Page 53: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/53.jpg)
Gradle on JVMtask projectVersion { doLast { println ‘Project version’ + project.version }}
dolamroth:gradle-sample dgomezg$ gradle projectVersion:projectVersionProject Version: 0.1.0-SNAPSHOT!BUILD SUCCESSFUL!Total time: 3.708 secs
WTF!!!!Tiempo dedicado a levantar la JVM y traducir el script
![Page 54: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/54.jpg)
Gradle daemon to the rescue!gradle --daemon
![Page 55: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/55.jpg)
Gradle daemon to the rescue!gradle --daemon
![Page 56: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/56.jpg)
Gradle daemon to the rescue!gradle --daemon
![Page 57: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/57.jpg)
Gradle Wrapper
![Page 58: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/58.jpg)
Gradle Wrapper
![Page 59: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/59.jpg)
Gradle Wrappertask wrapper(type: Wrapper) { gradleVersion = '1.7'}
![Page 60: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/60.jpg)
Gradle Wrappertask wrapper(type: Wrapper) { gradleVersion = '1.7'} $ gradle wrapper
:wrapper!BUILD SUCCESSFUL!Total time: 5.071 secs!$ ls -l gradle/wrappertotal 112-rw-r--r-- 1 dgomezg staff 49875 Nov 20 16:53 gradle-wrapper.jar-rw-r--r-- 1 dgomezg staff 229 Nov 20 16:53 gradle-wrapper.properties$ ls gradle*gradle.properties gradlew gradlew.bat $ ./gradlew build:compileJava UP-TO-DATE:processResources UP-TO-DATE:classes UP-TO-DATE:war UP-TO-DATE:assemble UP-TO-DATE:compileTestJava UP-TO-DATE:processTestResources UP-TO-DATE:testClasses UP-TO-DATE:test UP-TO-DATE:check UP-TO-DATE:build UP-TO-DATE!BUILD SUCCESSFUL!Total time: 3.531 secs
![Page 61: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/61.jpg)
Convención flexibleSe pueden adaptar las convenciones de estructura de
proyecto
![Page 62: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/62.jpg)
Convención flexible
sourceSets { main { java { srcDirs = ['src'] } } test { java { srcDirs = ['test'] } }}buildDir = 'out'
Se pueden adaptar las convenciones de estructura de proyecto
![Page 63: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/63.jpg)
Convención flexible
sourceSets { main { java { srcDirs = ['src'] } } test { java { srcDirs = ['test'] } }}buildDir = 'out'
Se pueden adaptar las convenciones de estructura de proyecto
compileJava { source 'src/protobuf/java' source 'src/main/java'}
![Page 64: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/64.jpg)
ReutilizaciónLos archivos se pueden modularizar
![Page 65: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/65.jpg)
Reutilizaciónapply plugin: 'java'apply plugin: 'maven'apply plugin: 'eclipse'!group = 'com.autentia.dgomezg.sandbox'archivesBaseName = 'gradle-sample'!sourceCompatibility = 1.6!repositories { //mavenRepo name: 'nexus', url: 'http://terraka:8080/nexus/content/repositories/public' mavenCentral() mavenRepo name: 'spring-milestones', url: 'http://maven.springframework.org/milestone' mavenRepo name: 'java.net', url: 'http://download.java.net/maven/2/'}!dependencies { compile "org.springframework.security:spring-security-core:3.0.1.RELEASE", "org.springframework:spring-jdbc:3.0.0.RELEASE", "org.springframework:spring-tx:3.0.0.RELEASE" testCompile "junit:junit:4.5", "org.springframework:spring-test:3.0.0.RELEASE"}!
Los archivos se pueden modularizar
![Page 66: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/66.jpg)
Reutilizaciónapply plugin: 'java'apply plugin: 'maven'apply plugin: 'eclipse'!group = 'com.autentia.dgomezg.sandbox'archivesBaseName = 'gradle-sample'!sourceCompatibility = 1.6!repositories { //mavenRepo name: 'nexus', url: 'http://terraka:8080/nexus/content/repositories/public' mavenCentral() mavenRepo name: 'spring-milestones', url: 'http://maven.springframework.org/milestone' mavenRepo name: 'java.net', url: 'http://download.java.net/maven/2/'}!dependencies { compile "org.springframework.security:spring-security-core:3.0.1.RELEASE", "org.springframework:spring-jdbc:3.0.0.RELEASE", "org.springframework:spring-tx:3.0.0.RELEASE" testCompile "junit:junit:4.5", "org.springframework:spring-test:3.0.0.RELEASE"}!
Los archivos se pueden modularizarproject.gradle
![Page 67: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/67.jpg)
ReutilizaciónLos archivos se pueden importar
![Page 68: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/68.jpg)
Reutilizaciónapply plugin: 'java'apply plugin: 'maven'apply plugin: 'eclipse'!group = 'com.autentia.dgomezg.sandbox'archivesBaseName = 'gradle-sample'!sourceCompatibility = 1.6!repositories {}!dependencies {}
Los archivos se pueden importarproject.gradle
![Page 69: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/69.jpg)
Reutilizaciónapply plugin: 'java'apply plugin: 'maven'apply plugin: 'eclipse'!group = 'com.autentia.dgomezg.sandbox'archivesBaseName = 'gradle-sample'!sourceCompatibility = 1.6!repositories {}!dependencies {}
Los archivos se pueden importarproject.gradle
apply from: ‘../autentia-common/project.gradle’!dependencies { compile "com.google.guava:guava:r05", "org.apache.commons:commons-lang3:3.1", "org.slf4j:slf4j-api:1.6.1", "ch.qos.logback:logback-classic:0.9.24", "org.springframework:spring-aop:$springVersion", "org.springframework:spring-beans:$springVersion", "org.springframework:spring-context:$springVersion", "org.springframework:spring-core:$springVersion", "org.springframework:spring-web:$springVersion", "org.springframework.data:spring-data-mongodb:1.0.1.RELEASE", "org.mongodb:mongo-java-driver:2.7.1" testCompile "org.mockito:mockito-core:1.8.5"}
build.gradle
![Page 70: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/70.jpg)
ReutilizaciónLos archivos se pueden compartir
![Page 71: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/71.jpg)
ReutilizaciónLos archivos se pueden compartir
version=0.1.0-SNAPSHOTspringVersion=3.2.5.RELEASEsharedLocation=https://raw.github.com/autentia/common/#commitId of the version to be usedcommonComponentsVersion=c7e2110511112c5055e0aaaa7db953b35129a95b
gradle.properties
![Page 72: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/72.jpg)
ReutilizaciónLos archivos se pueden compartir
apply from: ‘$sharedLocation/$commonComponentsVersion/autentia-nexus.gradle’!dependencies { compile "com.google.guava:guava:r05", "org.apache.commons:commons-lang3:3.1", "org.slf4j:slf4j-api:1.6.1", "ch.qos.logback:logback-classic:0.9.24", "org.springframework:spring-aop:$springVersion", "org.springframework:spring-beans:$springVersion", "org.springframework:spring-context:$springVersion", "org.springframework:spring-core:$springVersion", "org.springframework:spring-web:$springVersion", "org.springframework.data:spring-data-mongodb:1.0.1.RELEASE", "org.mongodb:mongo-java-driver:2.7.1" testCompile "org.mockito:mockito-core:1.8.5"}
build.gradle
version=0.1.0-SNAPSHOTspringVersion=3.2.5.RELEASEsharedLocation=https://raw.github.com/autentia/common/#commitId of the version to be usedcommonComponentsVersion=c7e2110511112c5055e0aaaa7db953b35129a95b
gradle.properties
![Page 73: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/73.jpg)
ExtensibilidadPodemos ampliar la funcionalidad fácilmente
![Page 74: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/74.jpg)
ExtensibilidadPodemos ampliar la funcionalidad fácilmente
task deployJetty(dependsOn: assertJettyHome) << { new File("$jettyHome/contexts/${webappName}.xml").write ("""<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"><Configure class="org.mortbay.jetty.webapp.WebAppContext"> <Set name="contextPath">/${webappName}</Set> <Set name="resourceBase">${projectDir}/src/main/webapp</Set></Configure>""")}!task undeployJetty(dependsOn: assertJettyHome) << { ant.delete file: "$jettyHome/contexts/${webappName}.xml"}
jetty.gradle
![Page 75: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/75.jpg)
ExtensibilidadPodemos ampliar la funcionalidad fácilmente
apply from: ‘$sharedLocation/$commonComponentsVersion/jetty.gradle’!project.ext { webappName=gradle-sample jettyHome= System.getenv(“JETTY_HOME”);}…
build.gradle
task deployJetty(dependsOn: assertJettyHome) << { new File("$jettyHome/contexts/${webappName}.xml").write ("""<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"><Configure class="org.mortbay.jetty.webapp.WebAppContext"> <Set name="contextPath">/${webappName}</Set> <Set name="resourceBase">${projectDir}/src/main/webapp</Set></Configure>""")}!task undeployJetty(dependsOn: assertJettyHome) << { ant.delete file: "$jettyHome/contexts/${webappName}.xml"}
jetty.gradle
![Page 76: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/76.jpg)
‘Arquetipos’Hay un proyecto de plugin que procura cubrir ese hueco:
https://github.com/townsfolk/gradle-templates
!
![Page 77: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/77.jpg)
‘Arquetipos’Hay un proyecto de plugin que procura cubrir ese hueco:
https://github.com/townsfolk/gradle-templates
!apply from: 'http://www.tellurianring.com/projects/gradle-plugins/gradle-templates/1.3/apply.groovy'!…
![Page 78: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/78.jpg)
‘Arquetipos’Hay un proyecto de plugin que procura cubrir ese hueco:
https://github.com/townsfolk/gradle-templates
!apply from: 'http://www.tellurianring.com/projects/gradle-plugins/gradle-templates/1.3/apply.groovy'!…
$ gradle tasks!Template tasks--------------createGradlePlugin - Creates a new Gradle Plugin project in a new directory named after your project.createGroovyClass - Creates a new Groovy class in the current project.createGroovyProject - Creates a new Gradle Groovy project in a new directory named after your project.createJavaClass - Creates a new Java class in the current project.createJavaProject - Creates a new Gradle Java project in a new directory named after your project.createScalaClass - Creates a new Scala class in the current project.createScalaObject - Creates a new Scala object in the current project.createScalaProject - Creates a new Gradle Scala project in a new directory named after your project.createWebappProject - Creates a new Gradle Webapp project in a new directory named after your project.exportAllTemplates - Exports all the default template files into the current directory.exportGroovyTemplates - Exports the default groovy template files into the current directory.exportJavaTemplates - Exports the default java template files into the current directory.exportPluginTemplates - Exports the default plugin template files into the current directory.exportScalaTemplates - Exports the default scala template files into the current directory.exportWebappTemplates - Exports the default webapp template files into the current directory.initGradlePlugin - Initializes a new Gradle Plugin project in the current directory.initGroovyProject - Initializes a new Gradle Groovy project in the current directory.initJavaProject - Initializes a new Gradle Java project in the current directory.initScalaProject - Initializes a new Gradle Scala project in the current directory.initWebappProject - Initializes a new Gradle Webapp project in the current directory.
![Page 79: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/79.jpg)
Y mucho más• Posibilidad de ejecutar gradle como demonio
• Toda la potencia de un lenguaje para los scripts
• Integración con sistemas de Integración Continua
• Jenkins
• ClinkerHQ
• Consola
![Page 80: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/80.jpg)
apply plugin: ‘android’
• Build variants
• local, remote & Module dependencies
• Manifest entries
• APK Sign
• ProGuard
• Testing
![Page 81: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/81.jpg)
Configuracion android
![Page 82: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/82.jpg)
Configuracion android
android { compileSdkVersion 20 buildToolsVersion "20.0.0"! defaultConfig { applicationId "com.autentia.dgomezg.sandbox.android.app" minSdkVersion 8 targetSdkVersion 8 versionCode 1 versionName "1.0" }}
![Page 83: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/83.jpg)
Dependencias
![Page 84: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/84.jpg)
Dependencias• Librerías en repositorio Maven (librerías remotas)
dependencies { compile 'com.android.support:appcompat-v7:19.0.1'}
![Page 85: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/85.jpg)
Dependencias• Librerías en repositorio Maven (librerías remotas)
dependencies { compile 'com.android.support:appcompat-v7:19.0.1'}
• Dependencia con otros módulosdependencies { compile project(":lib")}
![Page 86: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/86.jpg)
Dependencias
dependencies { // Local binary dependency compile fileTree(dir: 'libs', include: ['*.jar'])}
• Librerías en repositorio Maven (librerías remotas)dependencies { compile 'com.android.support:appcompat-v7:19.0.1'}
• Dependencia con otros módulosdependencies { compile project(":lib")}
• Dependencia con librerías locales
![Page 87: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/87.jpg)
Firma de distribución• A partir de la release key
![Page 88: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/88.jpg)
Firma de distribución• A partir de la release key
android { signingConfigs { release { storeFile file("myreleasekey.keystore") storePassword "password" keyAlias "MyReleaseKey" keyPassword "password" } } buildTypes { release { signingConfig signingConfigs.release } }}
![Page 89: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/89.jpg)
Firma de distribución• A partir de la release key
android { signingConfigs { release { storeFile file("myreleasekey.keystore") storePassword "password" keyAlias "MyReleaseKey" keyPassword "password" } } buildTypes { release { signingConfig signingConfigs.release } }}
storePassword System.getenv("KSTOREPWD")keyPassword System.getenv("KEYPWD")
![Page 90: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/90.jpg)
Firma de distribución• A partir de la release key
android { signingConfigs { release { storeFile file("myreleasekey.keystore") storePassword "password" keyAlias "MyReleaseKey" keyPassword "password" } } buildTypes { release { signingConfig signingConfigs.release } }}
storePassword System.getenv("KSTOREPWD")keyPassword System.getenv("KEYPWD")
storePassword System.console().readLine("\nKeystore password: ")keyPassword System.console().readLIne("\nKey password: ")
![Page 91: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/91.jpg)
Build variants• Permite sacar distintos desplegables desde el mismo proyecto, basado en combinación de
• BuildType
• Build Flavor
• 2 BuildTypes por defecto
• Debug
• release
![Page 92: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/92.jpg)
Build flavours• Configura los ‘flavors’ (necesita carpetas distintas en /src/)
![Page 93: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/93.jpg)
Build flavours• Configura los ‘flavors’ (necesita carpetas distintas en /src/)
android {! productFlavors { demo { applicationId “com.autentia.dgomezg.sandbox.android.app.demo” versionName "0.1-demo" } full { applicationId “com.autentia.dgomezg.sandbox.android.app.full" versionName “0.1-full" } }}
![Page 94: Construccion de proyectos con gradle](https://reader031.vdocuments.site/reader031/viewer/2022020105/547e8b03b47959c5508b4b6c/html5/thumbnails/94.jpg)
Conclusiones• No más XML Oriented Programming
• Concisión y legibilidad
• Toda la potencia de las convenciones de maven
• Integración con Ant
• Gestor de dependencias
• Flexibilidad de un lenguaje de programación
• Modularización y reutilización