![Page 1: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/1.jpg)
CZJUG 2009
Gradle
Hans Dockter
Gradle Project Manager
1
![Page 2: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/2.jpg)
About Me
Founder and Project Lead of Gradle
CEO of Gradle Inc.
In the old days: Committer to JBoss (Founder of JBoss-IDE)
2
![Page 3: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/3.jpg)
Gradle BackgroundVery active community (mailing-list, patches, issues, ...)
Apache v2 license.
Excellent Documentation (200+ pages user’s guide)
Frequent releases (Every 2 months)
Quality is king:
2800 unit tests, Many integration test
Healthy codebase
A Groovy DSL but a Java core
Commiter -> Steve Appling, Hans Dockter, Tom Eyckmans, Adam Murdoch, Russel Winder
3
![Page 4: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/4.jpg)
Live Demo Java Project
4
![Page 5: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/5.jpg)
5
Dependency Based Programmingtask hello << { println 'Hello world!'}
task intro(dependsOn: hello) << { println "I'm Gradle"}
4.times { counter -> task "task_$counter" << { println "I'm task $counter" }}
> gradle hello task1Hello world!I’m task 1
![Page 6: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/6.jpg)
Rich API
6
task helloprintln hello.namehello.dependsOn distZiphello << { println ‘Hello’ }
task distZip(type: Zip)distZip.fileSet(dir: ‘somePath’)distZip.baseName = hello.name
![Page 7: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/7.jpg)
Very Rich API: Test Task
Register listeners for test execution (this works even in forked mode)
Get informed about a started test execution
Get informed about a failing or succeeding test
Provides an API to ask for execution results.
Part of Gradle 0.9
7
![Page 8: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/8.jpg)
8
One way configuration Ant
<target name="test" depends="compile-test"> <junit> <classpath refid="classpath.test" /> <formatter type="brief" usefile="false" /> <test name="${test.suite}"/> </junit></target>
![Page 9: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/9.jpg)
9
One way configuration Maven
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.4.2</version> <configuration> <includes> <include>Sample.java</include> </includes> </configuration></plugin>
![Page 10: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/10.jpg)
Plugins
Java, Groovy, Scala (including mixed compilation)
War, Jetty
Code-Quality (Checkstyle, Codenarc)
OSGi
Maven
Eclipse project file generation
10
![Page 11: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/11.jpg)
Custom Plugins
11
public class CustomPlugin implements Plugin { public void use(final Project project, ProjectPluginsContainer plugins) { project.myProperty = ‘myValue’ plugins.withType(JavaPlugin).allPlugins { project.getTasks().add(‘someName’, SomeType.class) } plugins.withType(WarPlugin.class).allPlugins { // do something with the project } }
![Page 12: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/12.jpg)
Deep API
12
tasks.whenTaskAdded { task -> task.description = ‘This is a new task’}
tasks.allTasks { task -> task.description = ‘I am new or old’}
tasks.withType(Zip).whenTaskAdded { task -> task.fileSet(dir: ‘someDir’)}
liveLibs = tasks.withType(Jar)task someJar(type: Jar)println liveLibs.all // prints [‘someJar’]
![Page 13: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/13.jpg)
Rules
13
tasks.addRule("Pattern: ping<ID>") { String taskName -> if (taskName.startsWith("ping")) { task(taskName) << { // add task println "Pinging: " + (taskName - 'ping') } }}task groupPing { dependsOn pingServer1, pingServer2}
> gradle pingServer545Server545
> gradle groupPingServer1Server2
![Page 14: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/14.jpg)
Dependency Management 1
14
usePlugin(‘java’) ...configurations { allJar.extends runtime}
dependencies { compile "commons-lang:commons-lang:3.1", "org.hibernate:hibernate:3.2" runtime “mysql:mysql-connector-java:5.1.6” testCompile "junit:junit:4.4" allJar "commons-io:commons-io:1.4"}...task jarAll(type: Jar) { merge(dependencies.allJar.resolve())}
![Page 15: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/15.jpg)
Dependency Management 2
15
usePlugin(‘java’) ...
dependencies { compile "commons-lang:commons-lang:3.1", "org.hibernate:hibernate:3.2" runtime “mysql:mysql-connector-java:5.1.6” testCompile "junit:junit:4.4" }...task showDeps << { println(configurations.runtime.files { dep -> dep.group == ‘myGroup’ })}
![Page 16: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/16.jpg)
Dependency Management 3
Excludes per configuration or dependency
You can define rules for configuration and dependencies (as for tasks)
Very flexible repository handling
Retrieve and deploy from/to Maven repositories
Dependencies can have dynamic properties
And much more
16
![Page 17: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/17.jpg)
Using Ant Tasks
17
ant { taskdef name: "groovyc", classname: "org.groovy.ant.Groovyc" groovyc srcdir: "src", destdir: "${webinf}/classes", { classpath {! fileset dir: "lib" {! include name: "*.jar" }! pathelement path: "classes" } javac source: "1.5", target: "1.5", debug: "on" }}
![Page 18: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/18.jpg)
Deep Integration with Ant Builds
18
ant.importBuild 'build.xml'
hello.doFirst { println 'Here comes Ant' }task intro << { println 'Hello, from Gradle'}
<project> <target name="hello" depends="intro"> <echo>Hello, from Ant</echo> </target></project>
> gradle helloHello, from Gradle...Here comes Ant...[ant:echo] Hello, from Ant
![Page 19: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/19.jpg)
Smart and Configurable Execution
19
![Page 20: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/20.jpg)
Deep API
20
usePlugin(‘java’) ...compile.doFirst { compileTask -> println build.taskGraph.allTasks if (build.taskGraph.hasTask(‘codeGeneration’)) { compileTask.exclude ‘com.mycomp.somePackage’ }}
build.taskGraph.beforeTask { task -> println “I am executing now $task.name”}
build.taskGraph.afterTask { task, exception -> if (task instanceof Jetty && exception != null) { // do something }}
![Page 21: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/21.jpg)
Smart Task Exclusion
21
A
B
D
C
E
gradle A -x B executes: A, E
![Page 22: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/22.jpg)
Smart Merging
22
test
compile
clean
resources
> gradle clean compile test
> gradle clean compile; gradle test
![Page 23: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/23.jpg)
23
Camel Case Execution
task myNameIsPrettyLong << { println 'Long name'}
task someOtherTask(dependsOn: myNameIsPrettyLong) << { println "Other task"}
> gradle sOtT -x mNIPOther task
![Page 24: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/24.jpg)
Smart Skip & Incremental Work
24
A reliable build without clean.
Only do what is necessary (e.g. incremental compile).
We will have a generic approach that also works for custom tasks.
![Page 25: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/25.jpg)
Multi-Core and Distributed Builds
Gradle 0.9 comes with multi-threaded test execution.
After that:
Distributed test execution.
Multi-Threaded Build Execution
Distributed Build Execution
25
![Page 26: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/26.jpg)
Multi-Project Builds
Arbitrary Multiproject Layout
Configuration Injection
Separate Config/Execution Hierarchy
Partial builds
26
![Page 27: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/27.jpg)
Configuration InjectionultimateApp
api webservice shared
27
subprojects { usePlugin(‘java’) dependencies { compile "commons-lang:commons-lang:3.1" testCompile "junit:junit:4.4" } test { exclude '**/Abstract*' } }
![Page 28: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/28.jpg)
Separation of Config/Exec ultimateApp
api webservice shared
28
dependsOnChildren()subprojects { usePlugin(‘java’) dependencies { compile "commons-lang:commons-lang:3.1" testCompile "junit:junit:4.4" } }
task dist(type: Zip) << { subprojects.each { subproject -> files(subproject.jar.archivePath) }}
![Page 29: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/29.jpg)
Dependencies and Partial BuildsultimateApp
api webservice shared
29
dependencies { compile "commons-lang:commons-lang:3.1", project(‘:shared’)}
Support for build, buildNeeded, buildDependent
![Page 30: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/30.jpg)
Maven
30
![Page 31: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/31.jpg)
31
Convention instead of Configuration
![Page 32: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/32.jpg)
Frameworkitis ...
32
... is the disease that a framework wants to do too much for you or it does it
in a way that you don’t want but you can’t change it. It’s fun to get all this
functionality for free, but it hurts when the free functionality gets in the way.
But you are now tied into the framework. To get the desired behavior you
start to fight against the framework. And at this point you often start to lose,
because it’s difficult to bend the framework in a direction it didn’t anticipate.
Toolkits do not attempt to take control for you and they therefore do not
suffer from frameworkitis.
(Erich Gamma)
![Page 33: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/33.jpg)
Solution
33
Because the bigger the framework becomes, the greater the chances that it
will want to do too much, the bigger the learning curves become, and the
more difficult it becomes to maintain it. If you really want to take the risk of
doing frameworks, you want to have small and focused frameworks that
you can also probably make optional. If you really want to, you can use the
framework, but you can also use the toolkit. That’s a good position that
avoids this frameworkitis problem, where you get really frustrated because
you have to use the framework. Ideally I’d like to have a toolbox of smaller
frameworks where I can pick and choose, so that I can pay the framework
costs as I go.(Erich Gamma)
![Page 34: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/34.jpg)
Build Languageinstead of
Build Framework
34
![Page 35: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/35.jpg)
Organizing Build Logic
No unnecessary indirections
If build specific:
Within the script
Build Sources
Otherwise: Jar
35
![Page 36: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/36.jpg)
36
> gradle --gui
![Page 37: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/37.jpg)
Gradle Wrapper
Use Gradle without having Gradle installed
Useful for CI and open source projects
37
![Page 38: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/38.jpg)
Gradle 0.9
38
![Page 39: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/39.jpg)
39
Questions
![Page 40: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/40.jpg)
40
Thereareno
simple builds
![Page 41: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/41.jpg)
Project Automation
A build can do far more than just building the jar
Often repetitive, time consuming, boring stuff is still done manually
Many of those tasks are very company specific
Maven & Ant are often not well suited for this
41
![Page 42: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/42.jpg)
The Gradle Build
Gradle is build with Gradle
Automatic release management
Automatic user’s guide generation
Automatic distribution
Behavior depends on task execution graph
42
![Page 43: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/43.jpg)
Release Management
The version number is automatically calculated
The distribution is build and uploaded to codehaus
For trunk releases, a new svn branch is created.
A tag is created.
A new version properties file is commited.
The download links on the website are updated
43
![Page 44: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/44.jpg)
User’s Guide
The user’s guide is written in DocBook and generated by our build
The source code examples are mostly real tests and are automatically included
The expected output of those tests is automatically included.
The tests are run
The current version is added to the title
44
![Page 45: CZJUG 2009 Gradle · The source code examples are mostly real tests and are automatically included The expected output of those tests is automatically included. The tests are run](https://reader033.vdocuments.us/reader033/viewer/2022060415/5f1323db40e60153777f0edf/html5/thumbnails/45.jpg)
Uploading & Execution Graph
Based on the task graph we set:
Upload Destination
Version Number
45