Gradle Introduction

Post on 25-Jun-2015

2.827 views 1 download

Tags:

Transcript of Gradle Introduction

Introduction to Gradle Andrey Adamovich

Aestas/IT

What is Gradle?

Gradle is a general purpose build system

It comes with a rich build description language (DSL) based on Groovy

It supports ”build-by-convention” principle

But it is very flexible and extensible

It has built-in plug-ins for Java, Groovy, Scala, Web, OSGi

It derives all the best and integrates well with Ivy, Ant and Maven

What’s in this presentation?

Overview

Basic features & principles

Files and file collections

Dependencies

Multiple projects

Plug-ins

Reading material

Questions

OVERVIEW

Gradle features I

Declarative builds and build-by-convention

Language for dependency based programming and many ways to manage dependencies

Groovy as a base language allows imperative programming

Gradle features II

Deep and rich API for managing projects, tasks, dependency artefacts and much more.

State of the art support for multi-project builds

Ease of integration and migration. Ant, Maven, Ivy are supported out-of-the-box

Free and open source

Advanced features

Parallel unit test execution

Dependency build

Incremental build support

Dynamic tasks and task rules

Gradle daemon

Who uses Gradle?

Hibernate

Grails

Groovy

Spring Integration

Spring Security

Griffon

Gaelyk

Qi4j

Canoo

Carrier

FCC

Zeppelin

GPars

Spock

Aluminum

Gant

BASIC FEATURES & PRINCIPLES

Hello, Gradle!

task hello << {

print ’Hello, '

}

task world(dependsOn: hello) << {

println ’World!'

} >gradle -q hello world

Hello, World!

>gradle -q world

Hello, World!

task hello << {

println ’Hello, World'

} >gradle hello

:hello

Hello, World!

BUILD SUCCESSFUL

Total time: 2.401 secs

build.gradle:

build.gradle:

Task configuration & execution task hello

message = "What's up?"

hello {

println "Configuring hello task."

message = 'Hello, World!'

}

hello << {

println message

}

hello << {

println project.message

}

>gradle hello

Configuring hello task.

:hello

Hello, World!

What's up?

BUILD SUCCESSFUL

Total time: 1.958 secs

Gradle is Groovy, Groovy is Java

import java.io.File;

String parentDir = new File(”test.txt”)

.getAbsoluteFile()

.getParentPath();

def parentDir = new File(”test.txt”).absoluteFile.parentPath

parentDir = file(”test.txt”).absoluteFile.parentPath

Java:

Groovy:

Gradle:

Building Java project apply plugin: 'java'

>gradle clean build

:clean

:compileJava

:processResources UP-TO-DATE

:classes

:jar

:assemble

:compileTestJava UP-TO-DATE

:processTestResources UP-TO-DATE

:testClasses UP-TO-DATE

:test

:check

:build

BUILD SUCCESSFUL

Total time: 7.6 secs

Java plug-in tasks

compileJava processResources

classes javadoc

compileTestJava processTestResources

testClasses

test

check

build

clean

jar

uploadArchives

assemble

Extending tasks

test {

systemProperties ("net.sourceforge.cobertura.datafile": cobSerFile)

cobSerFile = "${project.buildDir}/cobertura.ser"

}

test.doFirst {

ant {

delete(file: cobSerFile, failonerror: false)

'cobertura-instrument'(datafile: cobSerFile) {

fileset(dir: "${sourceSets.main.classesDir}", includes: "**/*.class") }

}

}

}

test.doLast {

ant.'cobertura-report'(

destdir: "${project.buildDirName}/test-results",

format: 'xml',

srcdir: "src/main/java",

datafile: cobSerFile)

}

Ant is a first-class citizen

All Ant tasks and types can be used inside Gradle script using Groovy syntax

Whole Ant build script can be imported into Gradle and its targets can be called

Ant usage examples I task hello << {

String greeting = "hello from Ant"

ant.echo(message: greeting)

}

task zip << {

ant.zip(destfile: 'archive.zip') {

fileset(dir: 'src') {

include(name: '**.xml')

exclude(name: '**.java')

}

}

}

task list << {

def path = ant.path {

fileset(dir: 'libs', includes: '*.jar')

}

path.list().each {

println it

}

}

Ant usage examples II

<project>

<target name="hello">

<echo>Hello, from Ant</echo>

</target>

</project>

ant.importBuild 'build.xml'

>gradle hello

:hello

[ant:echo] Hello, from Ant

BUILD SUCCESSFUL

Total time: 7.898 secs

ant.taskdef(resource: 'checkstyletask.properties') {

classpath {

fileset(dir: 'libs/checkstyle', includes: '*.jar')

}

}

ant.checkstyle(config: 'src/tools/sun_checks.xml') {

fileset(dir: 'src')

}

Overriding conventions version = 1.0

group = ’org.gradletutorials’

version = "1.0-${new Date().format('yyyyMMdd')}"

task release(dependsOn: assemble) << {

println 'We release now'

}

build.taskGraph.whenReady { taskGraph ->

if (taskGraph.hasTask(':release')) {

version = '1.0’

} else {

version = '1.0-SNAPSHOT’

}

}

sourceSets.main.java.srcDirs += ["src/generated/java"]

sourceSets.main.resources.srcDirs += ["src/generated/resources"]

More examples

Many source directory sets per project without a need of a plug-in

Different dependencies per source directory

Even different JDK per source directory

Many artifacts per project

FILES AND FILE COLLECTIONS

Referencing files & file collections

// Using a relative path

File configFile = file('src/config.xml')

Groovy-like syntax:

FileCollection collection = files(

'src/file1.txt',

new File('src/file2.txt'),

['src/file3.txt', 'src/file4.txt'])

collection = files { srcDir.listFiles() }

Create a file collection from a bunch of files:

Create a files collection by referencing project properties:

def union = collection + files('src/file4.txt')

def different = collection - files('src/file3.txt')}

Operations on collections:

Using file collections as input

Many objects in Gradle have properties, which accept a set of input files. For example, the compile task has a source property, which defines the source files to compile. You can set the value of this property using any of the types supported by the files() method:

// Use a File object to specify the source directory.

compile {

source = file('src/main/java')

}

// Using a closure to specify the source files.

compile {

source = {

// Use the contents of each zip file in the src dir.

file('src')

.listFiles()

.findAll { it.name.endsWith('.zip') }

.collect { zipTree(it) }

}

}

}1

Copying files

ant.copy(todir: 'javadoc') {

fileset(dir: 'build/docs')

}

task copyTask(type: Copy) {

from 'src/main/webapp‘

into 'build/explodedWar‘

include '**/*.jsp‘

exclude { details ->

details.file.name.endsWith('.html') &&

details.file.text.contains('staging')

}

}

Using Ant integration:

Using Gradle task type:

DEPENDENCY MANAGEMENT

Repository configuration repositories {

mavenCentral()

}

repositories {

mavenCentral name: 'single-jar-repo', urls: "http://repo.mycompany.com/jars"

mavenCentral name: 'multi-jar-repos', urls:

["http://repo.mycompany.com/jars1", "http://repo.mycompany.com/jars1"]

}

repositories {

flatDir name: 'localRepository',

dirs: 'lib' flatDir dirs: ['lib1', 'lib2']

}

repositories {

add(new org.apache.ivy.plugins.resolver.FileSystemResolver()) {

name = 'localRepository'

latestStrategy = new org.apache.ivy.plugins.latest.LatestTimeStrategy()

addArtifactPattern(libDir +

'/[organization]/[artifact]/[ext]s/[artifact]-[revision].[ext]')

}

}

Referencing dependencies

dependencies {

compile 'org.springframework:spring-webmvc:3.0.0.RELEASE'

testCompile 'org.springframework:spring-test:3.0.0.RELEASE'

testCompile 'junit:junit:4.7'

}

dependencies {

runtime group: 'org.springframework', name: 'spring-core', version: '2.5'

runtime 'org.springframework:spring-core:2.5',

'org.springframework:spring-aop:2.5

}

dependencies {

runtime files('libs/a.jar', 'libs/b.jar')

runtime fileTree(dir: 'libs', includes: ['*.jar'])

}

List groovy = ["org.codehaus.groovy:groovy-all:1.5.4@jar",

"commons-cli:commons-cli:1.0@jar",

"org.apache.ant:ant:1.7.0@jar"]

List hibernate = ['org.hibernate:hibernate:3.0.5@jar',

'somegroup:someorg:1.0@jar']

dependencies {

runtime groovy, hibernate

}

Transitive dependencies

configurations.compile.transitive = true

dependencies {

compile 'org.springframework:spring-webmvc:3.0.0.RC2'

runtime 'org.hibernate:hibernate:3.0.5'

}

dependencies {

compile 'org.springframework:spring-webmvc:3.0.0.RC2'

runtime('org.hibernate:hibernate:3.0.5') {

transitive = true

}

}

MULTI-PROJECT BUILDS

Directories & settings.gradle

include 'shared', 'api', ':service:service1', ':service:service2'

settings.gradle:

You can have only one build file for the whole multi-project build

All properties, settings, plug-ins, dependencies are derived without a need to duplicate information

You can override almost all behaviour in child builds

All or something

allprojects {

task build << {

println "Building project: " + project.name

}

}

subprojects {

task prebuild << {

println "It is subproject!"

}

build.dependsOn prebuild

}

>gradle build

:build

Building project: 90-multi-project

:api:prebuild

It is subproject!

:api:build

Building project: api

:service:prebuild

It is subproject!

:service:build

Building project: service

:shared:prebuild

It is subproject!

:shared:build

Building project: shared

:service:service1:prebuild

It is subproject!

:service:service1:build

Building project: service1

:service:service2:prebuild

It is subproject!

:service:service2:build

Building project: service2

BUILD SUCCESSFUL

Total time: 9.684 secs

Inter-project dependencies subprojects {

apply plugin: 'java'

if (project.name.matches('^.*service\\d+$')) {

dependencies {

compile project(':api')

compile project(':shared')

}

}

}

project(':api') {

dependencies {

compile project(':shared')

}

}

dependsOnChildren()

>gradle clean build

:api:clean

:service:clean

:shared:clean

:service:service1:clean

:service:service2:clean

:shared:compileJava UP-TO-DATE

:shared:processResources UP-TO-DATE

:shared:classes UP-TO-DATE

:shared:jar

:api:compileJava

:api:processResources UP-TO-DATE

:api:classes

:api:jar

:api:assemble

:api:compileTestJava

:api:processTestResources UP-TO-DATE

:api:testClasses

:api:test

:api:check

:api:build

:service:compileJava UP-TO-DATE

:service:processResources UP-TO-DATE

:service:classes UP-TO-DATE

:service:jar

:service:assemble

:service:compileTestJava UP-TO-DATE

:service:processTestResources UP-TO-DATE

:service:testClasses UP-TO-DATE

:service:test UP-TO-DATE

:service:check UP-TO-DATE

:service:build

:shared:assemble

:shared:compileTestJava UP-TO-DATE

:shared:processTestResources UP-TO-DATE

:shared:testClasses UP-TO-DATE

:shared:test UP-TO-DATE

:shared:check UP-TO-DATE

:shared:build

:service:service1:compileJava

:service:service1:processResources UP-TO-DATE

:service:service1:classes

:service:service1:jar

:service:service1:assemble

:service:service1:compileTestJava

:service:service1:processTestResources UP-TO-

DATE

:service:service1:testClasses

:service:service1:test

:service:service1:check

:service:service1:build

:service:service2:compileJava

:service:service2:processResources UP-TO-DATE

:service:service2:classes

:service:service2:jar

:service:service2:assemble

:service:service2:compileTestJava

:service:service2:processTestResources UP-TO-

DATE

:service:service2:testClasses

:service:service2:test

:service:service2:check

:service:service2:build

BUILD SUCCESSFUL

Total time: 3.75 secs

PLUGINS

Extending your build Any Gradle script can be a plug-in:

apply from: 'otherScript.gradle'

apply from: 'http://mycomp.com/otherScript.gradle'

task configure << {

pos = new java.text.FieldPosition(10)

// Apply the script.

apply from: 'position.gradle', to: pos

println pos.beginIndex

println pos.endIndex

}

beginIndex = 1;

endIndex = 5;

position.gradle:

Configuration objects can be externalized:

apply plugin: 'java'

apply plugin: 'groovy'

apply plugin: 'scala'

apply plugin: 'war'

Use many of the standard or 3rd-party plug-ins:

Standard plug-ins Plug-in ID Plug-in ID

base application (java, groovy)

java-base jetty (war)

groovy-base maven (java, war)

scala-base osgi (java-base, java)

reporting-base war (java)

java (java-base) code-quality (reporting-base, java,

groovy)

groovy (java, groovy-base) eclipse (java, groovy, scala, war)

scala (java, scala-base) idea (java)

antlr (java) project-report (reporting-base)

announce sonar

READING MATERIAL

Literature

http://shop.oreilly.com/product/0636920019909.do

“Build and test software written in Java and

many other languages with Gradle, the open

source project automation tool that’s getting

a lot of attention. This concise introduction

provides numerous code examples to help

you explore Gradle, both as a build tool and

as a complete solution for automating the

compilation, test, and release process of

simple and enterprise-level applications .”

QUESTIONS?