© Adam L. Davis 2016

Adam L. Davis, Learning Groovy, 10.1007/978-1-4842-2117-4_12

12. Gradle

Adam L. Davis

(1)New York, USA

Gradle is a Groovy-based DSL for building projects. The Gradle web site describes it as follows:

  • Gradle combines the power and flexibility of Ant with the dependency management and conventions of Maven into a more effective way to build. Powered by a Groovy DSL and packed with innovation, Gradle provides a declarative way to describe all kinds of builds through sensible defaults. -gradle.org (2015)1

Projects and Tasks

Each Gradle build is composed of one or more projects and each project is composed of tasks. The core of the Gradle build is the build.gradle file (which is called the build script).

To try it out, go to gradle.org and install Gradle. Then create your own build.gradle file.

Tasks can be defined by writing task then a task name followed by a closure. For example:

1   task upper << {
2           String someString = 'test'
3           println "Original: $someString"
4           println "Uppercase: " + someString.toUpperCase()
5   }

Tasks can contain any Groovy code.

Much like in Ant, a task can depend on other tasks, which means they need to be run before the task. You simply call dependsOn with any number of task names as the arguments. For example:

1   task buildApp {
2           dependsOn clean, installApp, processAssets
3   }

You can also use the following alternative syntax:

1   task buildApp(dependsOn: [clean, installApp, processAssets])
A426440_1_En_12_Figa_HTML.jpg Tip

Use the << if your task contains the actual code you want the task to run.

You are adding a closure to the task, not configuring the task. Otherwise, Gradle always runs the code in the first pass, not just when you invoke the task.

Once you’ve defined your tasks, you run them by invoking gradle <task_name> at the command line. There are some built-in tasks. For example, to list all available tasks, invoke the following:

1   gradle tasks

Plugins

Gradle core has very little built-in, but it has powerful plugins to allow it to be very flexible. A plugin can do one or more of the following:

  • Add tasks to the project (e.g., compile and test).

  • Pre-configure added tasks with useful defaults.

  • Add dependency configurations to the project.

  • Add new properties and methods to existing type via extensions.

We’re going to concentrate on building Groovy-based projects, so we'll be using the Groovy plugin (however, Gradle is not limited to Groovy projects!):

1   apply plugin: 'groovy'

This plugin uses Maven's conventions. For example, it expects to find your main source code under src/main/groovy and your test source code under src/test/groovy.

Configuring a Task

Once you've added some plugins, you might want to configure some of the properties of a task for your purposes.

For example, you might want to specify a version of Gradle for the Gradle wrapper task:

1   task wrapper(type: Wrapper) {
2       gradleVersion = '2.2.1'
3   }

The properties available depend on what task you are configuring.

Extra Configuration

To provide extra properties within your Gradle build file, use the ext method. You can define any arbitrary values within the closure and they will be available throughout your project.

You can also apply properties from other Gradle build files. For example:

1   ext {
2       apply from: 'props/another.gradle'
3       myVersion = '1.2.3'
4   }

The properties defined within this closure can be used in your tasks.

Maven Dependencies

Every Java project tends to rely on many open source projects to be built. Gradle builds on Maven so you can easily include your dependencies using a simple DSL, like in the following example:

 1   apply plugin: 'java'
 2   
 3   sourceCompatibility = 1.8
 4   
 5   repositories {
 6           mavenLocal()
 7           mavenCentral()
 8   }
 9  
10      dependencies {
11              compile 'com.google.guava:guava:14.0.1'
12              compile 'org.bitbucket.dollar:dollar:1.0-beta3'
13              testCompile group: 'junit', name: 'junit', version: '4.+'
14              testCompile "org.mockito:mockito-core:1.9.5"
15      }

This build script uses sourceCompatibility to define the Java source code version of 1.8 (which is used during compilation). Next it tells Maven to use the local repository first (mavenLocal), then Maven Central.

In the dependencies block, this build script defines two dependencies for the compile scope and two for testCompile scope. Jars in the testCompile scope are only used by tests, and won't be included in any final products.

The line for JUnit shows the more verbose style for defining dependencies. It also specifies, using +, that the version be 4.0 or greater.

You can also specify your own Maven repository by calling maven with a closure supplying the appropriate parameters (at least an URL). For example (in the repositories section):

1   maven {url "https://oss.sonatype.org/content/repositories/snapshots/" }
2   maven { url = "$nexus/content/groups/public"
3           credentials {
4                   username 'deployment'
5                   password deploymentPassword
6           }
7   }

The second example demonstrates using a secured Maven repository. It also demonstrates using the variables nexus and deploymentPassword which could (probably should) be stored in a gradle.properties file.

Gradle Properties

The gradle.properties file allows you to specify Gradle properties and other properties available to your build script. For example, you can specify JVM arguments and whether you want to use the Gradle daemon (which runs in the background and speeds up subsequent Gradle builds):

1   org.gradle.daemon=true          
2   org.gradle.jvmargs=-Xms128m -Xmx512m

You could also specify build specific values that you don't want to keep in your versioning system (such as Nexus credentials, for example).

Multiproject Builds

A multiproject build can include any number of sub-projects that are built together. Each sub-project should be put in a directory under a single top directory, where the name of each directory is the name of the sub-project.

Separate builds in a multi-project build may depend on one another. You can express dependencies on any number of subprojects using the following syntax:

1   dependencies {
2     compile project(':subproject1')
3     compile project(':subproject2')
4   }

The top-level build.gradle file of multiproject should look something like the following:

1   allprojects {
2     apply plugin: "groovy"
3   }
4   project(":subproject1") {
5     dependencies {}
6   }
7   project(":subproject2") {
8     dependencies {}
9   }

File Operations

Since Gradle evaluates tasks before actually executing them, you should generally not use java.util.File for defining files or directories. Instead, Gradle provides a number of built-in methods and tasks. For example, you should use the file method for single files or directories and the files method to define a collection of files or directories.

1   outputDir = file("libs/x86")

There's also a fileTree method for recursively listing a directory of files. For example, you can depend on all files under the lib directory in the following way:

1   dependencies {
2           compile fileTree('lib')
3   }

To copy files from one place to another, use the Copy task. Here's a good example:

1   task copyImages(type: Copy) {
2           from 'assets'
3           into 'build/images'
4           include '**/*.jpg'
5           exclude '**/*test*'
6   }

This task would copy all images that end with .jpg in the assets directory into the build/images directory, excluding any files containing the word test.

Exploring

Remember you can also easily list properties of an object in Groovy using .properties. This can help you explore available Gradle properties at runtime. For example:

1   task test {
2           println sourceSets.main.properties
3   }

Completely Groovy

Remember that all of Groovy's goodness is available in Gradle. For example, the following one-liner sets the encoding option to UTF-8 for two tasks using the “star-dot” notation (this is useful when your code contains non-ASCII characters):

1   [compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
A426440_1_En_12_Figb_HTML.jpg Exercise

Explore Gradle by making your own build.gradle and trying out everything in this chapter.

Summary

This chapter taught you the following about Gradle:

  • How to create tasks

  • How to use plugins

  • How to specify dependencies

  • What gradle.properties is all about

  • How to create multiproject builds

  • Using built-in methods for file operations

A426440_1_En_12_Figc_HTML.jpg Online Documentation

Gradle has a huge online user guide available at gradle.org 2.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset