Gradle Introduction
-
Upload
neueda -
Category
Technology
-
view
2.838 -
download
1
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
Resources
http://www.gradle.org ◦ /tutorials
◦ /current/docs/userguide/userguide.html
◦ /current/docs/dsl/index.html
http://groovy.codehaus.org
◦ /gapi/
◦ /groovy-jdk/
◦ /User+Guide
http://ant.apache.org/manual
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?