如何在自定义 gradle 插件中创建嵌套配置参数?

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

如何在自定义 gradle 插件中创建嵌套参数结构?

首先,我使用的是 Gradle 7.2。我想为我的插件配置创建一个富有表现力的类似 DSL 的结构,其中包含一个嵌套元素

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

在学习如何编写 Gradle 插件时,我一直在关注 gradle plugin implementation docs,他们非常擅长展示如何使用扩展而不是“插件”class .

所以我已经对我的扩展进行了建模,FileDiffExtension 就像这样

abstract class FileDiffExtension {

    abstract RegularFileProperty getFile1()

    abstract RegularFileProperty getFile2()

    @Nested
    abstract Messages getMessages()

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

嵌套的 Messages class 是这样建模的

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

到目前为止,我认为我做得很好。然后我需要将我的扩展程序拉入我的插件,这就是我认为我 运行 遇到问题的地方。我的插件 class 目前看起来像

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
        }
    }
}

我正在尝试从根级扩展 fileDiff 中创建一个 messages 扩展。或者我不应该将任务中的 messages 对象设置为 getMessages() 抽象方法。但是我已经尝试了我能想到的每一种组合。实际任务如下图,但我觉得问题不在这里

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()
    }
}

为了测试,我正在使用 gradle 测试套件,目前我遇到以下错误。 `

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

嗯,根据 docs,如果 sub-extension 标记为 @Nested,则您无需对它执行任何操作,它应该可以正常工作。您是否尝试过完全删除此行?

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