Groovy Gradle插件任务上的共享@Input属性,理想情况下为嵌套配置
我的gradle插件生成许多具有共享配置的任务。此配置需要标记为@Input,因此当它被更改时,任务将被标记为过时并重新评估。我发现,当配置应用于多个任务时,共享配置很有挑战性。我正在使用规避Groovy Gradle插件任务上的共享@Input属性,理想情况下为嵌套配置,groovy,gradle,Groovy,Gradle,我的gradle插件生成许多具有共享配置的任务。此配置需要标记为@Input,因此当它被更改时,任务将被标记为过时并重新评估。我发现,当配置应用于多个任务时,共享配置很有挑战性。我正在使用规避project.afterEvaluate来允许增量编译。此示例是我目前拥有的内容的简化版本: 当前插件代码: class MyPluginTaskOne extends DefaultTask { @Input config = "default" @TaskAction publ
project.afterEvaluate
来允许增量编译。此示例是我目前拥有的内容的简化版本:
当前插件代码:
class MyPluginTaskOne extends DefaultTask {
@Input config = "default"
@TaskAction
public void action() {
// something that depends on config
}
}
class MyPluginTaskTwo extends DefaultTask {
@Input config = "default"
@TaskAction
public void action() {
// something that depends on config
}
}
class MyPluginExtension {
// blank for now
}
class MyPlugin implements Plugin<Project> {
void apply(Project project) {
project.extensions.create("myPluginConfig", MyPluginExtension)
project.tasks.create(name: 'myPluginTaskOne', type: MyPluginTaskOne) {}
project.tasks.create(name: 'myPluginTaskTwo', type: MyPluginTaskTwo) {}
}
}
首选配置:
class MyPluginTaskOne extends DefaultTask {
@Input config = "default"
@TaskAction
public void action() {
// something that depends on config
}
}
class MyPluginTaskTwo extends DefaultTask {
@Input config = "default"
@TaskAction
public void action() {
// something that depends on config
}
}
class MyPluginExtension {
// blank for now
}
class MyPlugin implements Plugin<Project> {
void apply(Project project) {
project.extensions.create("myPluginConfig", MyPluginExtension)
project.tasks.create(name: 'myPluginTaskOne', type: MyPluginTaskOne) {}
project.tasks.create(name: 'myPluginTaskTwo', type: MyPluginTaskTwo) {}
}
}
我想做的是一个类似于以下内容的配置,但具有跟踪@Input依赖项和最新测试的所有好处
myPluginConfig {
config "SHARED-CONFIG"
// myPluginTaskOne and myPluginTaskTwo both gets automatic
// 'SHARED-CONFIG' through Gradle
}
您似乎可以在任务之间自动添加依赖项(请参见下文)。是否可以只配置第一个任务,然后在第二个任务上将@Input滴流到@Input
让我们根据CopySpec.from()如何使用Project.files()计算参数,尝试删除任务依赖项。Gradle可以自动为我们添加任务依赖项。这还会将生成器任务的输出作为输入添加到zip任务中
从开始,最常见的约定是使用扩展来执行此操作。看起来你已经开始这么做了。然后,您将在扩展上定义属性,然后您的插件将读取扩展并在所有相关任务上设置属性
myPluginConfig {
sharedConfig 'value'
}
在您的插件中:
def extension = extensions.create("myPluginConfig", MyPluginExtension)
project.afterEvaluate {
// read prop from `extension` and set prop on tasks
}
以马克的评论为基础。下面是一个应用于所有任务且无法重写的属性示例(配置)
类MyPluginTaskOne扩展了DefaultTask{
@输入字符串getConfig(){project.mypluginofig.config}
@任务行动
公共无效行动(){
//这取决于配置
}
}
类MyPluginTaskTwo扩展了DefaultTask{
@输入字符串getConfig(){project.mypluginofig.config}
@任务行动
公共无效行动(){
//这取决于配置
}
}
类myplugin{
字符串配置
}
类MyPlugin实现插件{
无效申请(项目){
project.with{
extensions.create(“MyPluginFig”,MyPluginExtension)
创建(名称:'myPluginTaskOne',类型:myPluginTaskOne){}
创建(名称:'myPluginTaskTwo',类型:myPluginTaskTwo){}
}
}
}
我有一个扩展设置,但在调用.with
期间,它没有从修改的扩展对象获取更新的值。在@biggay的建议下,我从.afterEvaluate
切换到.with
。我记不起.afterEvaluate
的问题了,但我认为是因为它干扰了依赖关系。请看这里:每种方法都有优点/缺点。对于@biggay提到的方法,所讨论的属性不被视为任务输入,因此不用于增量构建支持(您正在尝试实现)。您可以通过向每个任务添加一个getter方法来解决这个问题,该方法返回扩展属性,并使用@Input
进行注释。问题是该属性实际上是只读的,不能为每个任务单独设置(这可能很好)。with()
和afterEvaluate()
之间的区别在于后者被推迟到项目配置之后。我们非常支持增量构建。有些配置是特定于任务的,有些是共享的,所以我们可以混合使用这些技术。你能概述一下返回带有@Input
注释的扩展对象的getter方法吗?这听起来很接近我们想要的。这是用于j2objc gradle脚本的,目前运行超过900行。完整脚本:基本上,根据@bigdaz给出的示例,如果您想将扩展属性作为任务的输入,您可以向任务添加一个方法,如so@input String getToolHome(){project.mypluginfig.toolHome}
。谢谢,我已经尝试了许多变体,但我无法得到正确编译和工作的东西。你能帮我把你的答案改成project.with
风格,并给出一个工作@Input String getToolHome(){…}
示例吗。这听起来好像能解决我的问题。谢谢这个@biggay。我成功地重新编写了j2objc gradle插件,输入/输出机制运行良好。
class MyPluginTaskOne extends DefaultTask {
@Input String getConfig() { project.myPluginConfig.config }
@TaskAction
public void action() {
// something that depends on config
}
}
class MyPluginTaskTwo extends DefaultTask {
@Input String getConfig() { project.myPluginConfig.config }
@TaskAction
public void action() {
// something that depends on config
}
}
class MyPluginExtension {
String config
}
class MyPlugin implements Plugin<Project> {
void apply(Project project) {
project.with {
extensions.create("myPluginConfig", MyPluginExtension)
tasks.create(name: 'myPluginTaskOne', type: MyPluginTaskOne) {}
tasks.create(name: 'myPluginTaskTwo', type: MyPluginTaskTwo) {}
}
}
}