2. Gradle for Beginners
â˘âŻ
Build-Management
â⯠Needs
â⯠Wishes
â˘âŻ
Gradle - Basics
â˘âŻ
ConďŹguration and Execution Phase
â˘âŻ
Groovy â Short Overview
â˘âŻ
Plug-ins â Basics
â˘âŻ
Our
ââŻ
ââŻ
ââŻ
ââŻ
ââŻ
ââŻ
First Project
Directory Structure
Dependencies
Manipulating the Jar
Tests
Quality Assurance
Publishing the Artefacts
3. What do we need from a Build-Management System?
â˘âŻ
â˘âŻ
â˘âŻ
â˘âŻ
â˘âŻ
â˘âŻ
â˘âŻ
â˘âŻ
â˘âŻ
â˘âŻ
Translating the Source Code (using a compiler)
Linking the Results
Check out the source code from a repository (optional)
Creating Tags (optional)
Execution of different types of tests: Examples:
â⯠Unit Tests for single Classes
â⯠Module or Component Tests
â⯠Integration Tests
â⯠Functional and Non-Functional System Tests
â⯠Automated Acceptance Tests
Detailed Test Reports combining all Test Results (optional)
Packing the Result (e.g., into a Jar, War or Ear)
Transfer the Results to the different Stages / Test Systems and Execution of
the respective Tests (optional)
Support for multi-language Projects
Creation of Documentation and Release Notes
4. What do we wish for in our Build-Management System?
â˘âŻ Explicit Support of the WorkďŹow implemented by the BuildManagement-System
â˘âŻ Simple ModiďŹability and Extensibility of the WorkďŹow to adapt to
local processes
â˘âŻ Readability and self-documentation of the notation in the build
script
â˘âŻ Use of sensible conventions (e.g., where to ďŹnd the sources)
â˘âŻ Simple change of the conventions to adap to local environment
â˘âŻ Incremental Build that can identify artefacts that have already
been built
â˘âŻ Parallelisation of independent steps in the workďŹow to minimize
waiting
â˘âŻ Programmatic access to all artefacts being created by the build
â˘âŻ Status reports that summarize the current state of the build
5. Gradle - Basics
â˘âŻ
Gradle uses build scripts which are named build.gradle
â˘âŻ
Every build script is a Groovy script
â˘âŻ
Two very important Principles
â⯠Convention over ConďŹguration
â⯠Donât Repeat Yourself
â˘âŻ
Gradle creates a dynamic model of the workďŹow as a Directed Acyclic Graph
(DAG)
â˘âŻ
(Nearly) Everything is convention and can be changed
tset
tseTelipmoc
dliub
elipmoc
elbmessa
6. ConďŹguration Phase
â˘âŻ
â˘âŻ
â˘âŻ
â˘âŻ
Executes the build script
The contained Groovy- and DSL-commands conďŹgure the underlying
object tree
The root of the object tree is the Project object
â⯠Is directly available in the script (methods and properties)
Creation of new Tasks that can be used
Manipulation of the DAG
â˘âŻ
Our ďŹrst script build.gradle
â˘âŻ
println âHello from the configuration phase"
7. Execution Phase
â˘âŻ
Executes all tasks that have been called (normally on the command line)
â˘âŻ
For a task that is executed every task it depends on is executed beforehand
â˘âŻ
Gradle uses the DAG to identify all task relationships
tset
tseTelipmoc
dliub
elipmoc
elbmessa
8. Task DeďŹnition
â˘âŻ
â˘âŻ
Takes an (optional) conďŹguration closure
Alternatively: can be conďŹgured directly
â˘âŻ
â˘âŻ
The operator << (left-shift) appends an action (a closure) to this taskâs list of actions
Equivalent to doLast()
â˘âŻ
Insert at the beginning of the list with doFirst()
task halloTask
halloTask.doLast { print "from the " }
halloTask << { println "execution phase" }
halloTask.doFirst { print "Hello " }
task postHallo (dependsOn: halloTask) << {
println "End"
}
postHallo { // configuration closure
dependsOn halloTask
}
9. Groovy â Short Overview
â˘âŻ
SimpliďŹed Java Syntax
â⯠Semicolon optional
â⯠GString
â⯠Everything is an Object
â⯠SimpliďŹcation e.g., âprintlnâ
â˘âŻ
Scripts
â˘âŻ
Operator Overloading
â⯠PredeďŹned
â˘âŻ Example <<
â˘âŻ Operator for secure navigation a.?b
â⯠You can provide your own implementations
â˘âŻ
Named Parameters
â˘âŻ
Closures
â˘âŻ
Collection Iterators
10. Plug-ins - Basics
â˘âŻ
Plug-ins encapsulate functionality
â˘âŻ
Can be written in any VM-language
â⯠Groovy is a good choice
â˘âŻ
Possible Plug-in Sources
â⯠Plug-ins packed with Gradle
â⯠Plug-ins included using URLs (donât do it)
â⯠Plug-ins provided by repositories (use your own repository)
â⯠Self-written Plug-ins (normally in the directory buildSrc)
â˘âŻ
Plug-ins
â⯠Extend objects
â⯠Provide new objects and / or abstractions
â⯠ConďŹgure existing objects
â˘âŻ
Plug-ins are load with the command apply plugin
apply plugin: âjavaâ
11. Our ďŹrst Project
â˘âŻ
We use the Java Plug-in
â˘âŻ
Default paths used by the
Java Plug-in
â⯠Derived from Maven
Conventions
12. The Class HelloWorld
package de.gradleworkshop;
import java.util.ArrayList;
import java.util.List;
public class HelloWorld {
public static void main(String[] args) {
HelloWorld hw = new HelloWorld();
for(String greeting : hw.generateGreetingsData())
System.out.println(greeting);
}
public List<String> generateGreetingsData() {
List <String> greetings = new ArrayList <String>();
greetings.add("Hallo Welt");
return greetings;
}
}
13. Manipulation of the Manifest
â˘âŻ
Every Jar-Archive contains a ďŹle MANIFEST.MF
â˘âŻ
Is generated by Gradle (see directory build/tmp/jar/MANIFEST.MF)
â˘âŻ
Contains information e.g., about the main class of the jar
â˘âŻ
Can be changed
jar {
manifest {
attributes 'Main-Class':
'de.gradleworkshop.HelloWorld'
}
}
â˘âŻ
Alternatively
jar.manifest.attributes 'Main-Class':
'de.gradleworkshop.HelloWorld'
14. Tests
package de.gradleworkshop;
import java.util.List;
import org.junit.*;
import static org.junit.Assert.*;
public class HelloWorldTest {
HelloWorld oUT;
@Before
public void setUp() {
oUT = new HelloWorld();
}
@Test
public void testGenerateGreetingsData() {
List<String> res = oUT.generateGreetingsData();
assertEquals("wrong number of results", 1, res.size());
}
}
15. ConďŹgurations and Dependencies
â˘âŻ
Gradle deďŹnes ConďŹguration Objects. These encapsulate
â⯠Dependency Information
â⯠Paths to Sources and Targets
â⯠Associated Artefacts
â⯠Additional ConďŹguration Information
â˘âŻ
Tasks use these ConďŹgurations
â˘âŻ
For most pre-deďŹned Task a ConďŹguration exists
â⯠compile, testCompile, runtime, testRuntime
â˘âŻ
â˘âŻ
Dependencies are deďŹned using the key word dependencies
Maven-like notation for the dependencies
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.+â
}
16. Repositories
â˘âŻ
Repositories provide libraries (normally jar archives)
â˘âŻ
You can deďŹne Ivy or Maven Repositories, both public and private
â˘âŻ
PredeďŹned Repositories
â⯠JCenter
â⯠Maven Central
â⯠Local Maven Repository (~/.m2/repository)
â˘âŻ
Repositories are deďŹned using the keyword repositories
repositories {
mavenLocal()
}
repositories {
jcenter()
mavenCentral()
}
â˘âŻ
Multiple Repositories can be deďŹned
17. The Application Plug-in
â˘âŻ
The Application-Plug-in
â⯠Adds a Task run
â⯠Creates start scripts, that can be used with the Task run
â⯠Creates a Task distZip, that packs all necessary ďŹles into a ziparchive
â⯠DeďŹnition of the Main Class
mainClassName = "de.gradleworkshop.HelloWorld"
â⯠Usage with
apply plugin: 'application'
19. Test Class for TestNG
package de.gradleworkshop;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.*;
public class TestHelloWorld {
HelloWorld oUT;
@BeforeTest
public void setUp() {
oUT = new HelloWorld();
}
@Test
public void testGenerateGreetingsData() {
List<String> res = oUT.generateGreetingsData();
assertEquals("Wrong Number of Entries", 1, res.size());
}
}
20. Quality Assurance
â˘âŻ
Support for PMD, Checkstyle, Findbugs, Emma, Sonar âŚ
â˘âŻ
Example PMD
apply plugin: 'pmd'
pmdMain {
ruleSets = [ "basic", "strings" ]
ignoreFailures = true
}
â˘âŻ
Another Example conďŹguring all Tasks of Type Pmd using withType()
tasks.withType(Pmd) {
ruleSets = [ "basic", "strings" ]
ignoreFailures = true
ruleSetFiles = files('config/pmd/rulesets.xml')
reports {
xml.enabled false
html.enabled true
}
}
21. Publishing the Artefacts
â˘âŻ
Gradle deďŹnes for every ConďŹguration a Task upload<ConďŹguration>
â⯠Builds and publishes the Artefact belonging to the ConďŹguration
â˘âŻ
The Java-Plug-in creates a ConďŹguration archives, which contains all artefacts
created in the Task jar
â⯠uploadArchives is the natural choice for publishing the artefacts
â˘âŻ
Use of the Maven-Plug-in with apply plugin: âmavenâ
â⯠Doesnât use the normal repository (intentionally)
apply plugin: 'maven'
version = '0.1-SNAPSHOT'
group = 'de.gradleworkshop'
uploadArchives {
repositories {
flatDir { dirs "repo" }
mavenDeployer { repository
(url : "file://$projectDir/mavenRepo/") }
}
}
23. Recap
â˘âŻ
We have, with Gradle
â⯠Built an Application
â⯠Created Tests and executed them
â⯠Used an alternative Test Framework TestNG
â⯠Used Quality Assurance
â⯠Uploaded the Artefacts into two Repositories
â˘âŻ
You now know everything to build normal Projects with Gradle
â˘âŻ
Gradle
â⯠Is simple
â⯠Easily understood
â⯠Has sensible conventions
â⯠That can be easily changed
â˘âŻ
Gradle adapts to your needs