Gradle For Beginners (Serbian Developer Conference 2013 english)

24
Gradle for Beginners Coding Serbia, 18.10.2013 Joachim Baumann

description

A Step-By-Step Introduction to Gradle leading to a full build script for a project.

Transcript of Gradle For Beginners (Serbian Developer Conference 2013 english)

Page 1: Gradle For Beginners (Serbian Developer Conference 2013 english)

Gradle for Beginners

Coding Serbia, 18.10.2013

Joachim Baumann

Page 2: Gradle For Beginners (Serbian Developer Conference 2013 english)

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

Page 3: Gradle For Beginners (Serbian Developer Conference 2013 english)

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

Page 4: Gradle For Beginners (Serbian Developer Conference 2013 english)

What do we wish for in our Build-Management System?

•  Explicit Support of the Workflow implemented by the Build-Management-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

Page 5: Gradle For Beginners (Serbian Developer Conference 2013 english)

build

assemble

testcompileTest

compile

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

Page 6: Gradle For Beginners (Serbian Developer Conference 2013 english)

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"

Page 7: Gradle For Beginners (Serbian Developer Conference 2013 english)

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

build

assemble

testcompileTest

compile

Page 8: Gradle For Beginners (Serbian Developer Conference 2013 english)

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 }

Page 9: Gradle For Beginners (Serbian Developer Conference 2013 english)

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

Page 10: Gradle For Beginners (Serbian Developer Conference 2013 english)

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’

Page 11: Gradle For Beginners (Serbian Developer Conference 2013 english)

Our first Project

•  We use the Java Plug-in

•  Default paths used by the Java Plug-in

–  Derived from Maven Conventions

Page 12: Gradle For Beginners (Serbian Developer Conference 2013 english)

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; }

}

Page 13: Gradle For Beginners (Serbian Developer Conference 2013 english)

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'

Page 14: Gradle For Beginners (Serbian Developer Conference 2013 english)

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()); }

}

Page 15: Gradle For Beginners (Serbian Developer Conference 2013 english)

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.+’ }

Page 16: Gradle For Beginners (Serbian Developer Conference 2013 english)

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

Page 17: Gradle For Beginners (Serbian Developer Conference 2013 english)

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 zip-archive

–  Definition of the Main Class mainClassName = "de.gradleworkshop.HelloWorld"

–  Usage with apply plugin: 'application'

Page 18: Gradle For Beginners (Serbian Developer Conference 2013 english)

Using TestNG

•  Very Simple

dependencies { testCompile group: 'org.testng', name: 'testng',

version: '6.+' } test {

useTestNG() }

Page 19: Gradle For Beginners (Serbian Developer Conference 2013 english)

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()); }

}

Page 20: Gradle For Beginners (Serbian Developer Conference 2013 english)

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 } }

Page 21: Gradle For Beginners (Serbian Developer Conference 2013 english)

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/") } }

}

Page 22: Gradle For Beginners (Serbian Developer Conference 2013 english)

The whole Script (less than 20 lines)

apply plugin: 'java' apply plugin: 'pmd' jar.manifest.attributes 'Main-Class': 'de.gradleworkshop.HelloWorld' pmdMain {

ruleSets = [ "basic", "strings" ] ignoreFailures = true

} repositories { mavenCentral() } dependencies {

testCompile group: 'junit', name: 'junit', version: '4.+' } apply plugin: ‘maven’ version = '0.1-SNAPSHOT’ group = 'de.gradleworkshop’ uploadArchives {

repositories { flatDir { dirs "repo" } mavenDeployer { repository (url : "file:///gradleWS/myRepo/")

} } }

Page 23: Gradle For Beginners (Serbian Developer Conference 2013 english)

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

Page 24: Gradle For Beginners (Serbian Developer Conference 2013 english)

Questions?

Dr. Joachim Baumann

codecentric AG

An der Welle 4

60322 Frankfurt

[email protected]

www.codecentric.de

blog.codecentric.de

24