Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Gradle Goodness: Creation Rules For Rule Based Model Configuration Using Model DSL

DZone's Guide to

Gradle Goodness: Creation Rules For Rule Based Model Configuration Using Model DSL

Continuing to work with rule-based model configuration, see how you can define a model block and a creation rule using Gradle.

· Java Zone ·
Free Resource

Verify, standardize, and correct the Big 4 + more– name, email, phone and global addresses – try our Data Quality APIs now at Melissa Developer Portal!

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.

In the following build file, we define a model block and define a creation rule for creating the object versionInfo of type VersionFile. Also, we add a new task to the tasks object of type ModelMap<Task>. To reference another object from the model space inside the Closure for a creation rule we use the syntax $.<objectName>:

// File: model.gradle
import mrhaki.gradle.VersionFile
import mrhaki.gradle.VersionFileTask

model {
    // Creation rule to create object
    // with name versionInfo (name of the method)
    // and type VersionFile.
    versionInfo(VersionFile) {
        // Set default value for version to project.version.
        version = project.version
        
        // Set default outputFile to 
        // file version.txt in build directory.
        outputFile = project.file("${buildDir}/version.txt")
    }
    
    // tasks is of type ModelMap<Task>.
    tasks {
        // Create task generationVersionFile 
        // with custom task type VersionFileTask.
        create('generateVersionFile', VersionFileTask) {
            // Set properties with values
            // from managed object versionInfo,
            // that we created with the creation rule
            // versionInfo(VersionFile).
            // We use the special $.<name> notation
            // to reference object from the model space.
            version = $.versionInfo.version
            outputFile = $.versionInfo.outputFile
        }
    }
}

The supporting VersionFile class is a Gradle managed object:

// File: buildSrc/src/main/groovy/mrhaki/gradle/VersionFile.groovy
package mrhaki.gradle

import org.gradle.model.Managed

@Managed
interface VersionFile {
    String getVersion() 
    void setVersion(final String version) 

    File getOutputFile() 
    void setOutputFile(final File outputFile) 
}

And the custom task is very straight forward for our example:

// File: buildSrc/src/main/groovy/mrhaki/gradle/VersionFileTask.groovy
package mrhaki.gradle

import org.gradle.api.DefaultTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction

/**
 * Simple task to save the value for the
 * {@link #version} property in a file.
 * The file is set with the {@link #outputFile}
 * property.
 */
class VersionFileTask extends DefaultTask {

    /**
     * Value for version to be saved.
     */
    @Input
    String version

    /**
     * Output file to store version value in.
     */
    @OutputFile
    File outputFile

    /**
     * Actual task actions to save the value
     * for {@link #version} in {@link #outputFile}.
     */
    @TaskAction
    void generateVersionFile() {
        outputFile.parentFile.mkdirs()
        outputFile.text = version
    }

}

We can use the model rules in our build script when we use apply from: 'model.gradle' in our build script. In our example we also add a model configuration block to configure the versionInfo object:

// File: build.gradle
apply from: 'model.gradle'

model {
    // Configuration rule for the versionInfo
    // object, that is created with the
    // creation rule from 'model.gradle'.
    versionInfo {
        version = '3.0.0.RELEASE'
    }   
}

Let's invoke the model task and check the output to see where are rules are applied:

$ gradle -q model
...
 tasks
      | Type:           org.gradle.model.ModelMap<org.gradle.api.Task>
      | Creator:        Project.<init>.tasks()
      | Rules:
         ⤷ tasks { ... } @ model.gradle line 18, column 5
...
    + generateVersionFile
          | Type:       mrhaki.gradle.VersionFileTask
          | Value:      task ':generateVersionFile'
          | Creator:    create(generateVersionFile, mrhaki.gradle.VersionFileTask) { ... } @ model.gradle line 21, column 9
          | Rules:
             ⤷ copyToTaskContainer
...
+ versionInfo
      | Type:           mrhaki.gradle.VersionFile
      | Creator:        versionInfo(mrhaki.gradle.VersionFile) { ... } @ model.gradle line 8, column 5
      | Rules:
         ⤷ versionInfo { ... } @ build.gradle line 47, column 5
    + outputFile
          | Type:       java.io.File
          | Value:      /Users/mrhaki/Projects/mrhaki.com/blog/posts/samples/gradle/versionrule/build/version.txt
          | Creator:    versionInfo(mrhaki.gradle.VersionFile) { ... } @ model.gradle line 8, column 5
    + version
          | Type:       java.lang.String
          | Value:      3.0.0.RELEASE
          | Creator:    versionInfo(mrhaki.gradle.VersionFile) { ... } @ model.gradle line 8, column 5
...
$

Written with Gradle 3.2.

Developers! Quickly and easily gain access to the tools and information you need! Explore, test and combine our data quality APIs at Melissa Developer Portal – home to tools that save time and boost revenue. Our APIs verify, standardize, and correct the Big 4 + more – name, email, phone and global addresses – to ensure accurate delivery, prevent blacklisting and identify risks in real-time.

Topics:
gradle ,java ,rule based model configuration ,dsl

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}