1. « Gradle, a better way to build. »
GRADLE
Grégory BOISSINOT
(@gboissinot)
02/05/2011
YA JUG - Présentation Gradle 1
2. « Gradle, a better way to build. »
A mon propos
• Consultant et formateur Zenika
– Mes spécialités: le build et l'intégration continue
– Lead technique de la solution d'intégration continue pour
l'ensemble des entités Thales
•Introduction et déploiement de Gradle
• Contributeur et Committer pour Hudson/Jenkins
– Intégration des chaînes de build Java (Gradle), C/C++, ADA
– Maintenance corrective et évolutive des plugins réalisés
– Développement de solutions transverses
YA JUG - Présentation Gradle 2
3. « Gradle, a better way to build. »
Principe du build
• Transformation d'une production humaine (le code
source) en une représentation machine (le binaire)
Fichier
JAR
Source
Fichier
Binaire
JVM
println "Hello World" A;^A^@^Am^A^@^T()Ljava/lang/Object;^C^
for (int i:[1,2,3]){ @^@^@^@^A^@^KHello World^H^@2^A^@-
print i org/codehaus/groovy/runtime/callsite/
} CallSite^G^@4^A^@^KcallCurrent^A^@@
(Lgroovy/lang/GroovyObject;
Ljava/lang/Object;)Ljava/lang/Object;
^L^@6^@7^K^@5^@8^C^@^@^@^A^L^@^H^
....
YA JUG - Présentation Gradle 3
4. « Gradle, a better way to build. »
Le build au sein de l'intégration continue
nall
l na
t rr i i s
na
al ee rees ry
ter rees ry
rn i s Ex ar to
t
Ex ibra tory
Ine ar o
Int ibra i iory i r oi
Lb ossi
r t L p
L si t
Lib pos Re p
eo
p Re
Re
R
INTERNET
INTERNET
Event
Polling l er
r
ule
du
hee
d
Sc
Sc
h
ENV
MM
SC
SC
eerr ing
tng
lop
op ori
rt
eel
Repo
p
Devv Re
De
s
ck
ks
hhe on
ec n
C ti
ts,C aio
, t
ess oma
st tom
T t
Te Au
Au
YA JUG - Présentation Gradle 4
5. « Gradle, a better way to build. »
Gradle: Pourquoi un outil de plus?
• La nature des besoins d'automatisation a changé
là du
A u-de
build el
tionn
tradi
• Les besoins d'automatisation ont augmentés
significativement ces dernières années
YA JUG - Présentation Gradle 5
6. « Gradle, a better way to build. »
Historique
1ère génération 2ème génération 3ème génération
2000 2004 2008
2008
2001
3
2
1
YA JUG - Présentation Gradle 6
8. « Gradle, a better way to build. »
Gradle en quelques mots
• Système de build complet focalisé sur le build des
applications d'entreprise Java, Web, Groovy, Scala et
OSGI
• Flexible à la Ant avec les conventions de Maven à la
demande
• Support et insertion totale dans des infrastructures Maven
et Ant/Ivy existantes
• Modèle de description du build très riche à travers une
API Java et une DSL Groovy
YA JUG - Présentation Gradle 8
9. « Gradle, a better way to build. »
Fédération autour des repository Maven
Central java.net
Maven
JBoss …
Codehaus
Artifacts +
maven meta
Ivy
Repository
Artifacts +
ivy meta
Other
Repository
Artifacts +
custom meta
YA JUG - Présentation Gradle 9
10. « Gradle, a better way to build. »
Approche déclarative et conventionnée
• Spécification du 'quoi' et pas du 'comment'
iture
r Fourn le
pteu d'un c
yc
scri vy
De oo de vie Même
Gr ntio
conve
apply plugin:'java' > gradle clean build n que
:clean Maven
repositories { :compileJava
src
mavenCental() :processResources
} :classes myLib main
.jar
:jar
dependencies { :assemble java
compile :compileTestJava
resources
"jdom:jdom:1.1" :processTestResources
testCompile :testClasses
"junit:junit:4.8" :test test
} :check
:build java
BUILD SUCCESSFUL resources
YA JUG - Présentation Gradle 10
11. « Gradle, a better way to build. »
Problématique des outils de build
On ne peut pas anticiper tous les besoins
Aucun projet n'est réellement pareil!
Le projet évolue et donc son processus d'intégration évolue aussi
Il est important de fournir au minimum le même niveau de support
pour les anciens projets que les nouveaux projets
YA JUG - Présentation Gradle 11
12. « Gradle, a better way to build. »
Fourniture d'un langage de build
Écrire un script Gradle consiste à configurer un élément 'Project'
configurations
build.gradle
repositories
dependencies
Project ant
Eléments
task personnalisés
artifacts
Public
API
YA JUG - Présentation Gradle 12
13. « Gradle, a better way to build. »
Un langage de build extensible
• Conçu pour répondre à un maximum de scénarios
– Plusieurs répertoires de sources par projet
– Plusieurs artefacts par projet
– Gestion de classpath distinct pour les tests
d'intégration
– ....
• De nombreux points d'extension pour enrichir les
éléments existants
• La possibilité de fournir ses propres éléments qui vont
former un modèle de build (un ensemble de
conventions), le tout dans une approche déclarative
YA JUG - Présentation Gradle 13
14. « Gradle, a better way to build. »
Au cœur de Gradle : les tâches
La mise en œuvre de l'API à
travers des tâches de
traitement
compile jar test custom
build
war
Un processus Gradle
est un ensemble de tâches
YA JUG - Présentation Gradle 14
15. « Gradle, a better way to build. »
Une tâche est un traitement réutilisable
Possibilité d'écrire du code Java/Groovy sous forme d'unités de
traitement réutilisables
<!-- build.gradle --> Gradle
task(boucleTask).doLast{
for (int i:[1,2,3]){ print i }
} Java/
Groovy
void printMessage(String message){
> gradle boucleTask
println "Print " + message :boucleTask
} 123
task(distribution).doLast {
printMessage("Distribution") > gradle distribution
} :distribution
Print Distribution
task(release)
release.dependsOn(distribution) > gradle release
:distribution
release.doLast{ Print Distribution
println "Print Release" :release
} Print Release
YA JUG - Présentation Gradle 15
16. « Gradle, a better way to build. »
Tâches typées
ConventionTask Mise à disposition d'un ensemble
de tâches prédéfinies
- réutilisables
AbstractCopyTask SourceTask - faciles à étendre
AbstractArchiveTask Copy Javadoc
public class Copy extends AbstractCopyTask {
public AbstractCopyTask from(Object... sourcePaths);
Zip Tar public AbstractCopyTask into(Object destDir);
public AbstractCopyTask include(String... includes);
. . .
}
Jar
task mycopy (type:Copy){
description ='Copies the resources dir'
from(file('resources'))
into(file('destination'))
War include('**/*.txt', '**/*.xml')
}
YA JUG - Présentation Gradle 16
17. « Gradle, a better way to build. »
Agrégation, Partage et Réutilisation
• Les plugins Gradle
• Insertion dans un environnement agile
YA JUG - Présentation Gradle 17
18. « Gradle, a better way to build. »
Regroupement des tâches en plugins
Chaque plugin
- est un ensemble de tâches préconfigurées
- expose un objet de configuration (avec des conventions)
Plugins maven
Java Configuration
Object
eclipse idea
Jetty Configuration War Configuration
Object Object
code-quality war
projects-reports java
… …
jetty osgi …
scala
... Project
Configuration
YA JUG - Présentation Gradle 18
19. « Gradle, a better way to build. »
Manipulation d'un plugin
Java Configuration
java Object
public class JavaPluginConvention {
public SouceSetContainer sourceSets();
public void setSourceCompatibility(Object value);
public void setTargetCompatibility(Object value);
public Manifest manifest()
. . .
}
<!-- build.gradle -->
Facile à
apply plugin:'java' mettre en
Simple à
place et
apprendre
sourceCompatibility = 1.6 facile à
maintenir
targetCompatibility = 1.6
YA JUG - Présentation Gradle 19
20. « Gradle, a better way to build. »
Partage & Réutilisation
Mise à
disposition
r
ur
teu
rae
at
gr
té g
Iné
Int
globalConfig-1.0.gradle
<!– build.gradle -->
task globalConfig {
...
}
Utilisation
ur
r
iaaee
tt u
lss
tii
Uil
Ut
<!– build.gradle --> > gradle config
apply from "http://repomanager/globalConfig-1.0.gradle" ...
...
YA JUG - Présentation Gradle 20
21. « Gradle, a better way to build. »
Haut niveau de contrôle
YA JUG - Présentation Gradle 21
22. « Gradle, a better way to build. »
Gestion évoluée des dépendances
• Possibilité de mettre en place des exclusions globales
• Flexibilité dans la définition des dépôts
repositories{
mavenCentral()
mavenRepo urls:"http://download.java.net/maven/2/"
flatDir name:'localRepository', dirs: 'lib'
}
• Possibilité de définir les dépendances et les déepdances
transitives directement dans le script Gradle
dependencies {
runtime module("org.codehaus.groovy:groovy-all:1.7.5") {
dependency("commons-cli:commons-cli:1.0") {
transitive = false
}
}
}
YA JUG - Présentation Gradle 22
23. « Gradle, a better way to build. »
Simplicité de personaliser son build
e
apply plugin:'java' och
A ppr ative
lar
déc
processResources.enabled=false
test.onlyIf{
!project.hasProperty('skipTests')}
task(preJar) > gradle build –PskipTests
jar.dependsOn preJar :compileJava
:processResources SKIPPED
//Change the source directory :classes
sourceSets{ :preJar
:jar
main{
:assemble
java.srcDirs file('src/java'), :compileTestJava
file('src/java2') :processTestResources
} :testClasses
} :test SKIPPED
:check
//Création d'un uberjar :build
jar {
BUILD SUCCESSFUL
configurations.compile.each {
from zipTree (it) }
}
YA JUG - Présentation Gradle 23
24. « Gradle, a better way to build. »
Manipulation d'un groupe de fichiers source
apply plugin:'java' > gradle clean build
:clean
sourceSets{ :generateTask
. . .
myGenSourceSet { :compileMyGenSourceSetJava
java { :processMyGenSourceSetResources
srcDir 'output/generated' :myGenSourceSetClasses
} . . .
}
}
Mise à disposition automatique d'un ensemble de tâches de traitement
pour le nouveau besoin fonctionnel
YA JUG - Présentation Gradle 24
25. « Gradle, a better way to build. »
Autowiring
> gradle clean build
sourceSets{ :clean
myGenSourceSet { :generateTask
java { :compileMyGenSourceSetJava
srcDir 'output/generated' :processMyGenSourceSetResources
} :myGenSourceSetClasses
:compileJava
main { :processResources
compileClasspath = :classes
configurations.compile . . .
+ sourceSets.myGenSourceSet.classes
runtimeClasspath =
classes
+ configurations.runtime
+ sourceSets.myGenSourceSet.classes
}
}
jar {
from sourceSets.myGenSourceSet.classes
}
YA JUG - Présentation Gradle 25
26. « Gradle, a better way to build. »
Introspecter et manipuler un build
C ONF I GU RAT I ON
t1 t2 t3 t1 t2 t3
E X E C UT I ON
GRADLE
t4 t4
P HAS E
P HAS E
HOOK
SCRIPT
Project Project Engine
Convention 1 Convention 2
gradle –-properties gradle.taskGraph.whenReady { taskGraph ->
gradle –-tasks if (taskGraph.hasTask(':release')){
gradle –-dependencies status = 'release'
gradle –-dry-run build }
}
// Other hooks
gradle.taskGraph.beforeTask { task -> .. .
gradle.beforeProject { project -> .. .
... 26
YA JUG - Présentation Gradle
27. « Gradle, a better way to build. »
Etre à l'écoute de son build
Soyez informé des événements: TestListener,
BuildListener, TaskActionListener, …
class MyTestListener implements TestListener{
beforeTest
GRADL E
void beforeTest(TestDescriptor test) {
GRADL E
println 'testStarting: '+test.getName()
} Test
(junit)
void afterTest(TestDescriptor test,
TestResult result) {
println 'testFinished: '+test.getName() afterTest
+', result: '+result.getResultType()
}
}
YA JUG - Présentation Gradle 27
28. « Gradle, a better way to build. »
Tester vos scripts de build
import org.junit.Assert
> gradle myzip
task myzip (type:Zip) { :myzip
from('somedir')
include('*.txt')
baseName='zipname'
doLast {
Assert.assertEquals('zipname.zip',
myzip.archiveName) createZip
Assert.assertEquals(file('build/distributions'),
myzip.destinationDir)
zipname
.zip
Assert.assertTrue(
!zipTree(myzip.archivePath).isEmpty())
txtfiles = fileTree('somedir').include('*.txt') check
ziptxtfiles=zipTree(myzip.archivePath).matching{
include('*.txt')
}
Assert.assertEquals ( BUILD SUCCESSFUL
txtfiles.getFiles().size(), >
ziptxtfiles.getFiles().size())
}
}
YA JUG - Présentation Gradle 28
29. « Gradle, a better way to build. »
Une boîte à outils pour une
insertion dans l'existant
YA JUG - Présentation Gradle 29
30. « Gradle, a better way to build. »
Réutilisation des tâches Ant
task generateTask(dependsOn:preSchemaGen) << {
ant.echo (message:"Generating ...")
ant {
def schemagenTaskPath = path {
fileset(dirs:'lib', includes: '*.jar')
}
taskdef (
name: "xjc", classname: "com.sun.tools.xjc.XJCTask",
classpath: schemagenTaskPath
)
xjc(destdir:generatedSources,
package:"com.zenika.lib.model"){
schema(dir:"src/main/resources", includes:"**/*.xsd")
}
}
}
YA JUG - Présentation Gradle 30
31. « Gradle, a better way to build. »
Réutilisation des scripts Ant
build.xml
<project>
<target name="antTarget">
<echo message="Hello from Ant"/>
</target>
</project>
build.gradle
ant.importBuild('build.xml')
antTarget.doLast {
println('Hello from Gradle')
}
> gradle antTarget
:antTarget
Hello from Ant
Hello from Gradle
YA JUG - Présentation Gradle 31
32. « Gradle, a better way to build. »
Déploiement dans un dépôt Ivy
apply plugin:'java'
repositories {
mavenCental()
flatDir(dirs:'destrepo', IVY
name:'ivyrep’)
}
group='com.zenika.gradledemos' > gradle uploadArchives
version='1.0'
status='release'
uploadArchives {
repositories {
add(repositories.ivyrep)
}
} Repository
Ivy
distant Artifacts +
meta Ivy
YA JUG - Présentation Gradle 32
33. « Gradle, a better way to build. »
Déploiement dans un dépôt Maven
apply plugin:'java'
apply plugin:'maven' Maven
Ant
group='test' Tasks
version='1.0-SNAPSHOT'
uploadArchives {
repositories {
mavenDeployer {
repository( > gradle > gradle
install uploadArchives
url: remoteRepo)
}
}
}
Repository Repository
Maven Maven
Local Artifacts + distant Artifacts +
meta Maven
meta Maven
YA JUG - Présentation Gradle 33
34. « Gradle, a better way to build. »
Performance
• Gestion avancée d'un multi projet
• Utilisation d'un cache
• Exécution parallèle des tests
• Build daemon
YA JUG - Présentation Gradle 34
35. « Gradle, a better way to build. »
Gestion multi-projet avancée
// settings.gradle shared
include 'api',
'shared',
'services:webservices'
webservices api
// root build.gradle
subprojects { api > gradle buildNeeded
apply plugin: 'java' :shared:jar
} :api:jar
project(':api') { :api:test
dependencies { :shared:test
compile project(':shared')
}
} api > gradle buildDependents
:shared:jar
// webservices/build.gradle :api:jar
:api:test
apply plugin:'war'
dependencies { :webservices:war
compile :webservices:test
project(':shared'),
project(':api'), api > gradle jar –-no-rebuild
'commons-io:commons-io:1.2' api:jar
}
YA JUG - Présentation Gradle 35
36. « Gradle, a better way to build. »
Utilisation systématique d'un cache
1. Le script Gradle est compilé uniquement en cas de
changement
2. Détection des changements pour chaque entrée et
chaque sortie pour la plupart des tâches fournies
> gradle myzip
:myzip
> gradle myzip
:myzip UP-TO-DATE
> gradle myzip –-cache rebuild
:myzip
YA JUG - Présentation Gradle 36
37. « Gradle, a better way to build. »
Mise en place d'une tâche avec cache
class GenerateSchemaType extends DefaultTask {
String depsPath
@InputFiles
SourceDirectorySet inputXsdDirs
@OutputDirectory
File outputFile
> gradle build
:generateTask UP-TO-DATE
@TaskAction :compileGeneratedJava UP-TO-DATE
void generate() { :processGeneratedResources UP-TO-DATE
ant { ...} :generatedClasses UP-TO-DATE
} :compileJava UP-TO-DATE
} ...
task generateTask(type:GenerateSchemaType) {
inputXsdDirs = sourceSets.main.resources
outputFile = generatedSources
depsPath = configurations.jaxb.asPath
}
YA JUG - Présentation Gradle 37
38. « Gradle, a better way to build. »
Exécution parallèle des tests
EXECUTION
Process 1 Process 6
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST
P ARAL L E L I S AT I ON
CLASS CLASS CLASS CLASS CLASS CLASS CLASS CLASS CLASS CLASS
Process 2 Process 7
TEST TEST TEST TEST TEST TEST TEST
CLASS CLASS CLASS CLASS CLASS CLASS CLASS
Process 3
TEST TEST TEST TEST TEST
CLASS CLASS CLASS CLASS CLASS
apply plugin:'java'
Process 4
TEST TEST TEST TEST TEST
CLASS CLASS CLASS CLASS CLASS test {
forkEvery = 5
maxParallelForks = 4
}
YA JUG - Présentation Gradle 38
39. « Gradle, a better way to build. »
Build daemon
• Utilisation d'un processus parallèle pour éviter le cout de
lancement
> gradle build
...
Total time: 3s
> gradle build –daemon
...
Total time: 3s
> gradle build
...
Total time: 1s
• Va favoriser l'intégration de Gradle avec Gradle UI et les
IDE (Eclipse, IDEA, ...)
YA JUG - Présentation Gradle 39
40. « Gradle, a better way to build. »
Intégration dans les IDE
IDE Maturité
NetBeans
Eclipse +
IntelliJ ++
YA JUG - Présentation Gradle 40
41. « Gradle, a better way to build. »
La communauté
YA JUG - Présentation Gradle 41
42. « Gradle, a better way to build. »
Les utilisateurs
gmock
security
spock
integration
4
YA JUG - Présentation Gradle 42
43. « Gradle, a better way to build. »
Support communautaire
• Mailing List très active
• User guide très riche (300 pages)
• Nombreuses contributions de plugins
• Le nombre d'articles et de conférences sur le sujet
augmentent
YA JUG - Présentation Gradle 43
44. « Gradle, a better way to build. »
Support commercial
• Fourniture de consulting et de formation
YA JUG - Présentation Gradle 44
45. « Gradle, a better way to build. »
Et Demain?
YA JUG - Présentation Gradle 45
46. « Gradle, a better way to build. »
Roadmap
• Introduction de modèles de JVM basés sur la nature des
applications
• Amélioration du DSL du graphe des tâches
• Réutilisation possible des plugins Maven
• Un livre en préparation
• Une communauté plus large
YA JUG - Présentation Gradle 46
47. « Gradle, a better way to build. »
Dans l'avenir…
YA JUG - Présentation Gradle 47
48. « Gradle, a better way to build. »
Nous avons besoin de vous…
• Essayez-le !
• Utilisez-le !
• Faites du buzz!
YA JUG - Présentation Gradle 48