présentation gradle au lyonjug par grégory boissinot - zenika

45
1 Lyon JUG - Présentation Gradle GRADLE Gregory BOISSINOT 23/11/2010

Upload: zenika

Post on 04-Jul-2015

1.865 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

1 Lyon JUG - Présentation Gradle

GRADLE Gregory BOISSINOT

23/11/2010

Page 2: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 3: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

3 Lyon JUG - Présentation Gradle

INTERNET

Page 4: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 5: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 6: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 7: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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>

Page 8: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 9: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 10: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 11: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 12: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 13: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 14: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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); . . . }

Page 15: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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" }

Page 16: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

16 Lyon JUG - Présentation Gradle

• Les plugins Gradle

• Insertion dans un environnement agile

Page 17: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 18: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 19: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

19 Lyon JUG - Présentation Gradle

Page 20: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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 } } }

Page 21: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 22: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

22 Lyon JUG - Présentation Gradle

apply plugin:'java'

sourceSets{ myGenSourceSet { java { srcDir 'build/generated' } } }

> gradle clean build :clean :generateTask . . . :compileMyGenSourceSetJava :processMyGenSourceSetResources :myGenSourceSetClasses . . .

Page 23: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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 . . .

Page 24: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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 -> .. . ...

Page 25: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 26: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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 >

Page 27: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

27 Lyon JUG - Présentation Gradle

Page 28: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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") } } }

Page 29: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 30: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 31: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 32: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 33: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 34: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 35: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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 ...

Page 36: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 37: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 38: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

38 Lyon JUG - Présentation Gradle

Page 39: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

39 Lyon JUG - Présentation Gradle

gmock

spock security

4

Page 40: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 41: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

41 Lyon JUG - Présentation Gradle

Page 42: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

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

Page 43: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

43 Lyon JUG - Présentation Gradle

Page 44: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

44 Lyon JUG - Présentation Gradle

• Essayez-le !

• Utilisez-le !

• Faites du buzz!

Page 45: Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

45 Lyon JUG - Présentation Gradle

Merci