présentation gradle au lyonjug par grégory boissinot - zenika
TRANSCRIPT
1 Lyon JUG - Présentation Gradle
GRADLE Gregory BOISSINOT
23/11/2010
2 Lyon JUG - Présentation Gradle
• Consultant et formateur Zenika – Mes spécialités: le build et l'intégration continue – Responsable technique de la solution d'intégration continue
chez Thales • Introduction et déploiement de Gradle à grande échelle
• Commiter Hudson – Intégration des châines de build Java (Gradle), C/C++, ADA
3 Lyon JUG - Présentation Gradle
INTERNET
4 Lyon JUG - Présentation Gradle
• Transformation d'une production humaine (le code source) en une représentation machine (le binaire)
Fichier Source JAR
JVM
println "Hello World" for (int i:[1,2,3]){ print i }
A;^A^@^Am^A^@^T()Ljava/lang/Object;^C^ @^@^@^@^A^@^KHello World^H^@2^A^@- 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^ ....
Fichier Binaire
5 Lyon JUG - Présentation Gradle
• Les besoins d'automatisation ont augmentés significativement ces dernières années
• La nature des besoins d'automatisation a changé Un build peut faire beaucoup plus de choses que la simple création d'une archive Java
6 Lyon JUG - Présentation Gradle
1ère génération
2008
2001
2
1
3
2ème génération 3ème génération 2000 2005 2008
7 Lyon JUG - Présentation Gradle
<!–- ANT -- build.xml --> <project> <target name="retrieceDeps> ... </target> <target name="compile" ... </project>
<!–- GRADLE– build.gradle --> apply plugin:'java'
version=1.0
repositories { mavenCental() flatDir(dirs:'lib') }
dependencies { compile( group:'org.apache.wicket', name:'wicket', version:'1.4.7') }
<!–- MAVEN – pom.xml--> <?xml version="1.0" encoding="UTF-8"?> <project> <modelVersion>4.0.0</modelVersion> <groupId>org.lyonjug</groupId> <artifactId>maven</artifactId> <version>1.0</version> <dependencies> <dependency> <groupId>org.apache.wicket</groupId> <artifactId>wicket</artifactId> <version>1.4.7</version> <scope>compile</scope> </dependency> </dependencies> </project>
8 Lyon JUG - Présentation Gradle
• Système de build complet focalisé sur le build des applications d'entreprise Java, Web, Groovy, Scala et OSGI
• Modèle de description du build très riche à travers une API et une DSL Groovy
• Flexible à la Ant avec les conventions de Maven à la demande
• Support et insertion totale dans des infrastructures Maven et Ant/Ivy existantes
9 Lyon JUG - Présentation Gradle
• Spécification du 'quoi' et pas du 'comment'
Même
convention
que Maven apply plugin:'java'
repositories { mavenCental() }
dependencies { compile "jdom:jdom:1.1" testCompile "junit:junit:4.8" }
myLib .jar
src
main
java
test
java
> gradle clean build :clean :compileJava :processResources :classes :jar :assemble :compileTestJava :processTestResources :testClasses :test :check :build
BUILD SUCCESSFUL resources
resources
10 Lyon JUG - Présentation Gradle
On ne peut pas anticiper tous les besoins
Il est nécessaire de fournir le même niveau de support entre les anciens projets et les nouveaux projets
11 Lyon JUG - Présentation Gradle
Project
repositories dependencies
task
configurations
artifacts
API
ant
Écrire un script Gradle consiste à configurer un objet Project
build.gradle
Eléments personnalisés
12 Lyon JUG - Présentation Gradle
• Conçu pour répondre à tous les scénarios possibles – Plusieurs répertoires de sources par projet – Une version de JDK par répertoire – Plusieurs artefacts par projet – ....
• De nombreux points d'extension pour enrichir les éléments existant
• La possibilité de fournir ses propres éléments qui vont former un modèle de build
13 Lyon JUG - Présentation Gradle
<!-- build.gradle --> task(boucleTask).doFirst{ for (int i:[1,2,3]){ print i } }
void printMessage(String message){ println "Print " + message }
task(distribution).doFirst { printMessage("Distribution") }
task(release) release.dependsOn(distribution) release.doFirst{ println "Print Release" }
> gradle boucleTask :boucleTask 123
> gradle distribution :distribution Print Distribution
> gradle release :distribution Print Distribution :release Print Release
Possibilité d'écrire du code Java/Groovy sous forme d'unités réutilisables
14 Lyon JUG - Présentation Gradle
task mycopy (type:Copy){ description ='Copies the resources dir' from(file('resources')) into(file('target')) include('**/*.txt', '**/*.xml') }
AbstractCopyTask
AbstractArchiveTask
Zip
Jar
War
Tar
SourceTask
Javadoc
ConventionTask
Copy
public class Copy extends AbstractCopyTask { public AbstractCopyTask from(Object... sourcePaths); public AbstractCopyTask into(Object destDir); public AbstractCopyTask include(String... includes); . . . }
15 Lyon JUG - Présentation Gradle
<!– HelloTask.groovy --> class HelloTask extends DefaultTask {
def message="Default Message"
@TaskAction public void print(){ println message } }
> gradle myhello :myhello Default Message
> gradle myhello2 :myhello2 Task Message <!-- build.gradle -->
task(myhello, type:HelloTask)
task(myhello2, type:HelloTask){ message="Task Message" }
16 Lyon JUG - Présentation Gradle
• Les plugins Gradle
• Insertion dans un environnement agile
17 Lyon JUG - Présentation Gradle
java
war
maven
osgi
code-quality
jetty
scala
eclipse idea
projects-reports
Java Configuration Object
War Configuration Object
Jetty Configuration Object
…
Plugins
Project Configuration
…
…
Chaque plugin
- est un ensemble de tâches
- expose un objet Java convention
18 Lyon JUG - Présentation Gradle
> gradle config ...
<!– build.gradle --> task config { ... }
<!– build.gradle --> apply from "http://repomanager/config-1.0.gradle" ...
config-1.0.gradle
Mise à disposition
Utilisation
19 Lyon JUG - Présentation Gradle
20 Lyon JUG - Présentation Gradle
• Flexibilité dans la définition des dépôts
• Possibilité de mettre en place des exclusions globales • Possibilité de définir les dépendances transitives dans le
script Gradle
repositories{ mavenCentral() mavenRepo urls: "http://download.java.net/maven/2/" flatDir name: 'localRepository', dirs: 'lib' }
dependencies { runtime module("org.codehaus.groovy:groovy-all:1.7.5") { dependency("commons-cli:commons-cli:1.0") { transitive = false } } }
21 Lyon JUG - Présentation Gradle
apply plugin:'java'
processResources.enabled=false
test.onlyIf{ !project.hasProperty('skipTests')}
//Add behavior in the lifecycle task(preJar) jar.dependsOn preJar
//Change the output directory buildDirName='target'
//Change the source directory sourceSets{ main{ java.srcDirs file('src/java'), file('src/java2') } }
> gradle build –PskipTests :compileJava :processResources SKIPPED :classes :preJar :jar :war :assemble :compileTestJava :processTestResources :testClasses :test SKIPPED :check :build
BUILD SUCCESSFUL
22 Lyon JUG - Présentation Gradle
apply plugin:'java'
sourceSets{ myGenSourceSet { java { srcDir 'build/generated' } } }
> gradle clean build :clean :generateTask . . . :compileMyGenSourceSetJava :processMyGenSourceSetResources :myGenSourceSetClasses . . .
23 Lyon JUG - Présentation Gradle
sourceSets{ myGenSourceSet { java { srcDir 'build/generated' }
main { compileClasspath = configurations.compile +sourceSets.myGenSourceSet.classes
runtimeClasspath = classes + configurations.runtime + sourceSets.myGenSourceSet.classes } }
jar { from sourceSets.myGenSourceSet.classes }
> gradle clean build :clean :generateTask :compileMyGenSourceSetJava :processMyGenSourceSetResources :myGenSourceSetClasses :compileJava :processResources :classes . . .
24 Lyon JUG - Présentation Gradle
version = 1.0 gradle.taskGraph.whenReady { taskGraph -> if (! taskGraph.hasTask(':release')){ version+='-SNAPSHOT' } }
GRADLE SCRIPT
Engine
CO
NFIG
UR
ATION
PHA
SE
t1 t2
t4
Project Convention 1
HO
OK
t3 t1 t2
t4
Project Convention 2
t3 EXEC
UTIO
N PH
ASE
gradle –-properties gradle –-tasks gradle –-dependencies gradle –-dry-run build
// Other hooks gradle.taskGraph.beforeTask { task -> .. . gradle.beforeProject { project -> .. . ...
25 Lyon JUG - Présentation Gradle
Soyez informé des événements: TestListener, BuildListener, TaskActionListener, …
class MyTestListener implements TestListener{
void beforeTest(TestDescriptor test) { println 'testStarting: '+test.getName() }
void afterTest(TestDescriptor test, TestResult result) { println 'testFinished: '+test.getName() +', result: '+result.getResultType() } }
Test (junit)
GR
AD
LE beforeTest
afterTest
26 Lyon JUG - Présentation Gradle
import org.junit.Assert
task myzip (type:Zip) { from 'somedir' include '*.txt' baseName='zipname' doLast { Assert.assertEquals('zipname.zip', myzip.archiveName) Assert.assertEquals(file('build/distributions'), myzip.destinationDir)
Assert.assertTrue( !zipTree(myzip.archivePath).isEmpty())
txtfiles = fileTree('somedir').include('*.txt') ziptxtfiles=zipTree(myzip.archivePath).matching{ include('*.txt') } Assert.assertEquals ( txtfiles.getFiles().size(), ziptxtfiles.getFiles().size()) } }
zipname.zip
createZip
check
> gradle myzip :myzip
BUILD SUCCESSFUL >
27 Lyon JUG - Présentation Gradle
28 Lyon JUG - Présentation Gradle
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") } } }
29 Lyon JUG - Présentation Gradle
build.gradle
build.xml
ant.importBuild('build.xml') antTask.doLast { println('Hello from Gradle') }
<project> <target name="antTask"> <echo message="Hello from Ant"/> </target> </project>
> gradle antTask :antTask Hello from Ant Hello from Gradle
30 Lyon JUG - Présentation Gradle
IVY
Repository Ivy
distant Artifacts + meta Ivy
apply plugin:'java'
repositories { mavenCental() flatDir(dirs:'destrepo', name:'ivyrep’) }
group='test' version='1.0' status='release'
uploadArchives { repositories { add(repositories.ivyrep) } }
> gradle uploadArchives
31 Lyon JUG - Présentation Gradle
Repository Maven distant Artifacts +
meta Maven
Maven Ant
Tasks
Repository Maven Local Artifacts +
meta Maven
apply plugin:'java' apply plugin:'maven'
group='test' version='1.0-SNAPSHOT'
uploadArchives { repositories { mavenDeployer { repository( url: remoteRepo) } } }
> gradle uploadArchives
> gradle install
32 Lyon JUG - Présentation Gradle
• Gestion avancée d'un multi projet
• Utilisation d'un cache
• Exécution parallèle des tests
• Build daemon
33 Lyon JUG - Présentation Gradle
// settings.gradle include 'api', 'shared', 'services:webservices'
// root build.gradle subprojects { apply plugin: 'java' } project(':api') { dependencies { compile project(':shared') } }
// webservices/build.gradle apply plugin:'war' dependencies { compile project(':shared'), project(':api'), 'commons-io:commons-io:1.2' }
shared
webservices api
api > gradle buildNeeded :shared:jar :api:jar :api:test :shared:test
api > gradle buildDependents :shared:jar :api:jar :api:test :webservices:war :webservices:test
api > gradle jar –-no-rebuild api:jar
34 Lyon JUG - Présentation Gradle
1. Le script Gradle est compilé uniquement en cas de changement
2. Détéction 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
35 Lyon JUG - Présentation Gradle
class GenerateSchemaType extends DefaultTask {
String depsPath
@InputFiles SourceDirectorySet inputXsdDirs
@OutputDirectory File outputFile
@TaskAction void generate() { ant { ...} } }
task generateTask(type:GenerateSchemaType) { inputXsdDirs = sourceSets.main.resources outputFile = generatedSources depsPath = configurations.jaxb.asPath }
> gradle build :generateTask UP-TO-DATE :compileGeneratedJava UP-TO-DATE :processGeneratedResources UP-TO-DATE :generatedClasses UP-TO-DATE :compileJava UP-TO-DATE ...
36 Lyon JUG - Présentation Gradle
apply plugin:'java'
test { forkEvery = 5 maxParallelForks = 4 }
Process 1 TEST SUITE
TEST SUITE
TEST SUITE
TEST SUITE
TEST SUITE
Process 7 TEST SUITE
TEST SUITE
Process 2 TEST SUITE
TEST SUITE
TEST SUITE
TEST SUITE
TEST SUITE
Process 3 TEST SUITE
TEST SUITE
TEST SUITE
TTEST SUITE
TEST SUITE
EXECUTION
Process 4 TEST SUITE
TEST SUITE
TTEST SUITE
TEST SUITE
TEST SUITE
Process 6 TEST SUITE
TEST SUITE
TEST SUITE
TEST SUITE
TEST SUITE PA
RA
LLELISATION
37 Lyon JUG - Présentation Gradle
• Utilisation d'un processus parallèle pour éviter le cout de lancement
• Va favoriser l'intégration de Gradle avec Gradle UI et les IDE (Eclipse, IDEA, ...)
> gradle build ... Total time: 3s
> gradle build –daemon ... Total time: 3s
> gradle build ... Total time: 1s
38 Lyon JUG - Présentation Gradle
39 Lyon JUG - Présentation Gradle
gmock
spock security
4
40 Lyon JUG - Présentation Gradle
• Mailing List très active
• User guide très riche (+280 pages)
• Nombreuses contributions de plugins
• Le nombre d'articles et de conférences sur le sujet augmentent
41 Lyon JUG - Présentation Gradle
42 Lyon JUG - Présentation Gradle
• Nouveau DSL de gestion des dépendances
• Introduction de modèles de JVM basés sur la nature des applications
• Fourniture d'un DSL de composition du build
• Amélioration du DSL du graphe des tâches
• Réutilisation possible des plugins Maven
• Un livre en préparation
43 Lyon JUG - Présentation Gradle
44 Lyon JUG - Présentation Gradle
• Essayez-le !
• Utilisez-le !
• Faites du buzz!
45 Lyon JUG - Présentation Gradle
Merci