Gradle has excellent incremental build support. This means that Gradle can determine if a task needs to be executed based on the input and output of that task. If for example nothing changed in one of the input and output files, then the task can be skipped. We can add incremental build support for our custom tasks by defining the input and output of the task. We can also define that a task can be skipped when a collection of files or a directory that is the input of the task are empty or not exists. Gradle offers the
@SkipWhenEmpty annotation we can apply on the input of our task.
Sometimes we want to check which operating system is used in our build script. For example we have tasks that need to run if the operating system is Windows and not for other operating systems. Gradle has an internal class
org.gradle.nativeplatform.platform.internal.DefaultOperatingSystem, but we should not use this class in our build scripts. The class is used internally by Gradle and can change without warning. If we would depend on this class and it changes we break our build scripts. But we can use a class from Ant that is already in Gradle’s class path:
org.apache.tools.ant.taskdefs.condition.Os. The class has several methods and constants to check the operating system name, version and architecture. The values are based on the Java system properties
Gradle builds are fast because Gradle supports incremental tasks. This means Gradle can determine if input or output of task has changed, before running the task. If nothing has changed a task is marked a up-to-date and the task is not executed, otherwise the task is executed. If we want execute a task even if it is up-to-date we must use the command line option
IntelliJ IDEA 2016.3 introduces the option to delegate the IDE build and run actions to Gradle. So if we invoke the Build Project action from the Build menu IntelliJ IDEA invokes the correct tasks using Gradle. Also the Run and Debug actions from the Run menu are executed with Gradle. Continue reading
In a previous post we learned how to create a class that extends
RuleSource with methods that define rules on how to create and change objects in the Gradle model space. With the
model configuration block in a build file we can also define creation rules for Rule based model configuration.
Rule based model configuration in Gradle allows us to have a graph of objects with dependencies that are resolved by Gradle. To make this work Gradle needs to know about the object in this model space. The model space is populated with objects of our own and with objects from Gradle. At time of writing this blog post we can not interact with the Gradle
Project object in our rule based model configuration. It is not officially part of the model space. Probably in the future this might change and will the
Project object managed by Gradle be part of the model space. Which means we can use then a
Project object as input parameter for any rule methods we have. For now the official way to pass project information to the rule based model space is via the
model configuration block in our build script. The
model configuration block can be used to set properties on objects with values from our
Rule based model configuration gives Gradle more knowledge about the objects and their dependencies. This information can be used by Gradle to optimise the build process. We define rules on how we want Gradle to create objects and how we want to mutate objects in a class that extends
RuleSource. We can also add rules to validate objects available in the Gradle model space. We use the
@Validate annotation on methods that have validation logic. The first argument of the method is of the type of the object we want to validate. This type must be managed by Gradle.
Gradle 3.2 deprecates the
<< operator to add actions to a task. The
<< operator maps to the
leftShift method of a task. This operator confuses a lot people that are new to Gradle. Because without the operator we are configuring a task instead of adding actions. I can tell from experience the mistake is easily made. If we use the
<< in our build script with Gradle 3.2 we get a warning on the console. The warning message already mentions a solution: use the
doLast method to add actions.
When we use Rule based model configuration in our Gradle project we can give Gradle rules on how to manage objects from the model space. These rules are defined in a class that extends
RuleSource. When we want to set some default values for properties of a model object (in Gradle terms this is a subject) we can use the
@Defaults annotation. Rules annotated with
@Defaults are invoked right after the object is created and before any other methods that can mutate the state of the object.
The method, to set the default values, must have the type of the object as first parameter. Other parameters are considered input parameters and can be used to set a default value based on other model objects.
We use the
model task to see which objects are available in the Gradle model space. The model spaced is managed by Rule based model configuration. Objects can be defined as hidden by the object author(s). By default a hidden object is not shown in the model report. We must use the task option
--showHidden to show also the hidden objects in the model report.