gradle 编写自己的插件时,得到意外的“无法设置只读属性的值”

kwvwclae  于 2023-01-13  发布在  其他
关注(0)|答案(1)|浏览(191)

我正在尝试编写一个DSL,如下所示:

toolSetups {
    someTool {
        argsFile = file('run/some_tool/xrun_files.f')
    }
    someOtherTool {
        argsFile = file('run/some_other_tool/xrun_files.f')
    }
}

我通过向项目添加扩展来实现这一点,扩展是ToolSetup条目的容器:

extensions.add('toolSetups', project.container(ToolSetup))

我按照用户指南中的示例在ToolSetup中声明了argsFile属性:

interface ToolSetup {
    Property<File> getArgsFile()
}

我四处寻找,发现只有当ToolSetupname属性时,这才有效。我将ToolSetup修改为:

abstract class ToolSetup {
    private final String name
    
    public ToolSetup(String name) {
        this.name = name
    }

    String getName() {
        return name
    }

    abstract Property<File> getArgsFile()
}

我得到了以下信息:
无法为ToolSetup $Inject类型的对象设置只读属性"argsFile"的值。
我也试过显式调用argsFile.set(file(...)),但这给了我同样的错误。我也试过使用ObjectFactory显式创建Property示例,但仍然得到同样的错误。
我已经编写了一个插件,它做了类似的事情,在哪里工作,但该插件是用Java编写的。我猜这里有一些小错误与Groovy有关,让Gradle为我管理实现,我没有看到。如果有人能指出这一点,我将非常感激。
以下是重现此问题的完整build.gradle文件:

abstract class ToolSetup {
    private final String name
    
    public ToolSetup(String name) {
        this.name = name
    }

    String getName() {
        return name
    }

    abstract Property<File> getArgsFile()
}

extensions.add('toolSetups', project.container(ToolSetup))

toolSetups {
    someTool {
        argsFile = file('run/some_tool/xrun_files.f')
    }
    someOtherTool {
        argsFile = file('run/some_other_tool/xrun_files.f')
    }
}
vql8enpb

vql8enpb1#

我能让下面的工作
buildSrc/src/main/java/com/sample/Resource.java

package com.sample;
import org.gradle.api.provider.Property;
import java.net.URI;

public interface Resource {
    // Type must have a read-only 'name' property
    String getName();

    Property<URI> getUri();

    Property<String> getUserName();

}

build.gradle

extensions.add("download", project.objects.domainObjectContainer(com.sample.Resource.class))

download {
    register('t1') {
        uri = uri("http://abc")
        userName = "t1u"
    }
    register('t2') {
        uri = uri("https://abc")
        userName = "t2u"
    }
}

println "download info "
download.each { println String.format("{name: %s, uri: '%s', userName: %s", it.getName(), it.getUri().getOrNull(), it.getUserName().getOrNull()) }

输出产生

> Configure project :
download info 
{name: t1, uri: 'http://abc', userName: t1u
{name: t2, uri: 'https://abc', userName: t2u

BUILD SUCCESSFUL in 1s
3 actionable tasks: 3 up-to-date

相关问题