At work we have a very manual process when packaging patches for our product. I wanted to alleviate some of the pain by automating the mindless/error-prone tasks, but there was a lot of metadata that needed to be gathered and stored in various places. I needed the file and source control power of a build tool, but the flexibility of a programming language for collecting metadata. After a few experiments I finally settled on Gradle.
Using Groovy’s Swing Builder, I constructed a dialog with inputs for all of the patch information I needed:
(Note: I cheated a little and used Eclipse’s WindowBuilder to design the UI. I then had to translate the generated code into a Groovy equivalent.)
Now, when I execute the “showDialog” task, a nice UI is displayed to collect the patch metadata:
While this solution provides a nice front-end for my patch builder, I want to make sure it aligns with Gradle’s best practices. In the Gradle documentation, I discovered a chapter on initialization scripts which mentions the following:
60.1. Basic usage Initialization scripts (a.k.a. init scripts) are similar to other scripts in Gradle. These scripts, however, are run before the build starts. Here are several possible uses:
- Set up enterprise-wide configuration, such as where to find custom plugins.
- Set up properties based on the current environment, such as a developer’s machine vs. a continuous integration server.
- Supply personal information about the user that is required by the build, such as repository or database authentication credentials.
- Define machine specific details, such as where JDKs are installed.
- Register build listeners. External tools that wish to listen to Gradle events might find this useful.
Register build loggers. You might wish to customize how Gradle logs the events that it generates.
One main limitation of init scripts is that they cannot access classes in the buildSrc project (see Section 59.3, “Build sources in the buildSrc project” for details of this feature).
My interpretation is that this is a good spot in the build lifecycle to collect customized configuration or metadata. I also like that the init script (
init.gradle) is separate from my build script (
build.gradle) and must be called explicitly on the command line with the
-I options. This means if I later want to build a patch using a properties file or some other configuration method, I can just drop the init script.
One of the caveats of using an init script is that it executes very early in the build lifecycle. To set data on a Project object, you need to wait until it has been evaluated. I wrapped my Swing Builder in an
allProjects.afterEvaluate closure to make sure I could set extra properties on the Project object: