Home > Blockchain >  How do I create nested configuration parameters in a custom gradle plugin?
How do I create nested configuration parameters in a custom gradle plugin?

Time:02-18

How do I create a nested parameter structure in a custom gradle plugin?

For starters, I am using Gradle 7.2. I want to make an expressive DSL-like structure for my plugin configuration, with a nested element

fileDiff {
    file1 = file('${testFile1.getName()}')
    file2 = file('${testFile2.getName()}')
                
    messages {
          message1 = 'Hi there'
    }                
}

While learning how to write Gradle Plugins I have been following the gradle plugin implementation docs, and they are great at showing what to do with the extension but not the "plugin" class.

So I have modeled my extension, FileDiffExtension like so

abstract class FileDiffExtension {

    abstract RegularFileProperty getFile1()

    abstract RegularFileProperty getFile2()

    @Nested
    abstract Messages getMessages()

    void messages(Action<? super Messages> action) {
        action.execute(getMessages())
    }
}

And the nested Messages class is modeled as such

abstract class Messages {
    abstract Property<String> getMessage1()
}

I think I am good up to this point. Then I need to pull my extension into my plugin and this is where I believe I am running into issues. My Plugin class currently looks like

class FileDiffPlugin implements Plugin<Project> {

    @Override
    void apply(Project project) {

        project.tasks.register('fileDiff', FileDiffTask) {
            project.extensions.create('fileDiff', FileDiffExtension)
            project.fileDiff.extensions.create("messages", FileDiffExtension.messages)

            file1 = project.fileDiff.file1
            file2 = project.fileDiff.file2

            messages = project.fileDiff.getMessages
        }
    }
}

I am trying to create a messages extension off of the root level extension fileDiff. Or maybe I am not supposed to set the messages object in the task to the getMessages() abstract method. But I have tried every combination I can think of. The actual task is shown below, but I don't think the problem lies here.

abstract class FileDiffTask extends DefaultTask {
    @InputFile
    abstract RegularFileProperty getFile1()

    @InputFile
    abstract RegularFileProperty getFile2()

    @Input
    abstract Property<Messages> getMessages()

    @OutputFile
    abstract RegularFileProperty getResultFile()

    FileDiffTask() {
        resultFile.convention(project.layout.buildDirectory.file('diff-result.txt'))
    }

    @TaskAction
    def diff() {
        // Print out the message
        println messages.get().message1.toString()

        // Now we do some fun file stuff
        String diffResult
        if (size(file1) == size(file2)) {
            diffResult = "Files have the same size at ${file1.get().asFile.getBytes()} bytes}"
        } else {
            File largestFile = size(file1) > size(file2) ? file1.get().asFile : file2.get().asFile
            diffResult = "${largestFile.toString()} is the largest file at ${largestFile.size()} bytes"
        }

        resultFile.get().asFile.write diffResult

        println "File written to $resultFile"
        println diffResult
    }

    private static long size(RegularFileProperty regularFileProperty) {
        return regularFileProperty.get().asFile.size()
    }
}

To test I am using the gradle test kit, and I'm currently getting the following error. `

Could not create task ':fileDiff'. No such property: messages for class: com.robschwartz.plugins.filediff.FileDiffExtension Possible solutions: messages `

CodePudding user response:

Hm, according to docs you do not need to do anything with the sub-extension if it's marked as @Nested, it should just work. Have you tried to remove this line entirely?

project.fileDiff.extensions.create("messages", FileDiffExtension.messages)
  • Related