75
Gradle Workshop

Gradle Workshop - Rich Web Experience · The Workshop Slides (you have a copy in the zip) Practical labs Ask questions. The Labs Pairing is encouraged ... Gradle build scripts are

  • Upload
    vocong

  • View
    214

  • Download
    0

Embed Size (px)

Citation preview

Gradle Workshop

The WorkshopSlides (you have a copy in the zip)

Practical labs

Ask questions

The LabsPairing is encouraged

Solutions are available (but avoid cheating)

Take your time and experiment

First lab is Gradle installation/setup.

ObjectivesGradle introduction

Cover fundamental concepts

Go beyond Gradle buildsusing

Look at some of the newer features

AgendaThe Gradle Project

Groovy and Gradle Basics

Tasks

Task Inputs/Outputs

Plugins

Java Plugin

Feature Tour

Dependency Management (time permitting)

GradleIntroduction

GradleGradle is a build tool with a focus on whole project automation and support for multi-languagedevelopment.

Created in 2008

Implemented in Java (Groovy outer layer)

100% Free Open Source - Apache Standard License 2.0

GradlewareThe company behind Gradle.

Employs full time engineers

Gradle consulting, support, development services etc.

Training: online, public and in-house

General build automation services

Germany, Australia, Austria, Switzerland, Sweden, Czech Republic, UK, Canada and the US.

http://www.gradleware.com

Gradle ProjectOpen Source (Apache v2 license), free to use and modify

Source code at github.com/gradle/gradle

Community centered around forums.gradle.org

Gradle Documentationhttp://gradle.org/documentation

User Guide

300+ pages, many complete samples

In depth explanations, introductions

single page HTML

multi page HTML

PDF

DSL Reference ( )gradle.org/docs/current/dsl/

API reference

Frequently accessed

Links through to Javadoc

Gradle Downloadshttp://gradle.org/downloads

-bin distribution contains just the runtime.

-all distribution contains the runtime, source, and all documentation.

Gradle 2.2Released on Nov 10th, 2014

Latest version

Used in this workshop.

Lab01-setup

Groovy andGradle Basics

GroovyModern scripting language for the JVM

Design goal is to be easily picked up by Java developers

Reuse of Java semantics and API

Compiles to byte code

Groovy Language FeaturesDynamic and optional static typing

Compile time and runtime metaprogramming

Operator overloading (e.g, , , on collections)<< += -=

Removes a lot of Java syntax noise (no semicolons etc.)

First-class properties

Closures (cf. Ruby blocks, Javascript functions, Java 8 lambdas)

Many JDK library enhancements

More GroovyGroovy has many uses outside Gradle.

Particularly good for testing Java code.

Groovy In Action (2nd Ed) is a great source for more Groovy goodness.

Groovy and GradleGradle is implemented in Java, with an outer Groovy layer.

Gradle build scripts are written in a Groovy-based DSL.

Gradle tasks and plugins be written in Groovy.can

apply plugin: "java"

description = "My first Gradle build"

version = 1.0

repositories {

  mavenCentral()

}

dependencies {

  compile "org.springframework:spring-core:4.0.5.RELEASE"

}

test {

  jvmArgs "-Xmx1024m"

}

Gradle Build ScriptsNamed by defaultbuild.gradle

Must be valid Groovy syntax

Can’t be executed by plain Groovy runtime

Are backed by a objectorg.gradle.api.Project

// does not compile:

println 'Gradle

// compiles, fails when run with Groovy or Gradle:

println zipCode

// compiles, fails when run with plain Groovy:

println name

Tasks

TasksTasks are the basic unit of work in Gradle.

Declared & configured by build scripts and plugins

Executed by Gradle

task helloWorld {

  doLast {

    println "Hello World!"

  } 

}

task is a keyword in the Gradle DSL.

All tasks implement the interface.Task

Task ActionsTasks have a of actions.list

task helloWorld {

  doLast { 

    println "World!"

  }

  doFirst {

    println "Hello" 

  }

}

Executing a task means executing all of its actions (in order).

Most tasks have one useful main action.

doFirst() and can be used to further decorate this action.doLast()

Executing TasksExecute tasks by specifying them on the command line.

$ gradle helloWorld

:helloWorld

Hello world!

Abbreviated Task NameExecutionTask names can be abbreviated on the command line.

task myNameIsPrettyLong {

  doLast {

    println "Long name"

  }

}

task someOtherTask {

  doLast {

    println "Other task"

  }

}

//running:

$ gradle mNIPL sOtherT

Characters between word boundaries can be dropped.

Task DependenciesA task may require other tasks to run (i.e. or something) before it can runproduce do

Tasks and their dependencies form a directed acyclic graph (DAG)

task compileJava

task processResources

task jar { 

  dependsOn compileJava

  dependsOn processResources

}

Task TypesMost tasks explicitly specify a type.

task copyFiles(type: Copy) { 

  // configure the task

}

Task types (e.g. ) provide a task action and a configuration API.Copy

The default task type is , and does not have an action.DefaultTask

Task APItask helloWorld { 

  onlyIf { System.getProperty("be.nice") == "true" }

  doLast { println "Hello" }

}

The and methods are available for all tasks (i.e. are part of the onlyIf() doLast() Task

interface).

task copyFiles(type: Copy) { 

  from "sourceDir"

  into "targetDir"

}

The and methods are only available for tasks.from() into() Copy

The task's API allows the task to be .configured

Implementing Task TypesPOJO extending DefaultTask

Declare action with @org.gradle.api.tasks.TaskAction

class FtpTask extends DefaultTask { 

  String host = 'docs.mycompany.com'

  @TaskAction 

  void ftp() { 

    // do something complicated

  }     

}

Lab02-custom-tasks

Build LifecycleInitialization Phase

Configure environment (init.gradle, gradle.properties)

Find projects and build scripts (settings.gradle)

Configuration Phase

Evaluate all build scripts

Build object model (Gradle -> Project -> Task, etc.)

Build task execution graph

Execution Phase

Execute (subset of) tasks

A concept to grasp.key

Lab03-build-lifecycle

Quick QuizBonus question: What's happening here?

task bar {

  doLast {

    dependsOn foo

  }

}

Will execute before ?foo bar

TaskInputs/Outputs

Modeling tasks as functions

Inputs and OutputsMost tasks can be described as functions

Inputs : Files, configuration values Outputs: Files

Modeling inputs and outputs enables powerful features:

Do not rerun tasks that would produce the same outputs.

Infer task dependency if one task's output becomes another task's input.

Validate that task inputs exist before running a task.

Create output directories that don't exist.

Clean all outputs of a particular task.

Etc.

Built-in task types already describe their inputs and outputs.

When implementing a custom task type, tell Gradle what its inputs and outputs are.

Input/Output Annotationsclass MyTask extends DefaultTask {

  @InputFile File text

  @InputFiles FileCollection path

  @InputDirectory File templates

  @Input String mode

  @OutputFile File result

  @OutputDirectory transformedTemplates

  boolean verbose // ignored

  @TaskAction

  generate() { ... }

}

Incremental BuildingA task can be skipped (UP-TO-DATE) if:

Inputs have not changed since last run

Outputs are still there and haven't changed

Change detection is content (not time) based:

Input/output files are hashed

Content of input/output dirs is hashed

Values of input properties are serialized

Dependency InferenceMany Gradle types (e.g. and ) implement .FileCollection ProjectDependency Buildable

Any task input that is creates inferred task dependencies.Buildable

task generateFiles {

  outputs.dir = "$buildDir/generated-files" // same as @OutputDirectory

  doLast { /* generate files */ }

}

compileJava {

  classpath += generateFiles.outputs.files // -> generateFiles

}

task copy(type: Copy) {

  from generateFiles // -> generateFiles

  into "someDir"

}

jar {

  from sourceSets.main.output // -> compileJava, processResources

  from sourceSets.test.output // -> compileTestJava, processTestResources

}

Lab04-task-input-output

Plugins

PluginsPlugins are reusable build logic.

They can do everything a build script can do (and vice versa):

Configure defaults

Add and configure tasks

Extend the build language

Etc.

Script plugins are applied by path:

apply from: "$rootDir/gradle/integration-test.gradle"

Binary plugins are applied by ID:

apply plugin: "java"

External PluginsNeed to be declared as dependencies.build script

buildscript {

  repositories {

    mavenCentral()

  }

  dependencies {

    classpath "org.hidetake:gradle-ssh-plugin:0.3.7"

  }

}

apply plugin: "ssh"

Standard Gradle PluginsGradle ships with many useful plugins.

Some examples:

java - compile, test, package, upload Java projects

checkstyle - static analysis for Java code

maven - uploading artifacts to Apache Maven repositories

scala - compile, test, package, upload Scala projects

idea and - generates metadata so IDEs understand the projecteclipse

application - support packaging your Java code as a runnable application

c / - support building native binaries using gcc, clang or visual-cppcpp

Many more, .listed in the Gradle User Guide

The Java Plugin

Java PluginThe basis of Java development with Gradle.

Introduces concept of source sets

“main” and “test” source set conventions

Compilation pre-configured

Dependency management

JUnit & TestNG testing

Produces single JAR

JavaDoc generation

Publishing (Maven or Ivy format)

IDE integration

Standard lifecycle/interface

Source SetsA logical compilation/processing unit of sources.

Java source files

Non compiled source files (e.g. properties files)

Classpath (compile & runtime)

Output class files

Compilation tasks

sourceSets {

  main {

    java {

      srcDir "src/main/java" // default

    }

    resources {

      srcDir "src/main/resources" // default

    }

  }

}

Lifecycle TasksThe plugin provides a set of “lifecycle” tasks for common tasks.java

clean - delete all build output

classes - compile code, process resources

test - run tests

assemble - make all archives (e.g. zips, jars, wars etc.)

check - run all quality checks (e.g. tests + static code analysis)

build - combination of & assemble check

TestingBuilt in support for JUnit and TestNG.

Pre-configured “test” task

Automatic test detection

Forked JVM execution

Parallel execution

Configurable console output

Human and CI server friendly reports

Lab05-java-plugin

Feature TourA small selection of useful features.

Gradle WrapperA way to bootstrap Gradle installations.

$ gradle wrapper

gradle

gradle-wrapper.jar

gradle-wrapper.properties

gradlew

gradlew.bat

$ ./gradlew build

Build DaemonMakes builds start faster.

Enable with

--daemon command line option

org.gradle.daemon=true in gradle.properties

-Dorg.gradle.daemon=true in GRADLE_OPTS

Force shutdown with gradle --stop

Will be used in the future for more optimization.

Init PluginCreate build from template, convert Maven build.

$ gradle init --type java-library

$ gradle init --type pom

Continue after Failure$ gradle build --continue

Especially useful for CI builds.

Parallel BuildsRun independent tasks from different projects in parallel.

$ gradle build --parallel

Incubating feature; some restrictions apply.

Q&AThank you for attending the workshop

Questions?

Feedback?

http://gradle.org

http://gradleware.com

http://www.gradle.org

DependencyManagement

Dependency ManagementGradle supports managed and unmanaged dependencies.

“Managed” dependencies have identity and possibly metadata.

“Unmanaged” dependencies are just anonymous files.

Managed dependencies are superior as their use can be automated and reported on.

Unmanaged Dependenciesdependencies {

  compile fileTree(dir: "lib", include: "*.jar")

}

Can be useful during migration.

Managed Dependenciesdependencies {

  compile "org.springframework:spring-core:4.0.5.RELEASE"

  compile group: "org.springframework", name: "spring-web", version: 

"4.0.5.RELEASE"

}

Group/Module/Version

ConfigurationsDependencies are assigned to .configurations

configurations {

  // default with `java` plugin

  compile

  runtime

  testCompile

  testRuntime

}

dependencies {

  compile "org.springframework:spring-core:4.0.5.RELEASE"

}

See in DSL reference.Configuration

Transitive DependenciesGradle (by default) fetches dependencies of your dependencies. This can introduce versionconflicts.

Only one version of a given dependency can be part of a configuration.

Options:

Use default strategy (highest version number)

Disable transitive dependency management

Excludes

Force a version

Fail on version conflict

Dependency resolution rules

Disable TransitivesPer dependency…

dependencies {

  compile("org.foo:bar:1.0") {

    transitive = false

  }

}

Configuration-wide…

configurations {

  compile.transitive = false

}

ExcludesPer dependency…

dependencies {

  compile "org.foo:bar:1.0", {

    exclude module: "spring-core"

  }

}

Configuration-wide…

configurations {

  compile {

    exclude module: "spring-core"

  }

}

Version ForcingPer dependency…

dependencies {

  compile("org.springframework:spring-core:4.0.5.RELEASE") {

    force = true

  }

}

Configuration-wide…

configurations {

  compile {

    resolutionStrategy.force "org.springframework:spring-core:4.0.5.RELEASE"

  }

}

Fail on ConflictAutomatic conflict resolution can be disabled.

configurations {

  compile {

    resolutionStrategy.failOnVersionConflict()

  }

}

If disabled, conflicts have to be resolved manually (using force, exclude etc.)

Cross Configuration RulesConfiguration level rules can be applied to all configurations.

configurations {

  all {

    resolutionStrategy.failOnVersionConflict()

  }

}

all is a special keyword, meaning all things in the configuration container.

Dependency CacheDefault location: .~/.gradle/caches/…

Multi process safe

Source location aware

Optimized for reading (finding deps is fast)

Checksum based storage

Avoids unnecessary downloading

Finds local candidates

Uses checksums/etags

An opaque cache, not a repository.

Changing DependenciesChanging dependencies are mutable.

Version numbers ending in are changing by default.-SNAPSHOT

dependencies {

  compile "org.company:some-lib:1.0-SNAPSHOT"

  compile("org:somename:1.0") {

    changing = true

  }

}

Default TTL is 24 hours.

Dynamic DependenciesDynamic dependencies do not refer to concrete versions.

Can use Ivy symbolic versions.

dependencies {

  compile "org.company:some-lib:2.+"

  compile "org:somename:latest.release"

}

Default TTL is 24 hours.

Controlling Updates & TTLconfigurations.all {

  resolutionStrategy.cacheChangingModulesFor 4, "hours"

  resolutionStrategy.cacheDynamicVersionsFor 10, "minutes"

}

--offline - don't look for updates, regardless of TTL

--refresh-dependencies - look for updates, regardless of TTL

Dependency ReportsView the dependency graph.

$ gradle dependencies [--configuration «name»]

View a dependency in the graph.

$ gradle dependencyInsight --dependency «name» [--configuration «name»]

Built in tasks.

RepositoriesAny Maven/Ivy repository can be used

Very flexible layouts are possible for Ivy repositories

repositories {

  jcenter()

  mavenCentral()

  maven {

    name "codehaus"

    url "http://repository.codehaus.org"

  }

  ivy {

    url "http://repo.mycompany.com"

    layout "gradle" // default

  }

  flatDir(dirs: ["dir1", "dir2"])

}

Lab06-dependencies

UploadingUpload your artifacts to any Maven/Ivy repository

ivy.xml/pom.xml is generated

Repository metadata (e.g. maven-metadata.xml) is generated

Uploading to Maven Repositoriesapply plugin: "maven"

uploadArchives {

  repositories {

    mavenDeployer {

      repository(url: "http://my.org/m2repo/")

    }

  }

}

Provided by the pluginmaven

All Maven wagon protocols can be used

For Artifactory, JFrog provides an pluginartifactory-publish