20091020 - Normandy Jug - Builders Battle

Post on 22-Jan-2015

3.070 views 2 download

description

Présentation au NormandyJUG le 20 oct. 2009 Builders Battle - Ant, Ivy, Gradle, EasyAnt, Maven

Transcript of 20091020 - Normandy Jug - Builders Battle

NormandyJUG20 octobre 2009

Builders Battle Maven / Ivy / Ant / Gradle / EasyAnt ...

Grégory Boissinot

• Committer Hudson depuis 2008

• Consultant Zenika– Spécialiste sur les outils de build et

l'intégration continue– Formateur sur l'usine logicielle– A mis en place Gradle chez un grand

acteur de l'industrie

Jean-Louis Boudart• Leader d’EasyAnt

• Commiter Hudson

• Consultant indépendant– Spécialiste sur les outils de build et d’intégration

continue

Xavier Hanin• Createur d’Apache Ivy

• Architecte Principal 4SH

Arnaud Héritier

• eXo Platform - http://www.exoplatform.com– Software Factory Manager

• Qualité• Outillage• Productivité des développements

• Committer depuis 2004 et membre du PMC

• Co-auteur « Apache Maven » aux éditions Pearson (FR)

Programme• Un peu d’archéologie

• Les protagonistes– Apache Maven– Apache Ivy– EasyAnt– Gradle

• Le combat final

• Questions / Réponses

UN PEU D’ARCHÉOLOGIERetour au début du siècle

Construction d’un war en 2002• Utilisation d’Eclipse limitée

– Pas de WTP (uniquement dans la version payante d’IBM),

– Eclipse ne permettait pas d’exporter des Wars

Construction d’un war en 2002• Beaucoup de tâches manuelles

– Modifier les fichiers de paramétrage– Exporter les différents jar– Copier les dépendances (et nos jars), dans un

répertoire lib– Faire un zip que l’on renomme en war– Tagguer l’ensemble des sources dans le répertoire de

sources (CVS)– Envoyer le fichier par FTP sur le serveur

d’intégration– Se connecter à la console d’administration du serveur

et déployer l’application

Construction d’un war en 2002• Un seul problème,

Y’a toujours des problèmes– Erreur dans la

configuration– Oubli d’une dépendance– oubli d’un fichier– Correction de dernière minute qui

introduit une régression…– Autres

• Combien de temps ça prend ?– Quand tout va bien : 15

minutes

– Quand il y a des problèmes : ½ journée

APACHE MAVENBuilders Battle

Une première réponse : ANT• Ecriture d’un script

– Permet d’automatiser le process– Durée du processus réduite de moitié– Le processus ne monopolise personne

• On le lance et on passe à autre chose

Les limites de ANT• Ecrire le script, c’est long• Modifier un script, c’est

très long• Au final, le gains de

temps n’est pas évident– Mais c’est quand même

plus amusant

– Il est possible de réutiliser le script !

La réutilisation de scripts ANT• Les scripts ne sont pas directement réutilisables

– Structure de projets différents– Besoins différents

• Encore du temps perdu– Modification du script– Réécriture pour le rendre plus générique

• Un nouveau métier s’est créé dans chaque projet : scripteur ANT

Quelques exemples• Junit : http://junit.cvs.sourceforge.net/viewvc/junit/junit/build.xml?view=markup

• Findbugs : http://findbugs.googlecode.com/svn/trunk/findbugs/build.xml

• Jboss SEAM : http://anonsvn.jboss.org/repos/seam/branches/community/Seam_2_0

LES INTÉRÊTS POUR UN PROJETApache Maven

Maven, le choix Projet• Le projet peut-être librement découpé en

modules– Maven ne cristallise pas l’architecture de

l’application

• Gestion des dépendances– Déclaratif : Gestion automatique du téléchargement et

de l’utilisation dans le projet.– Transitivité : On ne déclare que ce que l’on utilise

Maven, le choix Projet• Centralise et automatise

les différents aspects du développement de logiciels

• Une seule chose qu’il ne peut faire à votre place : Développer

– Construction

– Tests

– Packaging

– Déploiement

– Documentation

– Contrôles et rapports sur la qualité des développements

LES INTÉRÊTS POUR UNE ENTREPRISE

Apache Maven

Maven, le choix Entreprise• Standard du marché

– Disponibilité des ressources

• Standardisation des développements– Organisation des sources– Descripteur de projet

Maven, le choix Entreprise• Rationnaliser les coûts

– On ne réinvente pas la roue à chaque nouveau projet– Factorisation entre projets

• Promotion de la qualité et intégration de l’outillage associé

APACHE IVYBuilders Battle

1/2

Qu'est ce qu'Apache Ivy• Un gestionnaire de dépendances

– Resolving / Publishing / Reporting

• Peut être utiliser en tant que – Plugin Ant– Librairie (Gradle, IDE Integration...)– Depuis la ligne de commande

1/2

Features

• Flexible et configurable

• Supporte les dépendances transitive

• Assurer la reproductibilité d'un build

• Robuste et documenté

1/2

Features• Gestionnaire de conflits

• Intégration avec Ant

• Comptabilité avec les dépôts maven

• Support de gros graphes de dépendances

1/2

Comparatif Ivy / Maven POM<ivy-module version="2.0"> <info organisation="org.jug.normandyjug" module="hello-ivy"/> <dependencies> <dependency org="commons-lang" name="commons-lang"

rev="2.0"/> <dependency org="commons-cli" name="commons-cli" rev="1.0"/> </dependencies></ivy-module>…<dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.0</version></dependency>

1/2

L'esprit d'Ivy : La flexibilité !

• Adaptable à votre environnement selon vos besoin

• Configurable et facilement intégrable

• Large choix de repository (FTP, SSH, HTTP, iBiblio, etc...)

• Nombreuses taches ant

1/2

L'esprit d'Ivy : La flexibilité !• Definir son propre parser

• Rajouter des extra attributes

• Personnaliser son versionning– Définir ses propres contraites de version (Alpha,

Beta, RC, etc...)– Définir quel version est plus récente qu'une autre

• Gestion de conflits

• Cache (metadata, artifact)

• Triggers

EASYANTBuilders Battle

1/2

Qu’est ce qu'EasyAnt ?• Build system basé sur des standard (Ant + Ivy)

• Open Source (Apache Software Foundation)

• Architecture extensible à base de Plugins

• Conventions

• Simple, Flexible, Extensible

1/2

Objectif ?

• Gérer le cycle de vie de nos applications

• Industrialiser les développement– Ne pas réinventer la roue a chaque foi– Factoriser les ressources inter projet– Organisation des sources

• Gestion des dépendances

• Promouvoir la qualité et l'intégration

• Rester souple et adaptable

• Etre OpenSource!!

1/2

Plugins éxistant

• Compilation : Java, Scala, Groovy

• Packaging : Jar, War, OSGi

• Test : Junit, TestNG

• Couverture de code : Emma, Cobertura(*)

• SCM : SVN

• Divers: Checkstyle, Javadoc, Jetty, etc...

• Documentation : DocBook, Xooki

• Build types (Java standard, Java Web, Scala, etc...)

1/2

Features• Gestion du cycle de vie

• Gestion multi-modules

• Gestion de dépendances– Resolution– Reporting– Publication

• Gestion de squelettes de projets

• Phases

• Build-configurations

• Documentation des plugins auto-générée

1/2

Contribution connexes• Apache Ant

– Phase– Import / Include– Abstraction du format d'entrée

• Apache Ivy– Introduction d'un mécanisme d'héritage de méta

donnée

• Apache IvyDE

• Beet (http://beet.sourceforge.net/)– Utilisation d'EasyAnt en tant que build-system

1/2

Prochaines versions• Abstraction de langage pour les plugins (XML,

Java, Groovy?)

• Simplifier le développement de plugin

• Gestion de projet eclipse

• Gestion de projet android

• EasyAnt4e

• Hudson

1/2

EasyAnt4e : intégration dans eclipse

• Création / import de nouveau projet EasyAnt

• Completion de code :– Les tags du descripteur de modules– Les plugins– Property

• Classpath dynamique

• Visualisation / Execution des targets

GRADLEBuilders Battle

Gradle en quelque mots• Système de build complet et flexible à la Ant• Utilisation des conventions de Maven à la

demande• Une gestion multi projet avancée• Utilisation de Apache Ivy comme gestionnaire de• dépendances

– Utilisation par API

• Support et Insertion totale dans une infrastructure• Maven et Ivy existante• Chaîne de build en Groovy• Modèle de description du build très riche

Architecture

CORE UI DOCSOPEN-APIWRAPPER

api

project-reports

code-qualitygroovyjava maven osgi

war jetty scala eclipseplugins

build tools

Ant Ivy Maven Ant Tasks

checkstyle codeNarc webdav other dependencies

librairies tierces

Gradle

Groovy

Notion de tâche• Un script de build Gradle est défini par un ensemble de

tâches sur lesquelle est ajouté des actions qui sont des closures Groovy

<!-- build.gradle -->task distribution <<{ println "Distribution"}

task release (dependsOn: 'distribution')<<{ println "Release"}

<!-- build.gradle -->task distribution <<{ println "Distribution"}

task release (dependsOn: 'distribution')<<{ println "Release"}

> gradle distributionDistribution

> gradle distributionDistribution

> gradle releaseDistributionRelease

> gradle releaseDistributionRelease

Tâche simple

Accès à l'APIJava

Les tâches ont une API

Copy myCopy = task(myCopy, type:Copy)myCopy.from(file('resources'))myCopy.into(file('target'))myCopy.include('**/*.txt', '**/*.xml')

Copy myCopy = task(myCopy, type:Copy)myCopy.from(file('resources'))myCopy.into(file('target'))myCopy.include('**/*.txt', '**/*.xml')

task mycopy (type:Copy)

mycopy{ description ='Copies the resources dir' from(file('resources')) into(file('target')) include('**/*.txt', '**/*.xml')}

task mycopy (type:Copy)

mycopy{ description ='Copies the resources dir' from(file('resources')) into(file('target')) include('**/*.txt', '**/*.xml')}

task mycopy (type:Copy){ description ='Copies the resources dir' from(file('resources')) into(file('target')) include('**/*.txt', '**/*.xml')}

task mycopy (type:Copy){ description ='Copies the resources dir' from(file('resources')) into(file('target')) include('**/*.txt', '**/*.xml')}

Tâche améliorée

CustomTask

Copy

mycopy

Une API très riche

task source(type:Jar){ baseName='source' from sourceSets.main.java}

task source(type:Jar){ baseName='source' from sourceSets.main.java}

task distrib(type:Zip){ dependsOn(jar) baseName='dist' from sourceSets.main.java from jar.archivePath }

task distrib(type:Zip){ dependsOn(jar) baseName='dist' from sourceSets.main.java from jar.archivePath }

CustomTask

AbstractArchiveTask

Zip

Jar

War

Tar

SourceTask

task javadoc(type: Javadoc) { source sourceSets.main.allJava}

task javadoc(type: Javadoc) { source sourceSets.main.allJava}

Javadoc

Plusieurs tâches par défaut

<!-- build.xml --><project default="all">

<target name="clean"> <echo message="Cleaning"/></target>

<target name="jar"> <echo message="Packaging"/></target>

<target name="all"> <antcall target="clean"/> <antcall target="jar"/></target>

</project>

<!-- build.xml --><project default="all">

<target name="clean"> <echo message="Cleaning"/></target>

<target name="jar"> <echo message="Packaging"/></target>

<target name="all"> <antcall target="clean"/> <antcall target="jar"/></target>

</project>

<!-- build.gradle -->defaultTasks 'clean',

'jar'

task clean << { println "Cleaning"}

task jar << { println "Packaging"}

<!-- build.gradle -->defaultTasks 'clean',

'jar'

task clean << { println "Cleaning"}

task jar << { println "Packaging"}

> antCleaningPackaging

> antCleaningPackaging

> gradleCleaningPackaging

> gradleCleaningPackaging

Exécution unique et ordonnée

compilecompileTest test

dist

> ant test distcompilecompileTesttestcompilecompileTesttestdist

> ant test distcompilecompileTesttestcompilecompileTesttestdist

> gradle test dist:compile:compileTest:test:dist

> gradle test dist:compile:compileTest:test:dist

Pour un projet Java/JEE

CORE UI DOCSOPEN-APIWRAPPER

api

project-reports

code-qualitygroovyjava maven osgi

war jetty scala eclipseplugins

build tools

Ant Ivy Maven Ant Tasks

checkstyle codeNarc webdav other dependencies

librairies tierces

Gradle

Groovy

Build d'une librairie

<!-- build.gradle -->usePlugin 'java'

archivesBaseName = 'core'version = '3.5' manifest.mainAttributes( 'Implementation-Version': version)

repositories { mavenCentral()}dependencies { compile group: 'commons-collections', name: 'commons-collections',

version: '3.2' testCompile group: 'junit',

name: 'junit', version: '4.+'

}

<!-- build.gradle -->usePlugin 'java'

archivesBaseName = 'core'version = '3.5' manifest.mainAttributes( 'Implementation-Version': version)

repositories { mavenCentral()}dependencies { compile group: 'commons-collections', name: 'commons-collections',

version: '3.2' testCompile group: 'junit',

name: 'junit', version: '4.+'

}

> gradle compileJava> gradle jar

> gradle compileJava> gradle jar

core-3.5.jar

Gradle

jar

Configurationaccessible sous forme

de propriétés

Build d'une webapp

<!-- build.gradle -->usePlugin 'war'usePlugin 'jetty'archivesBaseName = 'web'version = '1.0'

repositories { mavenCentral()}

dependencies { compile "commons-io:commons-io:1.4" compile ("log4j:log4j:1.2.15"){ exclude(group:'javax.jms') exclude(group:'com.sun.jdmk') exclude(module:'jmxri') }}

<!-- build.gradle -->usePlugin 'war'usePlugin 'jetty'archivesBaseName = 'web'version = '1.0'

repositories { mavenCentral()}

dependencies { compile "commons-io:commons-io:1.4" compile ("log4j:log4j:1.2.15"){ exclude(group:'javax.jms') exclude(group:'com.sun.jdmk') exclude(module:'jmxri') }}

> gradle war> gradle jettyRun

> gradle war> gradle jettyRun

WEB-INFoptionel

JEE6 compatible

web-2.4.war

Gradle

war

Phases de build• Gradle fournit 3 phases distinctes de build• Initialisation

– Détermine l'ensemble des projets à builder

– Création d'un objet Projet pour chaque module

• Configuration– Configuration des objets Project

• Exécution– Exécution des tâches crées et configurés précédemment

gradle.taskGraph.whenReady {taskGraph -> if (taskGraph.hasTask(':release')) { version = '1.0' } else { version = '1.0-SNAPSHOT' }}

gradle.taskGraph.whenReady {taskGraph -> if (taskGraph.hasTask(':release')) { version = '1.0' } else { version = '1.0-SNAPSHOT' }}

Nombreux hooks

disponibles

Intégration native avec Ant

CORE UI DOCSOPEN-APIWRAPPER

api

project-reports

code-qualitygroovyjava maven osgi

war jetty scala eclipseplugins

build tools

Ant Ivy Maven Ant Tasks

checkstyle codeNarc webdav other dependencies

librairies tierces

Gradle

Groovy

Utilisation possible des tâches Ant

<!-- build.gradle -->task generateStub << { ant { def wsdl2java_classpath = path { fileset(dir: 'lib') { include(name: '*.jar') } } taskdef( name: 'axisWsdl2java', classname: 'org.apache.axis.tools.ant.wsdl.Wsdl2javaAntTask', classpath: wsdl2java_classpath )

axisWsdl2java( output:"generated", verbose:"true" , url:"Exemple.wsdl") }}

<!-- build.gradle -->task generateStub << { ant { def wsdl2java_classpath = path { fileset(dir: 'lib') { include(name: '*.jar') } } taskdef( name: 'axisWsdl2java', classname: 'org.apache.axis.tools.ant.wsdl.Wsdl2javaAntTask', classpath: wsdl2java_classpath )

axisWsdl2java( output:"generated", verbose:"true" , url:"Exemple.wsdl") }}

Utilisation de l'objetGroovy AntBuilder

LES INTÉRÊTS POUR UNE ENTREPRISE

Gradle

Gradle, un choix pertinent en Entreprise

• Utiliser Gradle en lieu et place de vos scripts Ant– Réutilisation (Import) de scripts Ant existant– Utilisation de toute tâche native

• Utiliser Gradle avec votre infrastructure Ivy– Intégration plus profonde et plus riche

• Utiliser Gradle avec votre infrastructure Maven• existante

– Les même conventions que Maven– Simplicité de gestion des dépendances Maven– Flexibilité au besoin

LES PROBLEMESGradle

Les problèmes

• Ce qui manque– Gestion d'un ear pour JEE– Génération de la configuration IDEA et NetBeans– Intégration avec les outils de couvertures de code ou

d'autres outils de métriques (Findbugs, …)• Délégation à des tâches Ant aujourd'hui

• Un manque de maturité– Changement de la DSL entre chaque release

LE COMBAT FINALIl n’en restera plus qu’un … ou pas

LES DOCUMENTATIONS DOCUMENTATIONS ?

Apache Maven

Quelques liens• Le site web :

– http://maven.apache.org

• Le wiki projet : – http://docs.codehaus.org/display/MAVEN

• Le wiki utilisateurs : – http://docs.codehaus.org/display/MAVENUSER

Ouvrages• Sonatype / O’Reilly :

– The Definitive Guide

– http://www.sonatype.com/books

– Gratuit en version électronique

– D’ici la fin de l’année (?) en français

Ouvrages• Exist Global

– Better builds with Maven

– http://www.maestrodev.com/better-build-maven

– Gratuit

– Version électronique uniquement

Ouvrages• Nicolas De loof – Arnaud

Héritier – Aux éditions Pearson

– Collection Référence

– Un ouvrage original condensé de retours d’expériences

– En français

– Disponible le 20 Novembre

Support• Listes de diffusion

– http://maven.apache.org/mail-lists.html

• IRC– irc.codehaus.org - #maven

• Developpez.net– http://www.developpez.net/ forum maven– En français

• Contrats de support– Sonatype et quelques autres entreprises

DOCUMENTATIONSEasyAnt

1/2

Documentations / Contact• Le site web :

– http://www.easyant.org/

• La documentation :– http://www.easyant.org/doc/

• La mailing list :– http://groups.google.com/group/easyant/

• IRC:– irc.freenode.net - #easyant

LES DOCUMENTATIONS ?Gradle

Quelques liens

• Le site web :– http://www.gradle.org/

• Un user guide– http://www.gradle.org/0.8/docs/userguide/

userguide.html – http://www.gradle.org/0.8/docs/userguide/

userguide.pdf

• Un cookbook– http://docs.codehaus.org/display/GRADLE/

Cookbook

• Le wiki projet : – http://docs.codehaus.org/display/GRADLE/Home

Support

• Liste de diffusion– http://www.gradle.org/lists.html

• Support commercial– http://www.gradle.biz/

LA COMMUNAUTÉApache Maven

La communauté des utilisateurs

• 1780 inscrits sur la liste de diffusion des utilisateurs

• Statistiques sur 90 jours

• En bleu le nombre d’inscrits

• En rouge le nombre de messages par jours

Le site web

Les téléchargements

• Nombre de téléchargements par mois depuis un an

L’équipe projet• Près de 60 committeurs enregistrés,

• Plus de 20 actifs depuis le début de l’année,

• Des entreprises comme Sonatype ou MaestroDev fournissent des ressources pour le projet et du support professionnel pour les utilisateurs,

• Une communauté de développeurs moins isolée : rapprochements avec Eclipse, Jetty, …

LA COMMUNAUTÉEasyAnt

1/2

Vie du projet

• 1 ans d'existence

• 6 développeur enregistrés

• 3 développeur actif

• Constante évolution

• Un produit loin d’être « parfait »,

• Encore beaucoup de choses à faire– Aidez nous à le faire évoluer

LA COMMUNAUTÉGradle

La communauté des utilisateurs

• Les utilisateurs Groovy

L'équipe projet

• 6 committeurs enregistrés

• L'entreprise « Gradle inc » soutient le projet

• De nouvelles contributions arrivent

SOUS LE CAPOTDiesel ou essence ?

Gradle fournit des cycles de vies (1/2)

• Ensemble de tâches prédéfinies

Exemple du plugin 'java'

Des conventions de répertoires• Gradle utilise par défaut

les mêmes conventions de répertoires que Maven

<!-- répertoires -->+build.gradle+src/main/java+src/main/resources+src/main/webapp+src/test/java+src/test/resources

+build/classes+build/libs+build/reports+build/test-results

<!-- répertoires -->+build.gradle+src/main/java+src/main/resources+src/main/webapp+src/test/java+src/test/resources

+build/classes+build/libs+build/reports+build/test-results

<!-- build.gradle -->sourceSets{ main{ java { srcDir 'src/java' } resources { srcDir 'src/resources' } } main{ java { srcDir 'src2/java' } resources { srcDir 'src2/resources' } }}

<!-- build.gradle -->sourceSets{ main{ java { srcDir 'src/java' } resources { srcDir 'src/resources' } } main{ java { srcDir 'src2/java' } resources { srcDir 'src2/resources' } }}

Trèsconfigurable

Séparation propre

Gestion des dépendances avec Ivy

CORE UI DOCSOPEN-APIWRAPPER

api

project-reports

code-qualitygroovyjava maven osgi

war jetty scala eclipseplugins

build tools

Ant Ivy Maven Ant Tasks

checkstyle codeNarc webdav other dependencies

librairies tierces

Gradle

Groovy

Gestion des dépendances• Support complet de

repository Maven ou Ivy existant

• Interaction possible avec un gestionnaire de configuration– Gestion des dépendances

transitives (client module)

Gradle

VCS

RepositoryMaven

local/distant

RepositoryIvy

local/distant

Artifacts + méta Maven

(pom.xml)

Artifacts + méta Ivy (ivy.xml)

Artifacts +méta gradle

Ivy

Définition des repositories

repositories { mavenCentral() mavenRepo urls:"http://serveur/archiva/repo-group"}

repositories { mavenCentral() mavenRepo urls:"http://serveur/archiva/repo-group"}

repositories {flatDir name: 'localRepository', dirs: 'lib'

}

repositories {flatDir name: 'localRepository', dirs: 'lib'

}

repositories {add( new org.apache.ivy.plugins.resolver.FileSystemResolver()){ name = 'repo' addArtifactPattern "$projectDir/lib/[module]_[revision].[ext]" descriptor = 'optional' checkmodified = true }}

repositories {add( new org.apache.ivy.plugins.resolver.FileSystemResolver()){ name = 'repo' addArtifactPattern "$projectDir/lib/[module]_[revision].[ext]" descriptor = 'optional' checkmodified = true }}

Déclaration des dépendances• Dépendances vers des modules (+deps)dependencies { compile "log4j:log4j:1.2.14" testCompile "junit:junit:4.7"}

dependencies { compile "log4j:log4j:1.2.14" testCompile "junit:junit:4.7"}

• Dépendances vers des artefacts (-deps)dependencies { runtime "org.groovy:groovy:1.5.6@jar"}

dependencies { runtime "org.groovy:groovy:1.5.6@jar"}

• Client modulesdependencies { runtime module("commons-lang:commons-lang:2.4") { dependency("commons-io:commons-io:1.2") }}

dependencies { runtime module("commons-lang:commons-lang:2.4") { dependency("commons-io:commons-io:1.2") }}

Dépendancestransitives sans XML

<!-- build.xml --><property name="src.dir" value="src"><target name="compile"> <echo message="Compile,from Ant"/></target>

<!-- build.xml --><property name="src.dir" value="src"><target name="compile"> <echo message="Compile,from Ant"/></target>

<!-- build.gradle -->ant.importBuild 'build.xml'

//Complément de la tâche compilecompile << { println "Added compiling from Gradle" println "SourceDir: ${ant.properties['src.dir']}"}

<!-- build.gradle -->ant.importBuild 'build.xml'

//Complément de la tâche compilecompile << { println "Added compiling from Gradle" println "SourceDir: ${ant.properties['src.dir']}"}

> gradle compile:compile[ant:echo] Compile, from AntAdded compiling from GradleSourceDir: src

> gradle compile:compile[ant:echo] Compile, from AntAdded compiling from GradleSourceDir: src

Gradle et Ant: dans les deux sens (1/2)

Gradle et Ant: dans les deux sens (2/2)

<!-- build.xml --><target name="deploy" depends="assemble"> <echo message="Deploy, from Ant"/></target>

<!-- build.xml --><target name="deploy" depends="assemble"> <echo message="Deploy, from Ant"/></target>

<!-- build.gradle -->task assemble (dependsOn: 'compile') << { println 'Assemble, from Gradle'}

<!-- build.gradle -->task assemble (dependsOn: 'compile') << { println 'Assemble, from Gradle'}

> gradle deploy:compile[ant:echo] Compile, from AntAdded compiling from Gradle:assembleAssemble, from Gradle:deploy[ant:echo] Deploy, from Ant

> gradle deploy:compile[ant:echo] Compile, from AntAdded compiling from Gradle:assembleAssemble, from Gradle:deploy[ant:echo] Deploy, from Ant

Gestion multi projet très avancée

CORE UI DOCSOPEN-APIWRAPPER

api

project-reports

code-qualitygroovyjava maven osgi

war jetty scala eclipseplugins

build tools

Ant Ivy Maven Ant Tasks

checkstyle codeNarc webdav other dependencies

librairies tierces

Gradle

Groovy

Gestion multi projet (1/3)

• Les descripteurs dans les sous modules sont optionnels

• Injection de configuration• Possibilité de mettre toute

la logique de build dans le parent

<!-- Structure de répertoires -->+build.gradle+settings.gradle+common/+pz/ +build.gradle-biz/ - biz-auth/

<!-- Structure de répertoires -->+build.gradle+settings.gradle+common/+pz/ +build.gradle-biz/ - biz-auth/

common

biz-auth pz

depends depends

war war

jar

<!-- settings.gradle -->include "common","pz","biz:auth"

<!-- settings.gradle -->include "common","pz","biz:auth"

Gestion multi projet (2/3)

<!-- master build.gradle -->subprojects{ usePlugin('java') group='org.jug.normandyjug' version='1.0'

repositories{ mavenCentral() } dependencies { testCompile 'junit:junit:4.7' }}project(':biz:biz-auth'){ dependencies{ compile project(':common') } usePlugin 'war'}

<!-- master build.gradle -->subprojects{ usePlugin('java') group='org.jug.normandyjug' version='1.0'

repositories{ mavenCentral() } dependencies { testCompile 'junit:junit:4.7' }}project(':biz:biz-auth'){ dependencies{ compile project(':common') } usePlugin 'war'}

<!-- pz/build.gradle -->usePlugin 'war'

dependencies{ compile project(':common')}

<!-- pz/build.gradle -->usePlugin 'war'

dependencies{ compile project(':common')}

cross project configuration

Gestion multi projet (3/3)

/web> gradle compileJava:common:compileJava:common:processResources:common:classes:common:jar:common:uploadDefaultInternal:pz:compileJava:biz:biz-auth:compileJava

/web> gradle compileJava:common:compileJava:common:processResources:common:classes:common:jar:common:uploadDefaultInternal:pz:compileJava:biz:biz-auth:compileJava

/web/biz/biz-auth> gradle compileJava:common:compileJava:common:processResources:common:classes:common:jar:common:uploadDefaultInternal:biz:biz-auth:compileJava

/web/biz/biz-auth> gradle compileJava:common:compileJava:common:processResources:common:classes:common:jar:common:uploadDefaultInternal:biz:biz-auth:compileJava

/web/biz/biz-auth> gradle compileJava -a:biz:biz-auth:compileJava

/web/biz/biz-auth> gradle compileJava -a:biz:biz-auth:compileJava

Compilation des projets dépendants

Utilisation des jars

dans le cache

Gradle GUI• Lancé par • > gradle –gui

• Exécution de tâches

• Paramétrage du niveau de log

Publie dans une infra Maven et Ivy

CORE UI DOCSOPEN-APIWRAPPER

api

project-reports

code-qualitygroovyjava maven osgi

war jetty scala eclipseplugins

build tools

Ant Ivy Maven Ant Tasks

checkstyle codeNarc webdav other dependencies

librairies tierces

Gradle

Groovy

Publication dans des repo Ivy

usePlugin 'java'version='1.0'

uploadArchives{ repositories{ flatDir(dirs:'destRepo') }}

usePlugin 'java'version='1.0'

uploadArchives{ repositories{ flatDir(dirs:'destRepo') }}

IVY API

Gradle RepositoryIvy

Artifacts + meta Ivy

> gradle uploadArchives> gradle uploadArchives

upload

Archives

Publication dans des repo Maven

usePlugin 'java'usePlugin 'maven'

group='org.jug.normandyjug'archivesBaseName='artefact-ex'version='1.0-SNAPSHOT'

uploadArchives { repositories.mavenDeployer { snapshotRepository(url: "http://serveur/archiva/repository/snapshots") }

usePlugin 'java'usePlugin 'maven'

group='org.jug.normandyjug'archivesBaseName='artefact-ex'version='1.0-SNAPSHOT'

uploadArchives { repositories.mavenDeployer { snapshotRepository(url: "http://serveur/archiva/repository/snapshots") }

> gradle install> gradle uploadArchives

> gradle install> gradle uploadArchives

Repository

Maven local

RepositoryMaven distant

MavenAntTasks

Gradle

Artifacts + meta Maven

Artifacts + meta Maven

install

upload

Archives

Production de plusieurs artefacts• Une librairie/module peut avoir plusieurs artefacts

<!-- sample/build.xml -->usePlugin 'java'

task sourceJar(type: Jar) task distrib(type: Zip)

artifacts{ archives sourceJar, distrib}

repositories{ flatDir name:'repo', dirs:'repo'}uploadArchives { repositories { add project.repositories.repo }}

<!-- sample/build.xml -->usePlugin 'java'

task sourceJar(type: Jar) task distrib(type: Zip)

artifacts{ archives sourceJar, distrib}

repositories{ flatDir name:'repo', dirs:'repo'}uploadArchives { repositories { add project.repositories.repo }}

> gradle uploadArchives> gradle uploadArchives

ivy.xml

Gradle

upload

Archives

RepositoryIvy

dist-1.0.zip

sample-1.0.jar

source-1.0.jar

Gestion simplifié des configurations

usePlugin 'java'configurations{ sources master { extendsFrom archives, sources }}artifacts{ sources sourceJar master distrib}uploadArchives{ repositories{ flatDir(dirs: file('repos'), name:'destRepo') }}uploadSources{ repositories{ add project.uploadArchives.repositories.destRepo } }uploadMaster.repositories=uploadSources.repositories

usePlugin 'java'configurations{ sources master { extendsFrom archives, sources }}artifacts{ sources sourceJar master distrib}uploadArchives{ repositories{ flatDir(dirs: file('repos'), name:'destRepo') }}uploadSources{ repositories{ add project.uploadArchives.repositories.destRepo } }uploadMaster.repositories=uploadSources.repositories

Ajout automatique de

build[ConfigurationName] et

upload[ConfigurationName]

Agir simplement sur le cycle de vie

• Un cycle de vie Gradle est composé d'un ensemble

• de tâches– Chaque tâche est une propriété du projet– Chaque tâche possède une propriété « enabled »

compileTestJava.enabled=falseprocessTestResources.enabled=falsetestClasses.enabled=falsetest.enabled=false

compileTestJava.enabled=falseprocessTestResources.enabled=falsetestClasses.enabled=falsetest.enabled=false

Portée des dépendances (1/2)

<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2;14</version></dependency><dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.0</version> <scope>provided</scope></dependency><dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.2</version></dependency>

<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2;14</version></dependency><dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.0</version> <scope>provided</scope></dependency><dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.2</version></dependency>

<!-- Contenu de l'archive -->WEB-INF/lib- log4j-1.2.14.jar- commons-codec-1.2jar

<!-- Contenu de l'archive -->WEB-INF/lib- log4j-1.2.14.jar- commons-codec-1.2jar

commons-httpclient

Common-codec

Portée des dépendances (2/2)

• Le plugin 'war' fournit les scopes 'providedCompile' et 'providedRuntime'

<build.gradle -->dependencies { compile "log4j:log4j:1.2.14" providedCompile "commons-httpclient:commons-httpclient:3.0" compile "commons-codec:commons-codec:1.2"}

<build.gradle -->dependencies { compile "log4j:log4j:1.2.14" providedCompile "commons-httpclient:commons-httpclient:3.0" compile "commons-codec:commons-codec:1.2"}

<!-- Contenu de l'archive -->WEB-INF/lib- log4j-1.2.14.jar

<!-- Contenu de l'archive -->WEB-INF/lib- log4j-1.2.14.jar

Questions ?

99

Licence et droits d’auteurs• Les photos et logos appartiennent à leurs auteurs

respectifs

• Le contenu de la présentation est sous licence Creative Commons 2.0 France– Contrat Paternité– Pas de modification

• http://creativecommons.org/licenses/by-nd/2.0/fr/

100

Sponsors