39
Introduction to Gradle Andrey Adamovich Aestas/IT

Gradle Introduction

  • Upload
    neueda

  • View
    2.836

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Gradle Introduction

Introduction to Gradle Andrey Adamovich

Aestas/IT

Page 2: Gradle Introduction

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

Page 3: Gradle Introduction

What’s in this presentation?

Overview

Basic features & principles

Files and file collections

Dependencies

Multiple projects

Plug-ins

Reading material

Questions

Page 4: Gradle Introduction

OVERVIEW

Page 5: Gradle Introduction

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

Page 6: Gradle Introduction

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

Page 7: Gradle Introduction

Advanced features

Parallel unit test execution

Dependency build

Incremental build support

Dynamic tasks and task rules

Gradle daemon

Page 8: Gradle Introduction

Who uses Gradle?

Hibernate

Grails

Groovy

Spring Integration

Spring Security

Griffon

Gaelyk

Qi4j

Canoo

Carrier

FCC

Zeppelin

GPars

Spock

Aluminum

Gant

Page 9: Gradle Introduction

BASIC FEATURES & PRINCIPLES

Page 10: Gradle Introduction

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:

Page 11: Gradle Introduction

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

Page 12: Gradle Introduction

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:

Page 13: Gradle Introduction

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

Page 14: Gradle Introduction

Java plug-in tasks

compileJava processResources

classes javadoc

compileTestJava processTestResources

testClasses

test

check

build

clean

jar

uploadArchives

assemble

Page 15: Gradle Introduction

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)

}

Page 16: Gradle Introduction

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

Page 17: Gradle Introduction

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

}

}

Page 18: Gradle Introduction

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')

}

Page 19: Gradle Introduction

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

Page 20: Gradle Introduction

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

Page 21: Gradle Introduction

FILES AND FILE COLLECTIONS

Page 22: Gradle Introduction

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:

Page 23: Gradle Introduction

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

Page 24: Gradle Introduction

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:

Page 25: Gradle Introduction

DEPENDENCY MANAGEMENT

Page 26: Gradle Introduction

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]')

}

}

Page 27: Gradle Introduction

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

}

Page 28: Gradle Introduction

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

}

}

Page 29: Gradle Introduction

MULTI-PROJECT BUILDS

Page 30: Gradle Introduction

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

Page 31: Gradle Introduction

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

Page 32: Gradle Introduction

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

Page 33: Gradle Introduction

PLUGINS

Page 34: Gradle Introduction

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:

Page 35: Gradle Introduction

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

Page 36: Gradle Introduction

READING MATERIAL

Page 38: Gradle Introduction

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

Page 39: Gradle Introduction

QUESTIONS?