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
Top Related