Présentation Gradle par Grégory Boissinot

publicité
GRADLE
Grégory Boissinot
Présentation Gradle
1
• Consultant et formateur chez Zenika
• Mes spécialités
– Ant/Ivy
– Maven
– Gradle
– Hudson
• Contributeur Hudson
• Introduction et mis en place de Gradle chez un très grand compte
industriel
Présentation Gradle
2
• Système de build pour la JVM Java, focalisé sur le build
des applications d'entreprise
• Modèle de description du build très riche à travers une
API
• Flexible à la Ant avec les conventions de Maven à la
demande
• Une gestion avancée d'un projet multi-modules
• Support et insertion totale dans des infrastructures Maven
et Ant/Ivy existantes
Présentation Gradle
3
1ère génération
2000
2ème génération
2005
3ème génération
2008
2
3
1
Présentation Gradle
4
<!–- ANT -- build.xml -->
<project>
<property name="version"
value="1.0"/>
<target name="antTask>
<echo message="Hello"/>
</target>
</project>
<!–- MAVEN – pom.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.zenika</groupId>
<artifactId>zenikac-core</artifactId>
<version>1.0</version>
<dependencies>
<!–- GRADLE– build.gradle -->
<dependency>
apply plugin:'java'
<groupId>org.apache.wicket</groupId>
<artifactId>wicket</artifactId>
repositories {
<version>1.4.7</version>
mavenCental()
<scope>compile</scope>
flatDir(dirs:'lib')
</dependency>
}
</dependencies>
</project>
dependencies {
compile
"org.apache.wicket:wicket:1.4.7"
}
Présentation Gradle
5
Distribution Gradle
CORE
UI
WRAPPER
OPEN-API
DOCS
api
java
groovy
maven
osgi
war
jetty
scala
eclipse
code-quality
project-reports
plugins
Ant
Ivy
Maven Ant Tasks
Groovy
outils
checkstyle
codeNarc
webdav
Autres dépendances
Librairies tierces
Présentation Gradle
6
Écrire un script Gradle consiste à configurer un objet Gradle Project
configurations
repositories
dependencies
build.gradle
Project
ant
artifacts
task
API
Présentation Gradle
7
Un script de build Gradle est défini par un ensemble de tâches sur
lesquelles sont ajoutées des actions qui sont des closures Groovy
<!-- build.gradle -->
task(hello)
hello.doFirst{
println "Hello World"
for (int i:[1,2,3]){
print i
}
}
> gradle hello
:hello
Hello World
123
task(distribution).doFirst {
println "Print Distribution"
}
task(release)
release.dependsOn(distribution)
release.doFirst{
println "Print Release"
}
Présentation Gradle
> gradle distribution
:distribution
Print Distribution
> gradle release
:distribution
Print Distribution
:release
Print Release
8
task mycopy (type:Copy){
from(file('resources'))
into(file('target'))
include('**/*.txt', '**/*.xml')
}
myCopy.include('**/*.properties')
ConventionTask
SourceTask
Javadoc
AbstractCopyTask
AbstractArchiveTask
Copy
Zip
public class Copy extends AbstractCopyTask {
public AbstractCopyTask from(Object... sourcePaths);
public AbstractCopyTask into(Object destDir);
}
Tar
Jar
War
Présentation Gradle
9
<!– 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"
}
Présentation Gradle
10
ant {
def wsdl2java_classpath = path {
fileset(dirs:'lib', includes: '*.jar')
}
taskdef(
name: 'axiswsdl2java',
classname:
'org.apache.axis.tools.ant.wsdl.Wsdl2javaAntTask',
classpath: wsdl2java_classpath )
}
axiswsdl2java( output:"generated",
verbose:"true" ,
url:"Exemple.wsdl" )
ant.echo (message:ANT)
Présentation Gradle
11
build.xml
build.gradle
<project>
<target name="antTask">
<echo message="Hello from Ant"/>
</target>
</project>
ant.importBuild('build.xml')
antTask.doLast {
println('Hello from Gradle')
}
> gradle antTask
:antTask
Hello from Ant
Hello from Gradle
Présentation Gradle
12
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())
ziptxtfiles=zipTree(myzip.archivePath).matching{
include('*.txt')
}
txtfiles=fileTree('somedir').include('*.txt')
Assert.assertEquals (
txtfiles.getFiles().size(),
ziptxtfiles.getFiles().size())
}
}
Présentation Gradle
13
Chaque plugin déclaré apporte un ensemble de tâches et de propriétés
CORE
UI
WRAPPER
OPEN-API
DOCS
api
java
groovy
maven
osgi
war
jetty
scala
eclipse
code-quality
project-reports
plugins
Ant
Ivy
Maven Ant Tasks
Groovy
outils
Présentation Gradle
14
apply plugin:'java'
repositories {
mavenCental()
flatDir(dirs:'destrepo',
name:'ivyrep’)
}
dependencies {
compile
"jdom:jdom:1.0",
":qtjambi:4.5.2_01"
testCompile
"junit:junit:4.7"
}
> gradle clean build
:clean
:compileJava
:processResources
:classes
:jar
:assemble
:compileTestJava
:processTestResources
:testClasses
:test
:check
:build
myLib
.jar
BUILD SUCCESSFUL
Total time: 2.937 secs
Présentation Gradle
15
apply plugin:'war'
processResources.enabled=false
//Add behavior in the lifecycle
task(preJar)
jar.dependsOn preJar
//Predicate
test.onlyIf{
!project.hasProperty('skipTests')
}
//Change the output directory
buildDirName='target'
//Change the source directory
sourceSets{
main{
java.srcDir file('src/main')
}
}
Présentation Gradle
> gradle build -PskipTest
:compileJava
:processResources SKIPPED
:classes
:preJar
:jar
:war
:assemble
:compileTestJava
:processTestResources
:testClasses
:test SKIPPED
:check
:build
BUILD SUCCESSFUL
Total time: 2.937 secs
16
Soyez informé de tous les événements de votre chaîne de build
class MyTestListener implements TestListener{
void beforeSuite(TestDescriptor suite) {
println('suiteStarting: '+suite.getName())
}
void afterSuite(TestDescriptor suite,
TestResult result) {
println 'suiteFinished: '+suite.getName()
}
void beforeTest(TestDescriptor test) {
println 'testStarting: '+test.getName()
}
}
void afterTest(TestDescriptor test,
TestResult result) {
println 'testFinished: '+test.getName()
+', result: '+result.getResultType()
}
Présentation Gradle
17
<!-- settings.gradle -->
include 'api',
'shared',
'services:webservices'
<!–- build.gradle -->
version='1.0'
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
Présentation Gradle
18
apply plugin:'java'
repositories {
mavenCental()
flatDir(dirs:'destrepo',
name:'ivyrep’)
}
IVY
group='test'
version='1.0'
status='release'
> gradle uploadArchives
uploadArchives {
repositories {
add(repositories.ivyrep)
}
}
Repository
Ivy
distant Artifacts +
meta Ivy
Présentation Gradle
19
apply plugin:'java'
apply plugin:'maven'
Maven
Ant
Tasks
group='test'
version='1.0-SNAPSHOT'
uploadArchives {
repositories {
mavenDeployer {
repository(
url: remoteRepo)
}
}
}
> gradle
install
Repository
Maven
Artifacts +
Local meta
Maven
Présentation Gradle
> gradle
uploadArchives
Repository
Maven
distant
Artifacts +
meta Maven
20
• Amélioration constante de la DSL pour encore plus de richesse et
de simplicité
• Support amélioré dans les IDE
• Une abstraction de Ivy pour encore un gestionnaire de
dépendance plus avancé
• Parallélisation/Distribution des builds
• Réutilisation des plugins Maven et import de projets Maven
• Simplification dans la phase de publication des artefacts
Présentation Gradle
21
gmock
spcok
Présentation Gradle
22
• Gradle vous offre toute la richesse pour exprimer vos chaines de
build au plus près de vos besoins
• Gradle fournit une approche déclarative de premier plan
• Gradle est un système de build complet et alternatif pour builder
vos applications
• Gradle s'insère nativement en lecture et en écriture dans votre
existant pour l'enrichir
Présentation Gradle
23
Téléchargement