Gradle Feature Spotlight: Continuous Build
Earlier this year the Gradle project released version 2.5 with a heap of new features and improvements. One of the most touted of those features is an incubating feature (read: beta) named Continuous Build which automatically re-executes tasks after a file change. Rubyists may recognize that this functionality is similar to what the guard gem provides.
What makes "continuous build" special is that it makes use of the existing build data present in your Gradle build. Using a task’s inputs the continuous build feature can automatically "watch" the appropriate files to re-execute your task, or your tasks dependent tasks, automatically as they change!
For users JRuby/Gradle this means that upgrading to Gradle 2.5 or later, and
ensuring your build.gradle
declares task inputs and continuous build will
"just work!" Consider the following example for running
RSpec tests:
buildscript {
repositories { jcenter() }
dependencies {
classpath "com.github.jruby-gradle:jruby-gradle-plugin:1.0.3" (1)
}
}
apply plugin: 'com.github.jruby-gradle.base' (2)
dependencies {
jrubyExec 'rubygems:rspec:3.3.0' (3)
}
import com.github.jrubygradle.JRubyExec
task spec(type: JRubyExec) {
group 'JRuby'
description 'Execute the RSpecs in JRuby'
script 'rspec'
inputs.source fileTree('spec').include('**/*.rb'), fileTree('lib').include('**/*.rb') (4)
}
1 | Specify our dependency on the JRuby/Gradle base plugin |
2 | Apply the plugin to our current project |
3 | Define our RSpec gem dependency |
4 | Set our task inputs to the .rb files in spec/ and in lib/ |
Using the build.gradle
above, I can auto-execute my tests whenever a Ruby file
inside of the spec/
(my tests) or lib/
(my code under test) with the
following command:
% ./gradlew -t spec
Here’s some example output from my example project:
example-project git:(master) % ./gradlew -t spec Continuous build is an incubating feature. :spec Randomized with seed 37453 .............................................. Finished in 0.52 seconds (files took 3.82 seconds to load) 46 examples, 0 failures Randomized with seed 37453 BUILD SUCCESSFUL Total time: 8.77 secs Waiting for changes to input files of tasks... (ctrl-d to exit)
At this point the Gradle process is patiently waiting until I write my most recent changes, then it kicks off the same task:
Change detected, executing build... :spec Randomized with seed 64935 .............................................. Finished in 0.502 seconds (files took 3.5 seconds to load) 46 examples, 0 failures Randomized with seed 64935 BUILD SUCCESSFUL Total time: 7.341 secs Waiting for changes to input files of tasks... (ctrl-d to exit)
Pretty neat huh?
What makes this functionality exceptionally powerful for JRuby/Gradle users is
that it respects the task inputs but also the task dependency graph. If my spec
task declares a dependency on the compileJava
task, whenever my Java source
code changes, that will trigger a re-execution of compileJava
and in turn
spec
!
So when you’re authoring tasks, even if you’re not this feature right now, be sure to declare task inputs. That build metadata can unlock lots of interesting functionality as Gradle continues to improve!
Continuous build is one of many examples of powerful Gradle functionality which can easily used in JRuby/Gradle, I hope you find it useful!