2. Gradle for Beginners
•
Build-Management
– Needs
– Wishes
•
Gradle - Basics
•
Configuration 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 Workflow implemented by the BuildManagement-System
• Simple Modifiability and Extensibility of the Workflow to adapt to
local processes
• Readability and self-documentation of the notation in the build
script
• Use of sensible conventions (e.g., where to find 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 workflow 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 Configuration
– Don’t Repeat Yourself
•
Gradle creates a dynamic model of the workflow as a Directed Acyclic Graph
(DAG)
•
(Nearly) Everything is convention and can be changed
tset
tseTelipmoc
dliub
elipmoc
elbmessa
6. Configuration Phase
•
•
•
•
Executes the build script
The contained Groovy- and DSL-commands configure 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 first 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 Definition
•
•
Takes an (optional) configuration closure
Alternatively: can be configured 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
•
Simplified Java Syntax
– Semicolon optional
– GString
– Everything is an Object
– Simplification e.g., “println”
•
Scripts
•
Operator Overloading
– Predefined
• 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
– Configure existing objects
•
Plug-ins are load with the command apply plugin
apply plugin: ‘java’
11. Our first 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 file 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. Configurations and Dependencies
•
Gradle defines Configuration Objects. These encapsulate
– Dependency Information
– Paths to Sources and Targets
– Associated Artefacts
– Additional Configuration Information
•
Tasks use these Configurations
•
For most pre-defined Task a Configuration exists
– compile, testCompile, runtime, testRuntime
•
•
Dependencies are defined 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 define Ivy or Maven Repositories, both public and private
•
Predefined Repositories
– JCenter
– Maven Central
– Local Maven Repository (~/.m2/repository)
•
Repositories are defined using the keyword repositories
repositories {
mavenLocal()
}
repositories {
jcenter()
mavenCentral()
}
•
Multiple Repositories can be defined
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 files into a ziparchive
– Definition 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 configuring 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 defines for every Configuration a Task upload<Configuration>
– Builds and publishes the Artefact belonging to the Configuration
•
The Java-Plug-in creates a Configuration 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