
Kevin is your Gradle tutor
Welcome to this review of the Pluralsight course Gradle Fundamentals by Kevin Jones.
Kevin is an industry veteran with a passion for developing and teaching. He is highly experienced with a range of different languages including C++, Java and C#.
In recent years he’s been focusing more and more on rich clients using JavaScript and tools such as Knockout and AngularJS. He believes that JavaScript is the best thing since, well, JavaScript.
What is Gradle?
Kevin says Gradle is a Build engine offering “Build by convention” with conventions that are easily overwritable.
It is written in Java, but the build language is a Domain Specific Language which is written in Groovy.
Kevin lists several other features the Gradle offers us, and talks more about the declarative build language.
Gradle Compared to Ant and Maven
Kevin gives an overview of Ant (Another Neat Tool). It was written by James Duncan Davidson as an improvement over Make.
However Kevin says the build scripts are hard to read and difficult to maintain, and we see an example of this.
Maven has several advantages over Ant. Perhaps the most important one is the conventions that reduce the amount of configuration required.
But it is still written in XML and is hard to read.
Kevin says although Gradle build files look unfamiliar at first, they will become largely self-explanatory and relatively easy to maintain.
Installing Gradle
There are couple of different ways we can install Gradle:
From the website from http://gradle.org
Using gvm (Groovy enVironment Management) http://gvmtool.net
Kevin warns that although gvm is great on Linux and Mac, it is very difficult to get gvm working on Windows.
Kevin downloads Gradle and says we need to add it to our path.
To manage working with changing versions of Gradle, he introduces Microsoft’s “junction” tool.
https://technet.microsoft.com/en-us/sysinternals/bb896768.aspx
This creates junction points from virtual folders to physical folders.
If you want to use the Groovy Environment Manager, you can download it with Curl:
curl -s get.gvmtool.net|bash
Once gvm is installed you can install Gradle with this command:
gvm install gradle
Kevin shows us how to do this in Ubuntu.
Running Gradle for the First Time
The Gradle build file is typically named build.gradle, and it contains tasks, plugins and dependencies.
We see a very simple example which just outputs “Hello, Gradle”. We execute a task by typing in gradle followed by the name of the task
gradle hello
:hello
Hello, Gradle
We also see an even simpler example than this! This build script just adds the java plugin and lets us build a Java application.
We run the build using the command:
gradle build
and we see the build folder that is created and the contents inside it.
We also see that Gradle is smart enough to only rebuild the things that have changed since the last build.
Introduction to the Gradle Wrapper
Kevin says the Gradle Wrapper is a third way to install Gradle.
We see a task called wrapper which sets the gradleVersion. We execute it with the command:
gradle wrapper
We see two new files: gradlew and gradlew.bat. the .bat file is using on Windows and gradlew is used on *nix systems.
Kevin says running application with different versions of libraries can cause problems, and so for build scripts.
The Gradle wrapper carries the version along with itself and use the correct version to build the applications.
Basic Gradle Tasks
Kevin says it might be worth watching some or all of the Groovy Fundamentals course to familiarise yourself with the language and get more out of this module.
Writing Simple Tasks
A task is code the Gradle executes for us. It has a lifecycle, with an initialization phase, a configuration phase and an execution phase.
Tasks also have properties (e.g. description, group) and actions. Actions are code code the execute.
Kevin explains that task actions are broken into the first action and the last action.
Finally there are dependencies. When some tasks are dependant on others, Gradle will work out the dependency order and execute them in the correct order.
In a Gradle build script, the top-level object is the project, and the project object defines everything within the build script:
project.task(“Task1”)
task(“Task2”)
task “Task3”
task Task4
Task4.description = “Task 4 Description”
We see the effect of typing the command gradle tasks against this and learn that Gradle delegates everything to the top level project object.
We also see here that both Groovy and Gradle are quite permissive with different syntactic styles.
Running Tasks
We see a couple of examples of the doLast action. We can use the << operator as a shorthand, and we see that Gradle appends closures together.
Kevin says this makes Gradle very powerful and very flexible.
Task Phases
1. Initialization Phase: used to configure multi project builds
2. Configuration Phase: executes code in the task that’s not the action
3. Execution Phase: Execute the task actions
Here we see a demonstration of the doFirst method.
Task Dependencies
Kevin says we like tasks to have dependencies and that we can easily do this in Gradle.
Each task has a dependsOn method, and we see that setting this affects the order that tasks are run.
However, there are other ways to set up dependencies. We can use dependsOn inside a task closure for example. Kevin demonstrates this.
Setting Properties on Tasks
We start with a demonstration of string interpolation, and then Kevin introduces extra properties. If we do:
project.ext.projectVersion = “2.0”
This is available other build files besides this one, because it is set on the project itself.
Task Dependencies
Task Dependencies
In the previous module we learned that Gradle executes code which has:
– a lifecycle
– properties
– actions
– dependencies
We will cover the last of these points in more detail. Kevin demonstrates a gradle script with 6 tasks. Task A dependsOn B, C and D.
Kevin says the order the tasks run in is undefined: Gradle will choose some order and we won’t know until it has done it.
We say tasks C and D depend on E. Then we create Task G.
Using mustRunAfter and shouldRunAfter
mustRunafter is used to tell Gradle if two tasks execute one MUST run after the other
shouldRunAfter is used to tell Gradle if two tasks execute one SHOULD run after the other. It ignores circular dependencies.
With mustRunAfter Gradle will fail the build if two tasks have a circular dependency on each other.
Using finalizedBy
finalizedBy means inverted dependency. A finalizedBy B means B runs after A.
Kevin says he does database migrations with flyway https://flywaydb.org/ and this lets him describe in different steps how he builds his databases.
It comes with a Gradle plugin, and you configure Flyway by calling a Flyway method.
We see two example tasks: one called migrateProduction and one called migrateTest.
finalizedBy allows us to have a task the configures Flyway migration and then runs Flyway:
migrateProduction.finalizedBy flywayMigrate
migrateTest.finalizedBy flywayMigrate
The full Pluralsight course also contains modules on the following topics:
Also see Larry Schiefer’s Exploring Android Studio: The Gradle Build System